[Q] How to exec code object with local variables specified?
Hi, Is it possible to run code object with local variables specified? I'm trying the following code but not work: def fn(): x = 1 y = 2 localvars = {'x': 0} exec(fn.func_code, globals(), localvars) print(localvars) ## what I expected is: {'x': 1, 'y': 2} ## but actual is: {'x': 0} Python: 2.7.3 OS: MacOS X -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: [Q] How to exec code object with local variables specified?
On Thu, Sep 20, 2012 at 10:15 PM, Peter Otten <__pete...@web.de> wrote: > >>>> loc = {} >>>> exec("x = 1; y = 2", globals(), loc) >>>> loc > {'y': 2, 'x': 1} > > However, this won't work with the code object taken from a function which > uses a different a bytecode (STORE_FAST instead of STORE_NAME): > Is there any way to use STORE_FAST instead of STORE_NAME? exec("string", ...) is not a solution for me. # What is different between fn.func_code and compile("string")? -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
ANN: pyTenjin 1.1.0 - a high-speed and full-featured template engine
I released pyTenjin 1.1.0. http://pypi.python.org/pypi/Tenjin/ http://www.kuwata-lab.com/tenjin/ Overview of pyTenjin * Very fast: about 10 times faster than Django template engine * Easy to learn: no need to learn template-original language * Full-featured: nestable layout template, partial template, preprocessing, etc. * Lightweight: only 2000 lines of code and very fast to import. * Google App Engine supported Documents - * User's Guide http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html * Examples http://www.kuwata-lab.com/tenjin/pytenjin-examples.html * CHANGES http://www.kuwata-lab.com/tenjin/pytenjin-CHANGES.txt Install --- $ sudo easy_install Tenjin Or: $ wget http://pypi.python.org/packages/source/T/Tenjin/Tenjin-1.1.0.tar.gz $ tar xzf Tenjin-1.1.0.tar.gz $ cd Tenjin-1.1.0/ $ sudo python setup.py install Example --- ## views/example.pyhtml ${title} ${item} ## main.py import tenjin #tenjin.set_template_encoding('utf-8') # optional (default 'utf-8') from tenjin.helpers import * from tenjin.html import * engine = tenjin.Engine(path=['views']) context = {'title': 'Example', 'items': ['Haruhi', 'Mikuru', 'Yuki'] } output = engine.render('example.pyhtml', context) print(output) ## output $ python main.py Example Haruhi Mikuru Yuki Enhancements and Changes in this release (See http://www.kuwata-lab.com/tenjin/pytenjin-CHANGES.txt for details.) * [Change] !! IMPORTANT!! Default cache file format is changed from marshal format to text format. You should remove all cache files to use this release. * [Enhance] Embedded pattern '${}' and '#{}' can contain pair of '{' and '}'. :: ${foo({'x':1})} # OK ${foo({}+{}+{})} # OK ${foo({'x':{'y':1}})}# NG * [Enhance] New preprocessing mechanism. You can specify your own preprocessor class by 'pp' parameter. * [Enhance] Add 'TrimPreprocessor' which removes spaces ad the beginning of lines. You can reduce size of output by it. * [Enhance] Add 'PrefixedLinePreprocessor' which converts ':: ...' into ''. You may like ':: ...' because it is simpler than ''. * [Enhance] Add 'JavaScriptPreprocessor' class which enables you to embed client-side javascript template code into server-side template. For example:: #{i} ${items[i]} #{tenjin.JS_FUNC} var html = render_table(["Haruhi", "Mikuru", "Yuki"]); document.getElementById('placehodler').innerHTML = html; will be converted into:: function render_table(items){var _buf=''; _buf+=' <table>\n'; for (var i = 0, n = items.length; i < n; i++) { _buf+='<tr>\n\ <td>'+_S(i)+'</td>\n\ <td>'+_E(items[i])+'</td>\n\ </tr>\n'; } _buf+=' </table>\n'; return _buf;}; #{tenjin.JS_FUNC} var html = render_table(["Haruhi", "Mikuru", "Yuki"]); document.getElementById('placehodler').innerHTML = html; by JavaScriptPreprocessor. Notice that you should embed 'tenjin.JS_FUNC' to run client-side code. How to use it:: pp = [ tenjin.JavaScriptPreprocessor() ] engine = tenjin.Engine(pp=pp) output = engine.render('example.pyhtml', {}) print(html) * [Enhance] Now supports Jython 2.5.2. (thanks to Lars Hupfeldt Nielsen) * [Enhance] Now supports PyPy 1.7 or later officially. * [Change] Template#convert() now converts "\r\n" into "\\r\n". This is necessary to follow change of language specification on Python 2.7 and 3.2. Have fun! -- makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[Q] How to specify options for 'setup.py install' by environment variable?
Hi, "setup.py install" command supports options such as --prefix, --install-scripts, and so on. For example: $ python setup.py install --prefix=$PWD/local --install-scripts=$PWD/bin Question: is it possible to specify these options by environment variable? I want to specify --prefix or --install-scripts options, but it is too troublesome for me to specify them in command line every time. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: [Q] How to specify options for 'setup.py install' by environment variable?
On Sun, Jun 10, 2012 at 11:55 AM, Ned Deily wrote: > In article > , > Makoto Kuwata wrote: > >> Hi, >> >> "setup.py install" command supports options such as --prefix, >> --install-scripts, and so on. >> For example: >> >> $ python setup.py install --prefix=$PWD/local --install-scripts=$PWD/bin >> >> Question: is it possible to specify these options by environment variable? >> I want to specify --prefix or --install-scripts options, but it is >> too troublesome for me to specify them in command line every time. > > There are some environment variable options for Distutils-based (i.e. > with setup.py) installations. The supported method is to put > frequently-used preferences into one of several configuration files. > See > http://docs.python.org/install/index.html#inst-config-fileshttp://docs.py > thon.org/install/index.html#inst-config-files Thank you Ned, but I can't find environment variable name on that page which is equivarent to '--install-scripts' or other options. $PYTHONHOME seems equivarent to --prefix option, but the following reports error. $ mkdir -p local/lib/python2.7/site-packages $ PYTHONHOME=local python setup.py install ImportError: No module named site -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: [Q] How to specify options for 'setup.py install' by environment variable?
On Sun, Jun 10, 2012 at 3:51 PM, Ned Deily wrote: >> >> Thank you Ned, >> but I can't find environment variable name on that page which is >> equivarent to '--install-scripts' or other options. > > Sorry, I wasn't clear. Using the Distutils config files would be > instead of setting environment variables. For example, you could do > something like this: > > $ cat >$HOME/.pydistutils.cfg < [install] > prefix = local > install-scripts = local/bin > EOF > > That will apply globally whenever you run a Distutils script, unless it > is overridden by a $PWD/setup.cfg file with an [install] section. Thank you Ned, I'm clear. You mean that there is no environment variable equivarent to options, therefore I should create configuration file of distutils. I'll try it. Thank you. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest 0.9.0 released - a new-style testing library
Hi, I released Oktest 0.9.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Oktest is a new-style testing library for Python. :: from oktest import ok, NG ok (x) > 0 # same as assert_(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) NG (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) NG ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) See http://packages.python.org/Oktest/ for details. NOTICE!! Oktest is a young project and specification may change in the future. Main Enhancements - * New '@test' decorator provided. It is simple but very powerful. Using @test decorator, you can write test description in free text instead of test method. ex:: class FooTest(unittest.TestCase): def test_1_plus_1_should_be_2(self): # not cool... self.assertEqual(2, 1+1) @test("1 + 1 should be 2")# cool! easy to read & write! def _(self): self.assertEqual(2, 1+1) * Fixture injection support by '@test' decorator. Arguments of test method are regarded as fixture names and they are injected by @test decorator automatically. Instance methods or global functions which name is 'provide_' are regarded as fixture provider (or builder) for fixture ''. ex:: class SosTest(unittest.TestCase): ## ## fixture providers. ## def provide_member1(self): return {"name": "Haruhi"} def provide_member2(self): return {"name": "Kyon"} ## ## fixture releaser (optional) ## def release_member1(self, value): assert value == {"name": "Haruhi"} ## ## testcase which requires 'member1' and 'member2' fixtures. ## @test("validate member's names") def _(self, member1, member2): assert member1["name"] == "Haruhi" assert member2["name"] == "Kyon" Dependencies between fixtures are resolved automatically. ex:: class BarTest(unittest.TestCase): ## ## for example: ## - Fixture 'a' depends on 'b' and 'c'. ## - Fixture 'c' depends on 'd'. ## def provide_a(b, c): return b + c + ["A"] def provide_b(): return ["B"] def provide_c(d): return d + ["C"] def provide_d(): reutrn ["D"] ## ## Dependencies between fixtures are solved automatically. ## @test("dependency test") def _(self, a): assert a == ["B", "D", "C", "A"] If loop exists in dependency then @test reports error. If you want to integrate with other fixture library, see the following example:: class MyFixtureManager(object): def __init__(self): self.values = { "x": 100, "y": 200 } def provide(self, name): return self.values[name] def release(self, name, value): pass oktest.fixure_manager = MyFixtureResolver() Other Enhancements and Changes -- * Supports command-line interface to execute test scripts. * Reporting style is changed. * New assertion method ``ok(x).attr(name, value)`` to check attribute. * New assertion method ``ok(x).length(n)``. * New feature``ok().should`` helps you to check boolean method. * 'ok(str1) == str2' displays diff if text1 != text2, even when using with unittest module. * Assertion ``raises()`` supports regular expression to check error message. * Helper functions in oktest.dummy module are now available as decorator. * 'AssertionObject.expected' is renamed to 'AssertionObject.boolean'. * ``oktest.run()`` is changed to return number of failures and errors of tests. * ``before_each()`` and ``after_each()`` are now non-supported. * (Experimental) New function ``NOT()`` provided which is same as ``NG()``. * (Experimental) ``skip()`` and ``@skip.when()`` are provided to skip tests:: See CHANGES.txt for details. http://packages.python.org/Oktest/CHANGES.txt Have a nice testing life! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: [ANN] Oktest 0.9.0 released - a new-style testing library
I published presentation slide about Oktest. If you have interested in testing, check it out. http://www.slideshare.net/kwatch/oktest-a-new-style-testing-library-for-python -- regards, makoto kuwata On Sat, Aug 27, 2011 at 9:37 PM, Makoto Kuwata wrote: > Hi, > > I released Oktest 0.9.0. > http://pypi.python.org/pypi/Oktest/ > http://packages.python.org/Oktest/ > > Oktest is a new-style testing library for Python. > :: > > from oktest import ok, NG > ok (x) > 0 # same as assert_(x > 0) > ok (s) == 'foo' # same as assertEqual(s, 'foo') > ok (s) != 'foo' # same as assertNotEqual(s, 'foo') > ok (f).raises(ValueError) # same as assertRaises(ValueError, f) > ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) > NG (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) > ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) > NG ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) > > See http://packages.python.org/Oktest/ for details. > > NOTICE!! Oktest is a young project and specification may change in the future. > > > Main Enhancements > - > > * New '@test' decorator provided. It is simple but very powerful. > Using @test decorator, you can write test description in free text > instead of test method. > ex:: > > class FooTest(unittest.TestCase): > > def test_1_plus_1_should_be_2(self): # not cool... > self.assertEqual(2, 1+1) > > @test("1 + 1 should be 2") # cool! easy to read & write! > def _(self): > self.assertEqual(2, 1+1) > > * Fixture injection support by '@test' decorator. > Arguments of test method are regarded as fixture names and > they are injected by @test decorator automatically. > Instance methods or global functions which name is 'provide_' are > regarded as fixture provider (or builder) for fixture ''. > ex:: > > class SosTest(unittest.TestCase): > > ## > ## fixture providers. > ## > def provide_member1(self): > return {"name": "Haruhi"} > > def provide_member2(self): > return {"name": "Kyon"} > > ## > ## fixture releaser (optional) > ## > def release_member1(self, value): > assert value == {"name": "Haruhi"} > > ## > ## testcase which requires 'member1' and 'member2' fixtures. > ## > @test("validate member's names") > def _(self, member1, member2): > assert member1["name"] == "Haruhi" > assert member2["name"] == "Kyon" > > Dependencies between fixtures are resolved automatically. > ex:: > > class BarTest(unittest.TestCase): > > ## > ## for example: > ## - Fixture 'a' depends on 'b' and 'c'. > ## - Fixture 'c' depends on 'd'. > ## > def provide_a(b, c): return b + c + ["A"] > def provide_b(): return ["B"] > def provide_c(d): return d + ["C"] > def provide_d(): reutrn ["D"] > > ## > ## Dependencies between fixtures are solved automatically. > ## > @test("dependency test") > def _(self, a): > assert a == ["B", "D", "C", "A"] > > If loop exists in dependency then @test reports error. > > If you want to integrate with other fixture library, see the following > example:: > > class MyFixtureManager(object): > def __init__(self): > self.values = { "x": 100, "y": 200 } > def provide(self, name): > return self.values[name] > def release(self, name, value): > pass > > oktest.fixure_manager = MyFixtureResolver() > > > > Other Enhancements and Changes > -- > > * Supports command-line interface to execute test scripts. > * Reporting style is changed. > * New assertion method ``ok(x).attr(name, value)`` to check attribute. > * New assertion method ``ok(x).length(n)``. > * New feature``ok().should`` helps you to check boolean method. > * 'ok(str1) == str2' displays diff if text1 != text2, even when using > with unittest module. > * Assertion ``raises()`` supports regular expression to check error message. > * Helper functions in oktest.dummy module are now available as decorator. > * 'AssertionObject.expected' is renamed to 'AssertionObject.boolean'. > * ``oktest.run()`` is changed to return number of failures and errors of > tests. > * ``before_each()`` and ``after_each()`` are now non-supported. > * (Experimental) New function ``NOT()`` provided which is same as ``NG()``. > * (Experimental) ``skip()`` and ``@skip.when()`` are provided to skip tests:: > > See CHANGES.txt for details. > http://packages.python.org/Oktest/CHANGES.txt > > > Have a nice testing life! > > -- > regards, > makoto kuwata > -- http://mail.python.org/mailman/listinfo/python-list
[Q] ImportError by __import__() on Python >= 3.4
Hi, I have a trouble around __import__(). The following sample code works well on Python <= 3.3, but it raises ImportError on Python >= 3.4. ## importtest.py import sys, os, shutil def test(name): try: ## create 'foo/__init__.py' file os.mkdir(name) with open(name + "/__init__.py", 'w') as f: f.write("X=1") f.flush() ## ipmort 'foo' module mod = __import__(name) finally: if os.path.isdir(name): shutil.rmtree(name) test("foo")# no errors test("bar")# may raise error on Python >= 3.4. Why? Output Example: ### No errors (Python <= 3.3) ubuntu$ export PYTHONPATH=. ubuntu$ for x in 1 2 3 ; do /usr/bin/python3.3 importtest.py; done ### ImportError (Python >= 3.4) ubuntu$ export PYTHONPATH=. ubuntu$ for x in 1 2 3 ; do /usr/bin/python3.4 importtest.py; done Traceback (most recent call last): File "tmp/importtest.py", line 19, in test("bar")# may raise error on Python >= 3.4. Why? File "tmp/importtest.py", line 13, in test mod = __import__(name) ImportError: No module named 'bar' Please give me any advices or hints. Thanks. -- regards, makoto -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] ImportError by __import__() on Python >= 3.4
On Thu, Jun 2, 2016 at 11:15 PM, Michael Selik wrote: > > > On Thu, Jun 2, 2016 at 10:06 AM Makoto Kuwata wrote: > >> os.mkdir(name) >> with open(name + "/__init__.py", 'w') as f: >> f.write("X=1") >> f.flush() >> >> Please give me any advices or hints. >> > > This wasn't your question, but you don't need to flush the file. The > ``with`` statement will automatically flush and close your file for you > after you exit the block. > Thanks. I'm sure that with-statement close file, but not sure whether it flushes or not. Any hints or advices for ogiginal question? -- regards, makoto -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] ImportError by __import__() on Python >= 3.4
On Sat, Jun 4, 2016 at 3:15 AM, MRAB wrote: > On 2016-06-03 06:48, Makoto Kuwata wrote: > > On Fri, Jun 3, 2016 at 9:31 AM, MRAB > pyt...@mrabarnett.plus.com>> wrote: >> >> On 2016-06-02 15:04, Makoto Kuwata wrote: >> >> Hi, >> >> I have a trouble around __import__(). >> The following sample code works well on Python <= 3.3, >> but it raises ImportError on Python >= 3.4. >> >> >> ## importtest.py >> import sys, os, shutil >> >> def test(name): >> try: >> ## create 'foo/__init__.py' file >> os.mkdir(name) >> with open(name + "/__init__.py", 'w') as f: >> f.write("X=1") >> f.flush() >> ## ipmort 'foo' module >> mod = __import__(name) >> finally: >> if os.path.isdir(name): >> shutil.rmtree(name) >> >> test("foo")# no errors >> test("bar")# may raise error on Python >= 3.4. Why? >> >> >> Output Example: >> >> ### No errors (Python <= 3.3) >> ubuntu$ export PYTHONPATH=. >> ubuntu$ for x in 1 2 3 ; do /usr/bin/python3.3 >> importtest.py; done >> >> ### ImportError (Python >= 3.4) >> ubuntu$ export PYTHONPATH=. >> ubuntu$ for x in 1 2 3 ; do /usr/bin/python3.4 >> importtest.py; done >> Traceback (most recent call last): >> File "tmp/importtest.py", line 19, in >> test("bar")# may raise error on Python >= 3.4. Why? >> File "tmp/importtest.py", line 13, in test >> mod = __import__(name) >> ImportError: No module named 'bar' >> >> >> Please give me any advices or hints. >> Thanks. >> >> Things to try: >> >> Does the order matter? If you try "bar" then "foo" does "foo" fail? >> >> >> Yes. Name is not matter. Order is matter. >> >> >> Does the directory matter? >> >> >> No. I created "foo" and "bar" directories in order to create python >> module. >> >> >> Is there something called "bar" in the directory already? >> >> >> No. Sample script removes directories every time. >> >> >> What does the created "bar" directory contain? Does it really >> contain only "__init__.py"? >> >> >> Yes. See sample script for detail. >> >> You're testing the script 3 times; on which iteration does it fail? >> >> >> Because sometimes script will fail and sometimes will work file. >> >> It sounds like it's some kind of race condition, e.g. it hasn't finished > writing the file before it does the import. > Maybe. I want to know why it happens on Python >= 3.4 and not on Python <= 3.3. It happens on both Linux (ubuntu 14.04) and MacOSX (El Captain). -- regards, makoto -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] ImportError by __import__() on Python >= 3.4
On Tue, Jun 7, 2016 at 7:28 AM, Michael Selik wrote: > On Thu, Jun 2, 2016 at 10:06 AM Makoto Kuwata wrote: > >> I have a trouble around __import__(). >> > > The docs for __import__ strongly recommend that you use importlib instead > https://docs.python.org/3.5/library/importlib.html#importlib.import_module > > The docs for ``importlib.import_module`` suggest that you use > ``invalidate_caches`` if you are importing dynamically generated files. > > https://docs.python.org/3.5/library/importlib.html#importlib.invalidate_caches > > I think you'll find this fixes your bug. > Great! I replaced '__import__()' in my code with 'importlib.invalidate_cache(); importlib.import_module()' and found it worked very well. Thank you very much. -- regards, makoto -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] ImportError by __import__() on Python >= 3.4
On Wed, Jun 8, 2016 at 10:24 PM, Michael Selik wrote: > By the way, why choose to write, import, and delete modules? I'd think > exec'ing code would be sufficient. > > In order to test my own framework for web application. It loads controller classes lazily. In other words, it loads python module only when it is required. For example: mappings = [ (r'/api/hello', 'myapp1.api.hello.Hello'),# myapp1/api/hello.py will be loaded lazily ] app = WSGIApplication(mappings) In order to test this framework, it is necessary to create and load python module file dynamically. -- regars, makoto -- https://mail.python.org/mailman/listinfo/python-list
Changing local vars via `locals()`
Hi, folks. I know that it is not possible to change local vars via `locals()` (except in module-level). ``` import sys def f1(): x = 1 d = locals() d['x'] = 2 print(x) #=> 1 (not changed) f1() ``` But I found that it is possible in class definition. ``` import sys class Foo: x = 1 d = locals() d['x'] = 2 print(x) #=> 2 (changed!!!) ``` Can anyone explain about difference between above two? Why it is possiable to change local var via `locals()` only in class definition? -- https://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest.py 0.12.0 released - a new-style testing library
Hi, I released Oktest 0.12.0. https://pypi.python.org/pypi/Oktest/ Oktest is a new-style testing library for Python. ## unittest self.assertEqual(x, y) self.assertNotEqual(x, y) self.assertGreaterEqual(x, y) self.assertIsInstance(obj, cls) self.assertRegexpMatches(text, rexp) ## Oktest.py ok (x) == y ok (x) != y ok (x) >= y ok (obj).is_a(cls) ok (text).match(rexp) Install $ easy_install oktest User's Guide http://www.kuwata-lab.com/oktest/oktest-py_users-guide.html Changes http://www.kuwata-lab.com/oktest/oktest-py_CHANGES.txt Highlight on this release - This release contains new and important enhancements. * [enhance] `ok (actual) == expected' reports unified diff. Example:: AssertionError: --- expected +++ actual @@ -1,3 +1,3 @@ {'email': 'har...@sos-brigade.org', - 'gender': 'Female', + 'gender': 'female', 'username': 'Haruhi'} * [enhance] @at_end decorator registers callback which is called at end of test case. :: @test("example to remove temporary file automatically") def _(self): ## create dummy file with open('dummy.txt', 'w') as f: f.write("blablabla") ## register callback to delete dummy file at end of test case @at_end def _(): os.unlink(tmpfile) ## do test with open(tmpfile) as f: ok (f.read()) == "blablabla" * [enhance] New assertions for WebOb/Werkzeug response object. :: ok (resp).is_response(200) # status code ok (resp).is_response((302, 303)) # status code ok (resp).is_response('200 OK') # status line ok (resp).is_response(200, 'image/jpeg')# content-type ok (resp).is_response(200, re.compile(r'^image/(jpeg|png|gif)$')) ok (resp).is_response(302).header("Location", "/") # header ok (resp).is_response(200).json({"status": "OK"}) # json data ok (resp).is_response(200).body("Hello") # response body ok (resp).is_response(200).body(re.compile(".*?")) * [bugfix] @todo decorator now supports fixture injection. :: @test('example') @todo # error on previous version but not on this release def _(self, x): assert False You can see all enhancements and changes. See http://www.kuwata-lab.com/oktest/oktest-py_CHANGES.txt Have fun! -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest.py 0.13.0 - a new style testing library
Oktest 0.13.0 is released. https://pypi.python.org/pypi/Oktest/ Oktest is a new-style testing library for Python. ## unittest self.assertEqual(x, y) self.assertNotEqual(x, y) self.assertGreaterEqual(x, y) self.assertIsInstance(obj, cls) self.assertRegexpMatches(text, rexp) ## Oktest.py ok (x) == y ok (x) != y ok (x) >= y ok (obj).is_a(cls) ok (text).match(rexp) It is possible to assert WebOb/Werkzeug/Requests response object easily. ok (response).is_response(200).json({"status":"OK"}) Install $ easy_install oktest User's Guide http://www.kuwata-lab.com/oktest/oktest-py_users-guide.html Changes http://www.kuwata-lab.com/oktest/oktest-py_CHANGES.txt What's New -- * [enhance] `ok().is_response()' now supports Requests. Example:: import requests resp = requests.get('http://www.example.com/') ok (resp).is_response(200, 'text/html') * [enhance] (Experimental) Add 'oktest.web' module to help WSGI app testing. Example:: ## create WSGI application class App(object): def __call__(self, environ, start_response): status = '200 OK' headers = [('Content-Type', 'application/json')] body= [b'''{"message":"Hello!"}'''] # bytes, not unicode start_response(status, headers) return body app = App() ## test for app import unittest import oktest from oktest import test, ok, subject from oktest.web import WSGITest # ! http = WSGITest(app) # ! https = WSGITest(app, {'HTTPS': 'on'})# ! class AppTest(unittest.TestCase): with subject('GET /'): @test("Returns messaging JSON.") def _(self): resp = http.GET('/') # or http('GET', '/') ok (resp).is_response(200).json({"message": "Hello!"}) ## or status, headers, body = http.GET('/') # or http('GET', '/') ok (status) == '200 OK' ok (headers) == [('Content-Type', 'application/json')] ok (body)== [b'''{"message":"Hello!"}'''] if __name__ == '__main__': oktest.main() -- regars, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
ANN: Benchmarker 4.0.0 released - small but awesome benchmark utility
I released Benchmarker ver 4.0.0 http://pypi.python.org/pypi/Benchmarker/ http://pythonhosted.org/Benchmarker/ Benchmarker is a small utility to benchmark your code. *NOTICE* This release doesn't have compatibility with ver 3.x. Installation $ sudo pip install Benchmarker Example --- example.py:: from benchmarker import Benchmarker with Benchmarker(1000*1000, width=20) as bench: s1, s2, s3, s4, s5 = "Haruhi", "Mikuru", "Yuki", "Itsuki", "Kyon" @bench(None) def _(bm): for _ in bm: ## empty loop pass @bench("concat") def _(bm): for _ in bm: s = s1 + s2 + s3 + s4 + s5 @bench("join") def _(bm): for _ in bm: s = "".join((s1, s2, s3, s4, s5)) @bench("format") def _(bm): for _ in bm: s = "%s%s%s%s%s" % (s1, s2, s3, s4, s5) Output example:: $ python example.py -h # show help message. $ python example.py # or python example.py -n 100 ## benchmarker: release 4.0.0 (for python) ## python version: 3.4.1 ## python compiler: GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.51) ## python platform: Darwin-14.0.0-x86_64-i386-64bit ## python executable: /usr/local/bin/python ## cpu model: Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz ## parameters: loop=100, cycle=1, extra=0 ##real(total= user+ sys) (Empty) 0.03350.03000.03000. concat 0.41920.42000.41000.0100 join0.36740.37000.37000. format 0.47650.46000.46000. ## Rankingreal join0.3674 (100.0) concat 0.4192 ( 87.6) ** format 0.4765 ( 77.1) *** ## Matrix real[01][02][03] [01] join 0.3674 100.0 114.1 129.7 [02] concat 0.419287.6 100.0 113.7 [03] format 0.476577.188.0 100.0 Notice that empty loop times (real, user, sys and total) are subtracted from other benchmark times automatically. For example:: === benchmark labelreal (second) --- join 0.3674 (= 0.4009 - 0.0335) concat 0.4192 (= 0.4527 - 0.0335) format 0.4765 (= 0.5100 - 0.0335) ======= See http://pythonhosted.org/Benchmarker/ for details. Have fun! -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Re: ANN: Benchmarker 4.0.0 released - small but awesome benchmark utility
I released Benchmarker.py ver 4.0.1 which includes several bug fixes. If you failed to install Benchmarker.py 4.0.0, try 4.0.1. http://pypi.python.org/pypi/Benchmarker/ http://pythonhosted.org/Benchmarker/ Bugfix -- * Fix 'setup.py' not to import 'ez_setup' * Fix to parse user-defined properties in command-line. * Add description about user-defined properties. * Fix example code to work on Python 2.6. * Fix test script. -- regards, makoto kuwata On Mon, Dec 15, 2014 at 9:43 PM, Makoto Kuwata wrote: > > I released Benchmarker ver 4.0.0 > http://pypi.python.org/pypi/Benchmarker/ > http://pythonhosted.org/Benchmarker/ > > Benchmarker is a small utility to benchmark your code. > > *NOTICE* This release doesn't have compatibility with ver 3.x. > > > Installation > > > $ sudo pip install Benchmarker > > > Example > --- > > example.py:: > > from benchmarker import Benchmarker > > with Benchmarker(1000*1000, width=20) as bench: > > s1, s2, s3, s4, s5 = "Haruhi", "Mikuru", "Yuki", "Itsuki", "Kyon" > > @bench(None) > def _(bm): > for _ in bm: ## empty loop > pass > > @bench("concat") > def _(bm): > for _ in bm: > s = s1 + s2 + s3 + s4 + s5 > > @bench("join") > def _(bm): > for _ in bm: > s = "".join((s1, s2, s3, s4, s5)) > > @bench("format") > def _(bm): > for _ in bm: > s = "%s%s%s%s%s" % (s1, s2, s3, s4, s5) > > Output example:: > > $ python example.py -h # show help message. > $ python example.py # or python example.py -n 100 > ## benchmarker: release 4.0.0 (for python) > ## python version: 3.4.1 > ## python compiler: GCC 4.2.1 Compatible Apple LLVM 6.0 > (clang-600.0.51) > ## python platform: Darwin-14.0.0-x86_64-i386-64bit > ## python executable: /usr/local/bin/python > ## cpu model: Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz > ## parameters: loop=100, cycle=1, extra=0 > > ##real(total= user+ sys) > (Empty) 0.03350.03000.03000. > concat 0.41920.42000.41000.0100 > join0.36740.37000.37000. > format 0.47650.46000.46000. > > ## Rankingreal > join0.3674 (100.0) > concat 0.4192 ( 87.6) ** > format 0.4765 ( 77.1) *** > > ## Matrix real[01][02][03] > [01] join 0.3674 100.0 114.1 129.7 > [02] concat 0.419287.6 100.0 113.7 > [03] format 0.476577.188.0 100.0 > > Notice that empty loop times (real, user, sys and total) are > subtracted from other benchmark times automatically. > For example:: > > === > benchmark labelreal (second) > ----------- > join 0.3674 (= 0.4009 - 0.0335) > concat 0.4192 (= 0.4527 - 0.0335) > format 0.4765 (= 0.5100 - 0.0335) > === > > > See http://pythonhosted.org/Benchmarker/ for details. > > > Have fun! > > -- > regards, > makoto kuwata > > -- https://mail.python.org/mailman/listinfo/python-list
[Q] Beaker 1.6.4 not work on Python3
Hi, Does Beaker 1.6.4 work on Python3 ? Is there anyone using Beaker on Python3? I got the following error on Python 3.3: File "/opt/lang/python/3.2.2/lib/python3.2/http/cookies.py", line 486, in __setitem__ rval, cval = self.value_encode(value) File "/opt/lang/python/3.2.2/lib/python3.2/site-packages/Beaker-1.6.4-py3.2.egg/beaker/session.py", line 70, in value_encode sig = HMAC.new(self.secret, val.encode('UTF-8'), SHA1).hexdigest() AttributeError: 'bytes' object has no attribute 'encode' The following is a monkey patch to avoid this error, but I'm not sure that it is correct solution. from beaker.crypto import hmac as HMAC, hmac_sha1 as SHA1 from beaker.session import SignedCookie def value_encode(self, val): #sig = HMAC.new(self.secret, val.encode('UTF-8'), SHA1).hexdigest() sig = HMAC.new(self.secret, val, SHA1).hexdigest() return str(val), ("%s%s" % (sig, val)) SignedCookie.value_encode = value_encode And, even with monkey patching, Beaker's SessionMiddleware doesn't save session correctly on Python3. Please help me: I want to run Beaker 1.6.4 on Python 3. (Pyton 3.3.3, MacOSX) Here is my sample code (which works on Python2.7 very well!): -- # -*- coding: utf-8 -*- import sys import waitress from beaker.middleware import SessionMiddleware def testapp(environ, start_response): session = environ.get('beaker.session') count = session.get('count', 0) + 1 session['count'] = count session.save() content = "count=%s" % count # start_response('200 OK', [('Content-Type', 'text/plain')]) return [content.encode('utf-8')] config = { 'session.type': 'cookie', 'session.validate_key': 'mysecretstring', } app = SessionMiddleware(testapp, config=config) ## monkey patch for Python3 python3 = sys.version_info[0] == 3 if 0 and python3: from beaker.crypto import hmac as HMAC, hmac_sha1 as SHA1 from beaker.session import SignedCookie def value_encode(self, val): #sig = HMAC.new(self.secret, val.encode('UTF-8'), SHA1).hexdigest() sig = HMAC.new(self.secret, val, SHA1).hexdigest() return str(val), ("%s%s" % (sig, val)) SignedCookie.value_encode = value_encode ## waitress.serve(app, port=8080) -- -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Re: [RELEASED] Python 3.3.4
Congrat! By the way, I can't find Python-3.3.4.tar.bz2 in: http://www.python.org/ftp/python/3.3.4/ Python-3.3.{1,2,3}.tar.bz2 and Python-3.4.0.tar.bz2 are provided, but Python-3.3.4.tar.bz2 is not. Why? # I hope that Python-3.3.4.tar.bz2 is also provided. -- regards, makoto kuwata On Tue, Feb 11, 2014 at 5:55 AM, Georg Brandl wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > On behalf of the Python development team, I'm very happy to announce > the release of Python 3.3.4. > > Python 3.3.4 includes several security fixes and over 120 bug fixes > compared to the Python 3.3.3 release. > > This release fully supports OS X 10.9 Mavericks. In particular, this > release fixes an issue that could cause previous versions of Python to > crash when typing in interactive mode on OS X 10.9. > > Python 3.3 includes a range of improvements of the 3.x series, as well > as easier porting between 2.x and 3.x. In total, almost 500 API items > are new or improved in Python 3.3. For a more extensive list of > changes in the 3.3 series, see > > http://docs.python.org/3.3/whatsnew/3.3.html > > To download Python 3.3.4 visit: > > http://www.python.org/download/releases/3.3.4/ > > > This is a production release, please report any bugs to > > http://bugs.python.org/ > > > Enjoy! > > - -- > Georg Brandl, Release Manager > georg at python.org > (on behalf of the entire python-dev team and 3.3's contributors) > -BEGIN PGP SIGNATURE- > Version: GnuPG v2.0.22 (GNU/Linux) > > iEYEARECAAYFAlL5PMwACgkQN9GcIYhpnLCv4wCePNVqwsOYCHdJBix2bKk4PNpK > GBoAnRML2x6obCssnUJe5xwuUZYw8ZSY > =+/Nz > -END PGP SIGNATURE- > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest.py 0.14.0 released - a new-style testing library
I released Oktest.py 0.14.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Oktest.py is a new-style testing library for Python:: from oktest import ok, NG ok (x) > 0 # same as assertTrue(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assertTrue(isinstance(u'foo', unicode)) ok ('A.txt').is_file() # same as assertTrue(os.path.isfile('A.txt')) It supports WSGI Application testing:: from oktest.web import WSGITest http = WSGITest(app) resp = http.GET('/') ok (resp).is_response(200).json({"status": "OK"}) See http://packages.python.org/Oktest/ for details. New features * [enhance] Response object returned by `WSGITest#GET()' or '#POST()' now supports `body_json' property. Example:: from oktest.web import WSGITest http = WSGITest(app) resp = http.GET('/') print(resp.body_json) * [change] `headers` argument of `WSGITest#GET()' (or '#POST()' and so on) now means HTTP headers, not environ values. Example:: ## version <= 0.13 http.GET('/', headers={'HTTP_COOKIE': 'name=val'}) ## version >= 0.14 http.GET('/', headers={'Cookie': 'name=val'}) ## or http.GET('/', environ={'HTTP_COOKIE': 'name=val'}) * [enhance] (Experimental) `oktest.validator.Validator' class is added. It is convenient to test complex data structure. Example:: from oktest.validator import Validator as V ok (resp.body_json) == { "status": "OK", "member": { "name": "Haruhi", "gender": V('gender', enum=('F', 'M')), "age": V('age', type=int, between=(15, 18)), "birthday": V('created_at', pattern=r'^\d\d\d\d-\d\d-\d\d$') } } See users guide for details. http://www.kuwata-lab.com/oktest/oktest-py_users-guide.html#validator -- regars, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Function decorator having arguments is complicated
I want to ask Python experts about function decorator which has arguments. I feel that function decorator having arguments is complicated, because three 'def' are nested: def multiply(n): def deco(func): def newfunc(*args, **kwargs): return n * func(*args, **kwargs) return newfunc return deco @multiply(4) def f1(x, y): return x+y print(f1(2, 3)) #=> 20 (= 4 * (2+3)) If function decorator notation could take arguments, decorator definition would be more simple: def multiply(func, n): def newfunc(*args, **kwargs): return n * func(*args, **kwargs) return newfunc @multiply 4 # ex: @decorator arg1, arg2, arg3 def f1(x, y): return x+y How do you think about this idea? -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Backport fix on #16611 to Python 2.7
Hi, I found a bug on SimpleCookie#load() which doesn't parse 'secure' and 'httponly' attributes correctly. try: from Cookie import SimpleCookie except: from http.cookies import SimpleCookie ck = SimpleCookie() ck.load('name1=value1; Path=/xxx; httponly; secure') print(ck.output()) #=> Set-Cookie: name1=value1; Path=/xxx # (Missing 'httponly' and 'secure' attributes on Python < 3.3.2!) This bug has been registered as #16611, and fixed on 3.3.3. But it is not backported into Python 2.7. http://bugs.python.org/issue16611 My question: Is there any plan to backport the fix to Python 2.7? -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Re: Backport fix on #16611 to Python 2.7
Sorry, I failed to post reply: -- Forwarded message -- From: Makoto Kuwata Date: Wed, Jun 18, 2014 at 5:32 PM Subject: Re: Backport fix on #16611 to Python 2.7 To: Terry Reedy On Wed, Jun 18, 2014 at 12:31 PM, Terry Reedy wrote: > > Do you have any plan to upgrade to 3.4, so you get *all* the bugfixes > possible? > > Please ask to Google. Google AppEngine doesn't support 3.4 yet. On 6/17/2014 9:08 PM, Mark Lawrence wrote: > The simple answer is no. The longer answer is, if you want to propose a >> patch to backport the fix, it's more likely that somebody will do the >> work to commit it as support for 2.7 has been extended until 2020. >> Please note that I said "more likely", there's no guarantee given that >> Python relies so much on volunteers. >> > I got it. Thank you. > > The extended support is mostly focused on build (compiler) and security > (internet) issues, to support software already written and *working* on 2.7. > > That said, if someone were to modify the patch to it could be imported to > 2.7 (at least changing file names) or make changes to the relevant files by > hand; run the tests, with whatever changes are needed so that they do run; > and change the code as needed so all tests pass; sign the contributor > agreement; and post a properly formatted test to the tracker and indicate a > readiness to respond to comments; then it might get some attention. > > -- > Terry Jan Reedy > I'm sorry if I bothered you. I just want to know whether the existing bugfix will be backported or not. I should be more careful to post even a small question. -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
[Q] override __init__() method of classes implemented in C
Is it impossible to override __init__() method of classes implemented in C (such as datetime.datetime) ? example.py: from datetime import datetime class Foo(datetime): def __init__(self): pass obj = Foo() Result (Python 2.7.7 and 3.4.1): Traceback (most recent call last): File "hoge.py", line 7, in obj = Foo() TypeError: Required argument 'year' (pos 1) not found It seems to be failed to override datetime.__init__() in subclass. -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] override __init__() method of classes implemented in C
On Mon, Jun 30, 2014 at 4:52 PM, Chris Angelico wrote: > > Actually, __init__ isn't the problem here, __new__ is. > > class Foo(datetime): > def __new__(self): > return super().__new__(self,2014,1,1) > > >>> Foo() > Foo(2014, 1, 1, 0, 0) > > Maybe that helps, maybe it doesn't, but the issue you're seeing is > specific to that class. > Got it! Thank you! -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest.py 0.15.0 released; a new-style testing library
Hi all, I released Oktest.py 0.15.0. * PyPI: https://pypi.python.org/pypi/Oktest/ * Document: http://www.kuwata-lab.com/oktest/oktest-py_users-guide.html What is Oktest.py? -- Oktest.py is a new-style testing library for Python. Example:: from oktest import test, ok, NG class FooTest(unittest.TestCase): @test("1 + 1 should be 2") def _(self): ok (1+1) == 2 # same as assertEqual(2, 1+1) @test("other examples") def _(self): ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (n) > 0 # same as assertTrue(n > 0) ok (fn).raises(Error) # same as assertRaises(Error, fn) ok ([]).is_a(list) # same as assertTrue(isinstance([], list)) NG ([]).is_a(tuple)# same as assertTrue(not isinstance([], tuple)) ok ('A.txt').is_file() # same as assertTrue(os.path.isfile('A.txt')) NG ('A.txt').is_dir() # same as assertTrue(not os.path.isdir('A.txt')) See http://www.kuwata-lab.com/oktest/oktest-py_users-guide.html for details. Changes in this release --- * [enhance] oktest.web.WSGITest class supports multipart form data. * [enhance] oktest.web.WSGITest class supports 'Cookie' and 'Set-Cookie'. * [enhance] New assertion methods. ok (xs).all(lambda x: x is None) # ok when all items in xs are None ok (xs).any(lambda x: x is None) # ok when there is None in xs ok (x).between(minval, maxval) # ok when minval <= x <= maxval ok (xs).length([minlen, maxlen]) # ok when minlen <= len(xs) <= maxlen ok (dictionary).has_key('key') # ok when dictinary has key ok (dictionary).has_item('key','val') # ok when dictionary has key an val * [enhance] New utility function 'options_of()' to get user-defined options. * [bugfix] oktest.web.WSGITest now works on Python 3.4. * [bugfix] fix oktest.web.WSGITest class to encode urlpath when multibyte. See http://www.kuwata-lab.com/oktest/oktest-py_CHANGES.txt for details. -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
[Q] is 'yield from' syntax sugar for 'for'+'yield'?
Question about 'yield from'. I understand that:: yield from xs is syntax suger of:: for x in xs: yield x And:: val = yield from xs is same as:: for x in xs: ret = yield x val = ret Is it true? Do I understand correctly? quote from https://docs.python.org/3/whatsnew/3.3.html#pep-380-syntax-for-delegating-to-a-subgenerator > For simple iterators, yield from iterable is essentially > just a shortened form of for item in iterable: yield item: -- regards, kwatch -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] is 'yield from' syntax sugar for 'for'+'yield'?
On Thu, Aug 14, 2014 at 6:38 PM, Chris Angelico wrote: > On Thu, Aug 14, 2014 at 7:35 PM, Makoto Kuwata wrote: > > I understand that:: > > > > yield from xs > > > > is syntax suger of:: > > > > for x in xs: > > yield x > > Not just. It's like that for simple cases, but there are edge cases > that are much more complicated to do manually, and are simply taken > care of. Best would be to read the PEP itself: > > http://www.python.org/dev/peps/pep-0380/ > > ChrisA > Thank you. It seems too complicated... I understand that 'val = yield from xs' is completely different from:: for x in xs: ret = yield x val = x Return value is propagated by StopIteration, like: it = iter(xs) try: while 1: yield next(it) except StopIteration as ex: val = ex.value Thanks. -- regards, kwatch -- https://mail.python.org/mailman/listinfo/python-list
Re: [Q] is 'yield from' syntax sugar for 'for'+'yield'?
On Thu, Aug 14, 2014 at 7:02 PM, Chris Angelico wrote: > On Thu, Aug 14, 2014 at 7:59 PM, Makoto Kuwata wrote: > > I understand that 'val = yield from xs' is completely different from:: > > > >for x in xs: > > ret = yield x > >val = x > > > > Return value is propagated by StopIteration, like: > > > >it = iter(xs) > >try: > > while 1: > >yield next(it) > >except StopIteration as ex: > > val = ex.value > > It's even more complicated than that. The PEP specifies the exact > semantics. > > ChrisA > Well, I wrote the above code in order to describe `value is propagated by StopIteration' because I misunderstood that it is propagated by return value of yield statement (see my first post). I have known that `yield from` is very complicated (thanks to your reply). -- regards, kwatch -- https://mail.python.org/mailman/listinfo/python-list
[ANN] pyKook 0.6.0 - task automation tool for Python, similar to Rake or Ant
Hi, I have released pyKook 0.6.0. http://pypi.python.org/pypi/Kook/0.6.0 http://www.kuwata-lab.com/kook/ http://www.kuwata-lab.com/kook/pykook-users-guide.html In this release, a lot of enhancements are introduced. pyKook Overview --- pyKook is a task automation tool for Python, similar to Rake or Ant. (Kookbook.py): kookbook.default = 'build' @recipe(None, ['hello']) def build(c): """build all""" pass @recipe('hello', ['hello.o']) def file_hello(c): """build 'hello' from 'hello.o'""" system(c%'gcc -o $(product) $(ingred)') @recipe('*.o', ['$(1).c', '$(1).h']) def file_o(c): system(c%'gcc -c $(ingred)') Command-line: bash> kk # or pykook $ gcc -c hello.c ### *** hello.o (recipe=file_o) $ gcc -c hello.c ### ** hello (recipe=file_hello) $ gcc -o hello hello.o ### * build (recipe=build) See http://www.kuwata-lab.com/kook/pykook-users-guide.html for details. Enhancements in this release * 'kookbook' variable is available in your cookbook to specify materials or default product. * Recipe meta-programming support. You can manipulate recipe objects directly. * Load other cookbooks by kookbook.load(). This enables you to split your Kookbook.py into several files. * Support some useful task recipes: clean, sweep, and all. * Namespace is now supported. It is called as 'Category' in Kook. * Concatenation supported. You can concatenate your cookbook and pyKook libraries into a file. Using concatenated file, user doesn't need to install pyKook at all. * Argument description is available. * Private spice option is available. * New command 'pushd()' provided. See http://www.kuwata-lab.com/kook/pykook-CHANGES.txt for details. Have fun! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Question about metaclass
Hi, I want to define a special class which groups functions, like: class Greepting(FuncGroup): def hello(): # no self, no @staticmethod! print("Hello!") def goodbye():# no self, no @staticmethod! print("Good Bye!") Geeting.hello():#=> "Hello!" Geeting.goodbye(): #=> "Good Bye!" I tried the following code which converts instance mthods into static method automatically, but I don't get result what I want. (python 2.5.5) import sys from types import FunctionType class MetaClass(type): def __init__(cls, name, bases, dct): ## converts instance methods to static methods automatically for k in dct.keys(): v = dct[k] if isinstance(v, FunctionType): dct[k] = staticmethod(v) print("*** debug: dct[%r] = %r" % (k, dct[k])) #=> class FuncGroup(object): __metaclass__ = MetaClass class Greeting(FuncGroup): def hello(): print("Hello!") def goodbye(): print("Good Bye!") print("*** type(Greeting.hello)=%r" % type(Greeting.hello) #=> print("*** type(Greeting.goodbye)=%r" % type(Greeting.goodbye) #=> Could you give me advice? -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: Question about metaclass
On Wed, Nov 2, 2011 at 1:40 PM, Ian Kelly wrote: > > If you want to customize the dict you need to do it in __new__, not > __init__. By the time __init__ is called, the class has already been > created. > > class MetaClass(type): > def __new__(mcs, name, bases, dict): > for k, v in dict.items(): > if isinstance(v, FunctionType): > dict[k] = staticmethod(v) > return type.__new__(mcs, name, bases, dict) Great! It works perfectly! > If you were using a more recent Python version, I would suggest using > a class decorator instead of a metaclass. You can still do this in > Python 2.5, but the syntax will be more awkward. > > # Python 2.6+ > def FuncGroup(class_): > for k, v in class_.__dict__.items(): > if isinstance(v, FunctionType): > setattr(class_, k, staticmethod(v)) > return class_ > > @FuncGroup > class Greeting(object): > def hello(): > print("Hello!") > > # Python 2.5 > class Greeting(object): > def hello(): > print("Hello!") > Greeting = FuncGroup(Greeting) This is so good method. Thank you, Ian. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] pyKook 0.7.0 - task automation tool for Python, similar to Rake or Ant
## start() is converted into staticmethod assert type(apache.__dict__['start']) == staticmethod from types import FunctionType assert type(apache.start) == FuntionType This makes execution of other recipes in category easier:: class apache(Category): @recipe def start(c): ... @recipe def stop(c): ... @recipe def restart(c): apache.start(c)# execute other recipe apache.stop(c) # execute other recipe * (internal) kook.config.stdout and kook.config.stderr are removed. See http://www.kuwata-lab.com/kook/pykook-CHANGES.txt for details. Have fun! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest.py 0.10.0 released - a new-style testing library
Hi, I released Oktest.py 0.10.0. http://packages.python.org/Oktest/ http://www.kuwata-lab.com/oktest/ Oktest.py is a new-style testing library for Python. :: from oktest import ok, NG ok (x) > 0 # same as assertTrue(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assertTrue(isinstance(u'foo', unicode)) NG (u'foo').is_a(int) # same as assertTrue(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assertTrue(os.path.isfile('A.txt')) NG ('A.txt').is_dir() # same as assertTrue(not os.path.isdir('A.txt')) See http://www.kuwata-lab.com/oktest/oktest-py_users-guide.html for details. Changes and Enhancements * [change] 'oktest.spec()' is obsoleted completely. It will print warning message if you use it. * [change] 'oktest.helper' module is renamed to 'oktest.util'. ('oktest.helper' is still available for backward compabibility.) * [enhance] Add 'oktest.main()' which is a replacement of 'oktest.run()'. Using 'oktest.main()' instead of 'oktest.run()', command options are available. ex:: ## for example: $ python test/foobar_test.py -sp -f test='*keyword*' ## is almost same as: $ python -m oktest test/foobar_test.py -sp -f test='*keyword*' * [enhance] Add 'oktest.fail(message)' which is same as 'unittest.fail(message)'. ex:: from oktest import fail fail("not impelmented yet")# will raise AssertionError * [enhance] (Experimental) Add '@todo' decorator which is equivarent to '@unittest.expectedFailure'. ex:: from oktest import ok, test, todo def add(x, y): return 0 # not implemented yet! class AddTest(unittest.TestCase): @test("returns sum of arguments.") @todo # equivarent to @unittest.expectedFailure def _(self): ok (10, 20) == 30 ## will be failed expectedly ## (because not implemented yet) Expected failure of assertion is reported as '[TODO]', not '[Failed]'. * [enhance] (Experimental) Test context supported. It helps you to describe specification in structured style. ex:: from oktest import ok, test from oktest.context import subject, situation class SampleTestCase(unittest.TestCase): SUBJECT = "class 'Sample'" with subject("method1()"): with situation("when condition:"): @test("spec1") def _(self): ... @test("spec2") def _(self): ... with situation("else:"): @test("spec3") def _(self): ... Output exmple:: $ python test/example_test.py * class 'Sample' + method1() + when condition: - [ok] spec1 - [ok] spec2 + else: - [ok] spec3 ## total:3, passed:3, failed:0, error:0, skipped:0 (elapsed 0.000) -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
easy_install doesn't install non-package *.py file
I got trouble about easy_install command. My package: README.rst setup.py foobar/ foobar/__init__.py foobar/data/ foobar/data/template.py In the above example, 'foobar/data/template.py' is just a template data file (= not a python module file). (notice that 'foobar/data/__init__.py' doesn't exist.) In this case, 'foobar/data/template.py' file is NOT installed when trying 'easy_install foobar'. This is trouble what I got. I found that: * foobar.tar.gz created by 'easy_install sdist' contains 'foobar/data/template.py' correctly. * foobar.egg created by 'easy_install bdist' doesn't contain 'foobar/data/template.py' file. Question: how can I enforce easy_install command to install 'foobar/data/template.py' (or non-package *.py file)? -- regars, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: easy_install doesn't install non-package *.py file
On Wed, Nov 9, 2011 at 4:09 AM, Terry Reedy wrote: > On 11/7/2011 11:32 PM, Makoto Kuwata wrote: >> >> I got trouble about easy_install command. >> >> My package: >> >> README.rst >> setup.py >> foobar/ >> foobar/__init__.py >> foobar/data/ >> foobar/data/template.py >> >> In the above example, 'foobar/data/template.py' is just a >> template data file (= not a python module file). > > Then why is it .py? If it is just data, use .txt. If .py, it should be > python code run either directly or imported, though I suppose you could exec > it. (I have no idea how renaming would affect your problem.) > I want to use template names according to language, such as template.py, template.html, template.rst, template.js, and so on. My question is "how to include non-python files into egg file?" I may change file name suffix from '.py' to '.py.template', but it doesn't solve my problem. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: easy_install doesn't install non-package *.py file
On Thu, Nov 10, 2011 at 9:58 AM, Makoto Kuwata wrote: > On Wed, Nov 9, 2011 at 4:09 AM, Terry Reedy wrote: >> On 11/7/2011 11:32 PM, Makoto Kuwata wrote: >>> >>> I got trouble about easy_install command. >>> >>> My package: >>> >>> README.rst >>> setup.py >>> foobar/ >>> foobar/__init__.py >>> foobar/data/ >>> foobar/data/template.py >>> >>> In the above example, 'foobar/data/template.py' is just a >>> template data file (= not a python module file). >> >> Then why is it .py? If it is just data, use .txt. If .py, it should be >> python code run either directly or imported, though I suppose you could exec >> it. (I have no idea how renaming would affect your problem.) >> > > I want to use template names according to language, > such as template.py, template.html, template.rst, template.js, and so on. > > My question is "how to include non-python files into egg file?" > I may change file name suffix from '.py' to '.py.template', > but it doesn't solve my problem. I create sample project to explain my trouble. Sample project source code: https://bitbucket.org/kwatch/helloworld/src When 'python setup.py sdist', all files are copied correctly. https://bitbucket.org/kwatch/helloworld/wiki/python_setup.py_sdist $ python setup.py sdist hard linking helloworld/__init__.py -> HelloWorld-0.1.0/helloworld hard linking helloworld/foo.py -> HelloWorld-0.1.0/helloworld hard linking helloworld/sub/__init__.py -> HelloWorld-0.1.0/helloworld/sub hard linking helloworld/sub/bar.py -> HelloWorld-0.1.0/helloworld/sub But when 'python setup.py bdist_egg', some files are not copied. https://bitbucket.org/kwatch/helloworld/wiki/python_setup.py_bdist_egg $ python setup.py bdist # 'helloworld/sub/{__init__,bar}.py' are not copied! copying build/lib/helloworld/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/helloworld copying build/lib/helloworld/foo.py -> build/bdist.macosx-10.4-x86_64/egg/helloworld Could you help me? -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: easy_install doesn't install non-package *.py file
On Thu, Nov 10, 2011 at 6:08 PM, Jonathan Hartley wrote: > Hey. I don't know the details, but your setup.py needs to use either the > 'package_data' or the 'data_files' entry in the dict you pass to setup. These > can specify files you want included in the sdist which aren't package files. > > There are many complications with using them though. One of them in > particular (I don't remember which one) installs the files you specify in a > different place depending on whether the user is installing the sdist from > local files (python setup.py install) or using pip, so be sure to test both > ways. 'package_data' is the solution for my trouble. Thank you very much, Jonathan. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] pyKook 0.7.1 - task automation tool for Python, similar to Rake or Ant
I have released pyKook 0.7.1.http://pypi.python.org/pypi/Kook/http://www.kuwata-lab.com/kook/http://www.kuwata-lab.com/kook/pykook-users-guide.html pyKook is a task automation tool for Python, similar to Rake or Ant. Bugfix in this release-- * Fixed to include 'kook/books/*.py' into .egg file --regads,makoto kuwata On Sat, Nov 5, 2011 at 3:06 PM, Makoto Kuwata wrote: > Hi, > > I have released pyKook 0.7.0. > http://pypi.python.org/pypi/Kook/ > http://www.kuwata-lab.com/kook/ > http://www.kuwata-lab.com/kook/pykook-users-guide.html > > In this release, you can run commands on remote machines using ssh. > This is very useful to deploy your application. > > > pyKook Overview > --- > > pyKook is a task automation tool for Python, similar to Rake or Ant. > > (Kookbook.py): > > kookbook.default = 'build' > > ## task > @recipe(None, ['hello']) > def build(c): > """build all""" > pass > > ## file > @recipe('hello', ['hello.o']) > def file_hello(c): > """build 'hello' from 'hello.o'""" > system(c%'gcc -o $(product) $(ingred)') > > ## rule > @recipe('*.o', ['$(1).c', '$(1).h']) > def file_o(c): > system(c%'gcc -c $(ingred)') > > > Command-line: > > bash> kk # or pykook > $ gcc -c hello.c > ### *** hello.o (recipe=file_o) > $ gcc -c hello.c > ### ** hello (recipe=file_hello) > $ gcc -o hello hello.o > ### * build (recipe=build) > > See http://www.kuwata-lab.com/kook/pykook-users-guide.html for details. > > > Enhancements in this release > > > * (EXPERIMENTAL!!) Remote command execution (ssh and sftp) is available. > This is very useful to deploy your application into servers. > > Ex (Kookbook.py):: > > from kook.remote import Remote > remote = Remote( > hosts = ['www1', 'www2', 'user3@www3:10022'], > port = 22, > user = 'user1', > #password = None, # for login, '~/.ssh/id_rsa' and sudo > passphrase = None, # only for '~/.ssh/id_rsa' > sudo_password = 'xxx', # only for sudo command > ) > > @recipe > @remotes(remote) > def hostinfo(c): > """show hostname""" > ssh = c.ssh > ssh('hostname') # run command with ssh > ssh('whomai') # run command with ssh > ssh.sudo('whoami') # run command with sudo > > @recipe > @remotes(remote) > def exchange(c): > """upload and download files""" > ssh = c.ssh > with ssh.pushd('work/apps'): > ssh.get('file.remote') # download a file > ssh.put('file.local') # upload a file > ssh.mget('remote.*') # download files > ssh.mput('local.*') # upload files > > Notice that you must configure ssh at first and confirm that > you can log into servers without typing password:: > > bash> ssh user1@www1 > bash> ssh user1@www2 > bash> ssh -p 10022 user3@www3 > bash> kk hostinfo > ### * showinfo (recipe=showinfo) > [user1@www1]$ hostame > www1 > [user1@www1]$ whoami > user1 > [user1@www1]$ sudo whoami > root > [user2@www2]$ hostame > www2 > [user2@www2]$ whoami > user2 > [user2@www2]$ sudo whoami > root > [user3@www3]$ hostame > www3 > [user3@www3]$ whami > user3 > [user3@www3]$ sudo whoami > root > > Currently commands are executed sequencially (not in parallel). > > * (EXPERIMENTAL!!) Password object supported. > Password object asks you to enter password in prompt when necessary. > > Ex (Kookbook.py):: > > from kook.remote import Remote, Password > remote = Remote( > hosts = ['user1@www1:22'], > #password = Password('login'), > passphrase = Password('~/.ssh/id_rsa'), > sudo_password = Password('sudo command') > ) > # > @recipe &
[ANN] PikoTest.py - a small testing library
I released PikoTest.py 0.1.0. http://pypi.python.org/pypi/PicoTest PikoTest.py is a samll testing library for Python. Features: * Structured Test * Setup/Teardown * Fixture Injection * Skip Test * TODO Example:: from __future__ import with_statement import picotest test = picotest.new() with test("type 'str'"): with test("operator '*'"): @test("repeats string N times.") def _(self): self.assertEqual("AAA", "A" * 3) @test("returns empty string when N is negative.") def _(self): self.assertEqual("", "A" * -1) if __name__ == '__main__': picotest.main() Output example:: $ python -m picotest -h# show help $ python example_test.py # or python -m picotest example_test.py example_test.py * type 'str' * operator '*' - [passed] repeats string N times. - [passed] returns empty string when N is negative. ## total:2, passed:2, failed:0, error:0, skipped:0, todo:0 See http://pypi.python.org/pypi/PicoTest for details. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
PREFIX directory for pip command
Is it possible to specify PREFIX directory for pip command by environment variable? I found that 'pip install --install-option=--prefix=PREFIX' works well, but I don't want to specify '--install-option=--prefix=PREFIX' every time. I prefer to specify it by environment variable such as:: export PIP_INSTALL_DIR=$PWD/local Is it possible? Or any idea? -- regards, makoto -- http://mail.python.org/mailman/listinfo/python-list
Re: PREFIX directory for pip command
On Tue, Nov 15, 2011 at 11:33 PM, Marc Christiansen wrote: > > I'd try > export PIP_INSTALL_OPTION=--prefix=$PWD/local It works very well. Thank you. -- regards, makoto > > using a config file is also possible. See > http://www.pip-installer.org/en/latest/configuration.html > > Ciao > Marc > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest.py 0.11.0 released - a new-style testing library
I released Oktest.py 0.11.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Oktest.py is a new-style testing library for Python. :: from oktest import ok, NG ok (x) > 0 # same as assertTrue(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assertTrue(isinstance(u'foo', unicode)) NG (u'foo').is_a(int) # same as assertTrue(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assertTrue(os.path.isfile('A.txt')) NG ('A.txt').is_dir() # same as assertTrue(not os.path.isdir('A.txt')) See http://packages.python.org/Oktest/ for details. Changes and Enhancements * [change] 'spec()' is now NOT obsoleted. * [change] 'spec()' is now available as function decorator. ex:: class FooTest(unittest.TestCase): def test_method1(self) @spec("1+1 should be 2") def _(): ok (1+1) == 2 @spec("1-1 should be 0") def _(): ok (1-1) == 0 * [enhance] New assertions: not_file(), not_dir() and not_exist(). ex:: ok (".").not_file() # same as NG (".").is_file() ok (__file__).not_dir() # same as NG (__file__).is_dir() ok ("foobar").not_exist() # same as NG ("foobar").exists() * [enhance] New assertion: not_match(). ex:: ok ("SOS").not_match(r"\d+") # same as NG ("SOS").matches(r"\d+") * [enhance] Global provider/releaser functions can take 'self' argument. ex:: def provide_logname(self): self._LOGNAME = os.getenv('LOGNAME') os.environ['LOGNAME'] = "Haruhi" return os.environ['LOGNAME'] def release_logname(self, value): os.environ['LOGNAME'] = self._LOGNAME * [change] Change not to ignore test classes which name starts with '_'. * [change] (internal) Move some utility functions to 'util' module. * [change] (internal) Move '_Context' and '_RunnableContext' classes into 'util' module. * [change] (internal) Move 'Color' class into 'util' module * [change] (internal) Remove 'OUT' variable in 'Reporter' class * [change] (internal) Move 'TARGET_PATTERN' variable to 'config' * [bugfix] Fix to clear ImportError after trying to import unittest2 -- regards, makoto -- http://mail.python.org/mailman/listinfo/python-list
ANN: Tenjin 0.6.1 - a fast and full-featured template engine
Hi all, I have released Tenjin 0.6.1. http://www.kuwata-lab.com/tenjin/ In this release, benchmark script is enhanced to support Genshi, Mako, and Templetor. Tenjin is a very fast and full-featured temlate engine. You can embed Python statements and expressions into your text file. Tenjin converts it into Python program and evaluate it. How fast Tenjin is? It is about: * three times faster than Cheetah and Myghty * nine times faster than Django * sixty times faster than Kid * twice faster than Mako You can see the detail of benchmark at: http://www.kuwata-lab.com/tenjin/ (benchmark script is included in Tenjin distribution.) Tenjin is not only so fast and lightweight but also full-featured. It supports: * layout template * partial template * capturing * preprocessing * and so on... See user's guide and examples at the above page for details. New release of Tenjin will be informed at: http://www.kuwata-lab.com/support/ Release 0.6.1: [Enhancements] * Benchmark script ('benchmark/bench.py') is rewrited. * Benchmark supports Genshi, Mako, and Templetor. * Add examples. [Bugfix] * Typo in User's Guide is fixed. -- makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Question about PyPI and 'easy_install'
Hi, I have a trouble around PyPI and easy_install. I have developed OSS (Tenjin) and registered it to PyPI. http://pypi.python.org/pypi/Tenjin/0.6.1 But I can't install it by 'easy_install' command. $ easy_install Tenjin Searching for Tenjin Reading http://pypi.python.org/simple/Tenjin/ Reading http://www.kuwata-lab.com/tenjin/ No local packages or download links found for Tenjin error: Could not find suitable distribution for Requirement.parse('Tenjin') This error reports that download link is not found, but download url is described in the above web page. Could you help me why the above error happen? Is it required to set registered name (Tenjin) and package name (pyTenjin) into same name? -- makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: most loved template engine on python is?
On 2008-02-25 Tamer Higazi <[EMAIL PROTECTED]> wrote: > Question: > Which is the most loved template engine for python? > I recommend pyTenjin template engine. http://www.kuwata-lab.com/tenjin/ pyTenjin is not famous nor popular, but it is very fast, full- featured, and very easy-to-use. The above web page shows that pyTenjin is about 3 times faster than Cheetah, 9 times faster than Django, and 60 times faster than Kid. It is easy to install pyTenjin because it is only single file. users-gude: http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html examples: http://www.kuwata-lab.com/tenjin/pytenjin-examples.html -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: Question about PyPI and 'easy_install'
On 2008-02-25, Richard Jones <[EMAIL PROTECTED]> wrote: > makoto kuwata wrote: > > Is it required to set registered name (Tenjin) and > > package name (pyTenjin) into same name? > > Yes. > Thank you, Richard. Your answer helps me very much. > How did you upload those files with a different name to that pypi package? I have no magic. I uploaded file via uploader page of PyPI. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: Question about PyPI and 'easy_install'
On 2008-02-26, Vsevolod Balashov <[EMAIL PROTECTED]> wrote: > > I`m think this patch is helpful for you > > ---BEGIN PATCH--- > > --- setup.py.orig 2007-10-23 03:54:18.0 +0400 > +++ setup.py 2008-02-26 14:08:44.66000 +0300 > @@ -6,12 +6,10 @@ > > import sys, re > -if len(sys.argv) > 1 and sys.argv[1] == 'egg_info': > - from ez_setup import use_setuptools > - use_setuptools() > -from distutils.core import setup > +from ez_setup import use_setuptools > +from setuptools import setup > > -name = 'pyTenjin' > +name = 'Tenjin' > version = '0.6.1' > author = 'makoto kuwata' > email = '[EMAIL PROTECTED]' > > ---END PATCH--- Thank you, Vsevolod. Your patch shows that both project name (Tenjin) and package name (pyTenjin) should be the same name. And, I'm afraid that your patch seems to require user to install setuptools. I want Tenjin to be install not only with easy_install but also without setuptools. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] pyTenjin 0.6.2 - a fast and full-featured template engine
I have released pyTenjin 0.6.2. http://www.kuwata-lab.com/tenjin/ This is a tiny bug fix release. pyTenjin is the fastest template engine for Python. Not only very fast, but also full-featured and easy-to-use is pyTenjin. You can embed Python statements and expressions into your text file. Tenjin converts it into Python program and evaluate it. Features: * very fast - x2 faster than Mako - x3 faster than Cheetah and Myghty - x9 faster than Django - x60 faster than Kid * Full-featured - layout template - partial template - capturing - preprocessing - and so on... You can see the detail of benchmark at: http://www.kuwata-lab.com/tenjin/ (benchmark script is included in pyTenjin distribution.) Installation: $ easy_install Tenjin ## or download, extract, and execute 'setup.py' Example: template.pyhtml ${title} ${item} #{item} Example: main.py import tenjin from tenjin.helpers import to_str, escape engine = tenjin.Engine() context = { 'title': 'pyTenjin Example', 'items': ['', 'B&B', '"CCC"'] } output = engine.render('template.pyhtml', context) print output, Example: result $ python main.py pyTenjin Example <AAA> B&B B&B "CCC" "CCC" See user's guide and examples at the above page for details. New release of pyTenjin will be informed at: http://www.kuwata-lab.com/support/ Release 0.6.2: [Changes] * When '-S', '-a retrieve', '-X', or '-a statements' specified, pytenjin command replaces text before expressions into spaces and print it. [Bugfix] * pytenjin command printed "\n\n" instead of "\n" when '-U' specified. Fixed to print "\n". -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest 0.6.0 released - a new-style testing library
Hi all, I released Oktest 0.6.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Oktest is a new-style testing library for Python. :: from oktest import ok ok (x) > 0 # same as assert_(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) not_ok (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) not_ok ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) See http://packages.python.org/Oktest/ for details. NOTICE!! Oktest is a young project and specification may change in the future. New features in this release Oktest supports Tracer class which can be mock or stub of function or method. Example to create fake object:: ## create fake objects from oktest.tracer import Tracer tr = Tracer() foo = tr.fake_obj(m1=100, m2=200) # method name and return-value bar = tr.fake_obj(m3=lambda self, x: x+1) # method name and body ## call fake methods ok (bar.m3(0)) == 1 ok (foo.m2(1,2,3)) == 200# any argument can be passed ok (foo.m1(x=123)) == 100# any argument can be passed ## check results ok (repr(tr[0])) == 'm3(0) #=> 1' ok (repr(tr[1])) == 'm2(1, 2, 3) #=> 200' ok (repr(tr[2])) == 'm1(x=123) #=> 100' There are several ways to check results:: from oktest.tracer import Tracer tr = Tracer() obj = tr.fake_obj(meth=9) ok (obj.meth(1, 2, x=3)) == 9 ## check results ok (repr(tr[0])) == 'meth(1, 2, x=3) #=> 9' ## or ok (tr[0].list()) == [obj, 'meth', (1, 2), {'x': 3}, 9] ## or ok (tr[0])== [obj, 'meth', (1, 2), {'x': 3}, 9] ## or ok (tr[0].receiver).is_(obj) ok (tr[0].name) == 'meth' ok (tr[0].args) == (1, 2) ok (tr[0].kwargs) == {'x': 3} ok (tr[0].ret)== 9 Example to trace method call:: class Foo(object): def m1(self, x): return x + 1 def m2(self, y): return y + 1 obj = Foo() ## trace methods from oktest.tracer import Tracer tr = Tracer() def dummy(original_func, *args, **kwargs): #return original_func(*args, **kwargs) return 100 tr.fake_method(obj, m1=dummy, m2=200) ## call methods ok (obj.m1(1)) == 100 ok (obj.m2(2)) == 200 ## check results ok (tr[0]) == [obj, 'm1', (1,), {}, 100] ok (tr[1]) == [obj, 'm2', (2,), {}, 200] Example to trace function call:: def f(x): return x+1 def g(y): return f(y+1) + 1 ## trace functions from oktest.tracer import Tracer tr = Tracer() f = tr.trace_func(f) g = tr.trace_func(g) ## call functions ok (g(0)) == 3 ## check results ok (tr[0]) == [None, 'g', (0,), {}, 3] ok (tr[1]) == [None, 'f', (1,), {}, 2] Example to fake method call:: class Foo(object): def m1(self, x): return x + 1 def m2(self, y): return y + 1 obj = Foo() ## fake methods from oktest.tracer import Tracer tr = Tracer() def dummy(original_func, *args, **kwargs): #return original_func(*args, **kwargs) return 100 tr.fake_method(obj, m1=dummy, m2=200) ## call method ok (obj.m1(1)) == 100 ok (obj.m2(2)) == 200 ## check results ok (tr[0]) == [obj, 'm1', (1,), {}, 100] ok (tr[1]) == [obj, 'm2', (2,), {}, 200] Example to fake function call:: def f(x): return x*2 ## fake a function def dummy(original_func, x): #return original_func(x) return 'x=%s' % repr(x) from oktest.tracer import Tracer tr = Tracer() f = tr.fake_func(f, dummy) ## call function ok (f(3)) == 'x=3' ## check results ok (tr[0]) == [None, 'f', (3,), {}, 'x=3'] Have a nice weekend! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Oktest 0.7.0 released - a new-style testing library
I released Oktest 0.7.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Oktest is a new-style testing library for Python. :: from oktest import ok ok (x) > 0 # same as assert_(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) not_ok (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) not_ok ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) See http://packages.python.org/Oktest/ for details. NOTICE!! Oktest is a young project and specification may change in the future. Enhancements and Changes * enhanced to allow users to define custom assertion functions. :: import oktest from oktest import ok # @oktest.assertion def startswith(self, arg): boolean = self.target.startswith(arg) if boolean == self.expected: return True self.failed("%r.startswith(%r) : failed." % (self.target, arg)) # ok ("Sasaki").startswith("Sas") * rename 'ok().hasattr()' to 'ok().has_attr()'. (but old name is also available for backward compatibility.) * change 'chdir()' to take a function as 2nd argument. :: def f(): ... do_something ... chdir('build', f) # The above is same as: with chdir('build'): ... do_something ... * add document of 'oktest.helper.dummy_io()'. :: with dummy_io("SOS") as io: assert sys.stdin.read() == "SOS" print("Haruhi") assert io.stdout == "Haruhi\n" assert io.stderr == "" * fix 'oktest.tracer.Call#__repr__()' to change output according to whether '==' is called or not. This is aimed to make output of 'ok(tr[0]) == [...]' to be more readable. * change 'Runner#run()' to skip AssertionError if it is raised by 'assert ' and not 'ok() == ...'. * fix example code for some helper functions. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Benchmarker 3.0.1 released - a small benchmark utility
Hi, I released Benchmarker 3.0.1. http://pypi.python.org/pypi/Benchmarker/ Benchmarker is a small utility to benchmark your code. *NOTICE* This release doesn't have compatibility with release 2.0.0. Download http://pypi.python.org/pypi/Benchmarker/ Installation:: ## if you have installed easy_install: $ sudo easy_install Benchmarker ## or download Benchmarker-3.0.1.tar.gz and install it $ wget http://pypi.python.org/packages/source/B/Benchmarker/Benchmarker-3.0.1.tar.gz $ tar xzf Benchmarker-3.0.1.tar.gz $ cd Benchmarker-3.0.1/ $ sudo python setup.py install Example --- ex0.py:: from benchmarker import Benchmarker, cmdopt cmdopt.parse() s1, s2, s3, s4, s5 = "Haruhi", "Mikuru", "Yuki", "Itsuki", "Kyon" with Benchmarker(width=20, loop=1000*1000) as bm: for _ in bm.empty(): ## empty loop pass for _ in bm('join'): sos = ''.join((s1, s2, s3, s4, s5)) for _ in bm('concat'): sos = s1 + s2 + s3 + s4 + s5 for _ in bm('format'): sos = '%s%s%s%s%s' % (s1, s2, s3, s4, s5) Output example:: $ python ex0.py -h# show help message of command-line optins $ python ex0.py ## benchmarker: release 3.0.1 (for python) ## python platform: darwin [GCC 4.2.1 (Apple Inc. build 5664)] ## python version:2.7.1 ## python executable: /usr/local/python/2.7.1/bin/python ## user sys total real (Empty)0.16000.0.16000.1639 join 0.65000.0.65000.6483 concat 0.57000.0.57000.5711 format 0.76000.0.76000.7568 ## Ranking real concat 0.5711 (100.0%) * join 0.6483 ( 88.1%) ** format 0.7568 ( 75.5%) *** ## Ratio Matrix real[01][02][03] [01] concat0.5711 100.0% 113.5% 132.5% [02] join 0.6483 88.1% 100.0% 116.7% [03] format0.7568 75.5% 85.7% 100.0% Notice that empty loop times (user, sys, total, and real) are subtracted from other benchmark times automatically. For example:: === benchmark labelreal (second) --- join 0.6483 (= 0.8122 - 0.1639) concat 0.5711 (= 0.7350 - 0.1639) format 0.7568 (= 0.9207 - 0.1639) === See http://pypi.python.org/pypi/Benchmarker/ for details. Changes on release 3.0.1 * License is changed again to Public Domain. * Change Task class to pass 1-origin index to yield block when 'for _ in bm()' . * Fix a bug that 'for _ in bm()' raised error when loop count was not specified. * Fix a bug that 'for _ in bm()' raised RuntimeError on Python 3. Changes on release 3.0.0 * Rewrite entirely. * Enhanced to support command-line options. :: import benchmarker benchmarker.cmdopt.parse() You can show all command-line options by ``python file.py -h``. See README file for details. * Benchmarker.repeat() is obsolete. :: ## Old (obsolete) with Benchmarker() as bm: for b in bm.repeat(5, 1): with b('bench1'): ## New for bm in Benchmarker(repeat=5, extra=1): with bm('bench1'): * Changed to specify time (second) format. :: import benchmarker benchmarker.format.label_with = 30 benchmarker.format.time = '%9.4f' * Followings are removed. * Benchmark.stat * Benchmark.compared_matrix() * Benchmark.print_compared_matrix() Have fun! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest 0.8.0 released - a new-style testing library
I released Oktest 0.8.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Oktest is a new-style testing library for Python. :: from oktest import ok, NG ok (x) > 0 # same as assert_(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) NG (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) NG ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) See http://packages.python.org/Oktest/ for details. NOTICE!! Oktest is a young project and specification may change in the future. Enhancements and Changes * add ``NG()`` which is same as not_ok(). * enhanced to proive egg files for Python 3. * enhanced to support assertion method chaining. :: ok ("sos".upper()).is_a(str).matches(r'^[A-Z]+$') == "SOS" * ``ok().matches()`` can take flag parameter which is passed to re.compile(). ok ("\nSOS\n").matches(r'^[A-Z]+$', re.M) ## same as: #ok("\nSOS\n").matches(r.compile(r'^[A-Z]$', re.M)) * enhance helper methods to be available without with-statement. (this is necessary for Python 2.4 which is default version on CentOS.) from oktest.helper import chdir def fn(): ok (os.getcwd()) == "/tmp" chdir("/tmp").run(fn) ## this is same as: #with chdir("/tmp"): # ok (os.getcwd()) == "/tmp" from oktest.dummy import dummy_file def fn(): ok ("A.txt").is_file() ok (open("A.txt").read()) == "SOS" dummy_file("A.txt", "SOS").run(fun) ## this is same as: #with dummy_file("A.txt", "SOS"): # ok (open("A.txt").read()) == "SOS" * ``spec()`` now checks environment variable $SPEC. This is useful to filter test cases. ## test script from oktest import oktest, run class StrTest(object): def test_upper(self): if spec("returns upper case string"): ok ("sos".upper()) == "SOS" if spec("doesn't change non-alphabetics"): ok ("sos123<>".upper()) == "SOS123<>" if __name__ == "__main__": run() ## terminal $ SPEC="returns upper case string" python test1.py * fix ``oktest.run()`` to print correct traceback if ok() is called from nested function. * fix content of README.txt. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Method chaining on decorator got SyntaxError
Hi, I have a question about decorator. I tried the following example and got Syntax Error. class deco(object): def __init__(self, name): self._name = name def foo(self, value): self._foo = value return self def __call__(self, func): func._deco = self return func ## ok @deco('aaa') def f1(): pass ## Syntax Error @deco('aaa').foo('bbb') # SyntaxError: invalid syntax def f2(): pass The above code shows that Python doesn't allow method chain on decorator syntax. Why does this limitation exist? I want to chain methods as a certain DSL, just like: @recipe().product('*.html').ingreds('$(1).rst') def file_html(c): system(c%"rst2html.py $(ingred) > $(product)") If you know the reason of the restriction, let me know it. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: Method chaining on decorator got SyntaxError
Thank you MRAB, On Thu, Feb 17, 2011 at 8:49 AM, MRAB wrote: > You may want to read the discussion at: > > https://groups.google.com/group/python-ideas/browse_thread/thread/1eebf486969c39a1/?hl=en > -- I can't figure out what is the point or conclusion of that discussion. Is there any technical reason? Or Ideological reason? -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: Method chaining on decorator got SyntaxError
On Thu, Feb 17, 2011 at 11:40 AM, MRAB wrote: > On 17/02/2011 01:55, Makoto Kuwata wrote: >> >> Thank you MRAB, >> >> On Thu, Feb 17, 2011 at 8:49 AM, MRAB wrote: >>> >>> You may want to read the discussion at: >>> >>> >>> https://groups.google.com/group/python-ideas/browse_thread/thread/1eebf486969c39a1/?hl=en >>> -- >> >> I can't figure out what is the point or conclusion of that discussion. >> Is there any technical reason? Or Ideological reason? >> > Ideological. > > Keep it simple. > > "Readability, not succinctness, is what's Pythonic." -- Mike Meyer Thank you, MRAB. I'm sad about this restriction because: @recipe.product('*.html').ingreds('$(1).rst') def file_html(c): # do something is enough simple and more readable than: @recipe.product('*.html') @recipe.ingreds('$(1).rst') def file_html(c): # do something But I'll follow the Python's philosophy. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
ANN: pyTenjin 1.0.0 - a high-speed and full-featured template engine
Hello World! * tenjin.Engine now helps M17N of templates. If you pass 'lang' option to Engine, it will generates cache files for each langs from a file. This feature is intened to use with preprocessing in order to reduce catalog expantion cost (such as '${_("Hello")}') ## for lang='en' engine_en = tenjin.Engine(lang='en', preprocess=True) engine_en.render('index.pyhtml') # generates 'index.pyhtml.en.cache' ## for lang='fr' engine_fr = tenjin.Engine(lang='fr', preprocess=True) engine_fr.render('index.pyhtml') # generates 'index.pyhtml.fr.cache' * (Experimental) New html helper 'js_link()'. >>> from tenjin.html import * >>> js_link('click', 'alert("OK")', klass='link') 'click' Changes --- * (IMPORTANT!!) You must close statement block of 'if', 'for', 'with', ... with corresponding '#endif', '#endfor', '#endwith', and so on. Notice that '#end' is available as almighty closer. * (IMPORTANT!!) tenjin.GaeMemcacheCacheStorage is removed (this is already announced in the previous release). Please use tenjin.gae.GaeMemcacheStorage instead. * 'tenjin.helpers.html' module is renamed to 'tenjin.html', but old module name is still available for backward compatibility. * escape_html() (and escape()) now escapes "'" into "'". * new_cycle() is moved from tenjin.helpers.html module to tenjin.helpers module because it is not only for HTML. * In GAE environment, Tenjin uses '1.1' as dummy value of CURRENT_VERSION_ID when it is not provided. This prevents error when using GAE and tenjin on test environment. * Python 2.3 is now unsupported. (Python 2.4 is still supported because CentOS uses Python 2.4). * (internal) Tenjin.escape_expr_and_escapeflag() is changed to Tenjin.escape_expr_and_flags(). * (internal) Tenjin.add_expr() is changed to take 'flags' argument. * (internal) 'tenjin.__release__' is renamed to 'tenjin.__version__'. Bugfixes * Cache file saving was failed on Windows because existing file should be removed before renaming file. (patched by elishowk, thank you!) Thank you. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
ANN: Oktest-0.2.2 - a new-style testing library
Hi, I released Oktest 0.2.2. http://packages.python.org/Oktest/ http://pypi.python.org/pypi/Oktest/ Overview Oktest is a new-style testing library for Python. :: from oktest import ok ok (x) > 0 # same as assert_(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) not_ok (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) not_ok ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) You can use ok() instead of 'assertXxx()' in unittest. Oktest requires Python 2.3 or later. Oktest is ready for Python 3. NOTICE!! Oktest is a young project and specification may change in the future. See http://packages.python.org/Oktest/ for details. Changes --- * Enhanced to set 'f.exception' after 'ok (f).raises(Exception)' to get raised exception object. For example:: def f(): int('foobar') ok (f).raises(ValueError) ok (f.exception.message) == "invalid literal for int() with base 10: 'foobar'" * Changed to flush output after '.'/'f'/'E' printed * Change to get exception message by 'str(ex)' instead of 'ex.message' Have fun! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: Wanted: Python solution for ordering dependencies
On Sun, Apr 25, 2010 at 5:53 AM, Jonathan Fine wrote: > I'm hoping to avoid reinventing a wheel (or other rolling device). I've got > a number of dependencies and, if possible, I want to order them so that each > item has its dependencies met before it is processed. > > I think I could get what I want by writing and running a suitable makefile, > but that seems to be such a kludge. > > Does anyone know of an easily available Python solution? If you are looking for alternatives of Make or Ant, try pyKook. pyKook is a pure-Python tool similar to Make, Ant, or Rake. http://www.kuwata-lab.com/kook/pykook-users-guide.html http://pypi.python.org/pypi/Kook/ example (Kookbook.py): CC = prop('CC', 'gcc') CFLAGS = prop('CFLAGS', '-g -O2') @recipe @ingreds('hello.o') def task_all(c): """compile all *.o"""# recipe description pass @recipe @product("*.o") @ingreds("$(1).c", if_exists("$(1).h")) def file_o(c): """compile '*.c' and '*.h' into '*.o'""" # recipe description system(c%"$(CC) $(CFLAGS) -c $(ingred)") example of command-line: ~/tmp> kk all ### ** hello.o (recipe=file_o) $ gcc -g -O2 -c hello.c ### * all (recipe=task_all) -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Benchmarker 1.1.0 released - a samll benchmark utility
I released Benchmarker 1.1.0. http://pypi.python.org/pypi/Benchmarker/ Benchmarker is a small utility to benchmark your code. Example === ex.py:: def fib(n): return n <= 2 and 1 or fib(n-1) + fib(n-2) from benchmarker import Benchmarker bm = Benchmarker(30) # or Benchmarker(width=30, out=sys.stderr, header=True) ## Python 2.5 or later with bm('fib(n) (n=33)'): fib(33) with bm('fib(n) (n=34)'): fib(34) with bm('fib(n) (n=35)'): fib(35) ## Python 2.4 bm('fib(n) (n=33)').run(fib, 33) # or .run(lambda: fib(33)) bm('fib(n) (n=34)').run(fib, 34) # or .run(lambda: fib(34)) bm('fib(n) (n=35)').run(fib, 35) # or .run(lambda: fib(35)) ## print compared matrix bm.print_compared_matrix(sort=False, transpose=False) Output:: $ python ex.py utime stime total real fib(n) (n=33) 1.890 0.000 1.890 1.900 fib(n) (n=34) 3.030 0.010 3.040 3.058 fib(n) (n=35) 4.930 0.010 4.940 4.963 --- real [01] [02] [03] [01] fib(n) (n=33) 1.900s- 60.9% 161.2% [02] fib(n) (n=34) 3.058s-37.9% - 62.3% [03] fib(n) (n=35) 4.963s-61.7% -38.4% - Changes in release 1.1.0 * Enhance Benchmarker.run() to take function args. :: bm = Benchmarker() bm('fib(34)').run(fib, 34) # same as .run(lambda: fib(34)) * (experimental) Enhance Benchmarker.run() to use function name as title if title is not specified. :: def fib34(): fib(34) bm = Benchmarker() bm.run(fib34) # same as bm('fib34').run(fib34) * Enhanced to support compared matrix of benchmark results. :: bm = Benchmarker(9) bm('fib(30)').run(fib, 30) bm('fib(31)').run(fib, 31) bm('fib(32)').run(fib, 32) bm.print_compared_matrix(sort=False, transpose=False) ## output example # utime stime total real #fib(30) 0.440 0.000 0.440 0.449 #fib(31) 0.720 0.000 0.720 0.722 #fib(32) 1.180 0.000 1.180 1.197 #-- #real [01] [02] [03] #[01] fib(30) 0.4487s- 60.9% 166.7% #[02] fib(31) 0.7222s-37.9% - 65.7% #[03] fib(32) 1.1967s-62.5% -39.6% - * Benchmark results are stored into Benchmarker.results as a list of tuples. :: bm = Benchmarker() bm('fib(34)').run(fib, 34) bm('fib(35)').run(fib, 35) for result in bm.results: print result ## output example: #('fib(34)', 4.37, 0.02, 4.39, 4.9449) #('fib(35)', 7.15, 0.05, 7.20, 8.0643) * Time format is changed from '%10.4f' to '%9.3f' * Changed to run full-GC for each benchmarks -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
Re: [ANN] Benchmarker 1.1.0 released - a samll benchmark utility
Terry, Thank you for trying Benchmarker. On Sun, Jun 27, 2010 at 7:15 AM, Terry Reedy wrote: > On 6/26/2010 1:09 PM, Makoto Kuwata wrote: >> >> I released Benchmarker 1.1.0. >> http://pypi.python.org/pypi/Benchmarker/ >> >> Benchmarker is a small utility to benchmark your code. >> >> >> Example >> === >> >> ex.py:: >> >> def fib(n): >> return n<= 2 and 1 or fib(n-1) + fib(n-2) >> from benchmarker import Benchmarker >> bm = Benchmarker(30) # or Benchmarker(width=30, out=sys.stderr, >> header=True) >> ## Python 2.5 or later > > Is that 2.5 to 2.7 or 2.5 to 3.1 and later? > > 2.5 to 3.1 and later, because with-statement is available 2.5, 2.6, 2.7, and 3.x. Benchmarker supports two styles to invoke. One is using with-statement and this is available 2.5, 2.6, 2.7, and 3.x. bm = Benchmarker() with bm('fib(30)'): fib(30) The other is to call run() method and this is available every version of Python. bm = Benchmarker() bm('fib(30)').run(fib, 30) Thank you for your attention. -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
[ANN] Oktest 0.4.0 released - a new-style testing library
I released Oktest 0.4.0. http://pypi.python.org/pypi/Oktest/ http://packages.python.org/Oktest/ Overview Oktest is a new-style testing library for Python. :: from oktest import ok ok (x) > 0 # same as assert_(x > 0) ok (s) == 'foo'# same as assertEqual(s, 'foo') ok (s) != 'foo'# same as assertNotEqual(s, 'foo') ok (f).raises(ValueError) # same as assertRaises(ValueError, f) ok (u'foo').is_a(unicode) # same as assert_(isinstance(u'foo', unicode)) not_ok (u'foo').is_a(int) # same as assert_(not isinstance(u'foo', int)) ok ('A.txt').is_file() # same as assert_(os.path.isfile('A.txt')) not_ok ('A.txt').is_dir() # same as assert_(not os.path.isdir('A.txt')) You can use ok() instead of 'assertXxx()' in unittest. Oktest requires Python 2.3 or later. Oktest is ready for Python 3. NOTICE!! Oktest is a young project and specification may change in the future. Download http://pypi.python.org/pypi/Oktest/ Installation:: ## if you have installed easy_install: $ sudo easy_install Oktest ## or download Oktest-$Release$.tar.gz and install it $ wget http://pypi.python.org/packages/source/O/Oktest/Oktest-$Release$.tar.gz $ tar xzf Oktest-$Release$.tar.gz $ cd Oktest-$Release$/ $ sudo python setup.py install Example --- test_example.py:: from oktest import ok, run import sys, os ## no need to extend TestCase class class Example1Test(object): @classmethod def before_all(self): # invoked only once before all tests os.mkdir('tmp.d') @classmethod def after_all(self):# invoked only once after all tests done import shutil shutil.rmtree('tmp.d') def before(self): # invoked before each test self.val = ['aaa', 'bbb', 'ccc'] def after(self):# invoked after each test pass def test_valtype(self): ok (type(self.val)) == list def test_length(self): ok (len(self.val)) == 3 ## 'ok()' is available with unittest.TestCase import unittest class Example2Test(unittest.TestCase): def setUp(self): self.val = ['aaa', 'bbb', 'ccc'] def test_valtype(self): ok (type(self.val)) == list def test_length(self): ok (len(self.val)) == 3 ## invoke tests if __name__ == '__main__': from oktest import run run(Example1Test, Example2Test) ## or #run('.*Test$') # specify class names by regular expression Changes in release 0.4.0 * enhanced to support 'ok (x).in_delta(y, d)' which raises assertion exception unless y-d < x < y+d. * change test script to support Python 2.7 and 3.x. * fixed a few bugs. Have fun! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
ANN: pyTenjin 0.9.0 - very fast and full-featured template engine
I released pyTenjin 0.9.0 http://www.kuwata-lab.com/tenjin/ http://pypi.python.org/pypi/Tenjin/ This release contains a lot of enhancements and changes. Also you should read planned changes in the next release (1.0.0). See http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#planned-changes for details. Overview pyTenjin is very fast and full-featured template engine for Python. * Very fast (about 10 times faster than Django template engine) * Easy to learn (no need to learn template-original language) * Full-featured (nestable layout template, partial template, preprocessing, ...) * Google App Engine supported Documents - * User's Guide http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html * Examples http://www.kuwata-lab.com/tenjin/pytenjin-examples.html * CHANGES http://www.kuwata-lab.com/tenjin/pytenjin-CHANGES.txt Enhancements from 0.8.1 --- * Performance improved (about 5%). * (IMPORTANT!!) Fragment cache supported. See http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#fragment-cache for details. * (IMPORTANT!!) include() now takes keyword arguments as local variables. ex. * Add new module 'tenjin.gae'. * Add 'input' argument to tenjin.Template() to create template object without file. ex. input = "Hello ${name}" t = tenjin.Template(None, input=input) html = t.render({'name': 'World'}) * Add tenjin.Engine.add_template() to add template object explicitly. * User's guide (doc/users-guide.html) is rewrited entirely. * Add benchmark for Jinja2. Changes from 0.8.1 -- * (IMPORTANT!!) It is strongly recommended to close 'if', 'for', 'while', ... by corresponding '#endif', '#endfor', '#endwhile', and so on. See http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#planned-changes for details. * (IMPORTANT!!) Google App Engine support is changed. All you have to do is to call tenjin.gae.init() at first. See http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#google-appengine for details. * (IMPORTANT!!) tenjin.Engine is changed to share a cache storage between engines by default. This improves performance of Tenjin but your test scripts may get errors. If you get errors in your test scripts, clear cache storage for each test. def setUp(self): tenjin.Engine.cache.clear() If you prefer previous behaviour, set tenjin.Engine.cache to None. ## create new MarshalCacheStorage object for each engine tenjin.Engine.cache = None * Now you can set default template class to tenjin.Engine.templateclass. ex. tenjin.Engine.templateclass = MyTemplate * 'cache' argument of tenjin.Engine() is changed. [old behaviour] if 'cache' is None, cache template object into memory. [new behaviour] if 'cache' is None, use default cache storage. * Default preamble is changed from "print ''.join(_buf)" to "print(''.join(_buf))". * 'doc/faq.html' is integrated into 'doc/users-guide.html'. * All test scripts are changed to import oktest instead of unittest. Bug fixes - * Fixed to set correct file path of template object which is loaded from cache. * Fixed a bug that 'pytenjin -sbN' didn't trim line number on the last line Have fun! -- regards, makoto kuwata -- http://mail.python.org/mailman/listinfo/python-list
WANT: bad code in python (for refactoring example)
Hi, Is there any *just right* python code to refactor? In other words, I'm finding bad code example in python. (background) I'm teaching Python to some novice programmer, and want to show refactoring example to them. (required) * not good code * not too large (for novice programmer) * not too complex (for novice programmer) * released under open source license If you know good material in github or bitbucket to refactor, let me know it. -- regards, kwatch -- https://mail.python.org/mailman/listinfo/python-list
Re: WANT: bad code in python (for refactoring example)
Thanks Irmen and Steven, I'm sorry that my explanation is not enough. I'm looking for bad python code, not refactoring examples. I can do (and want to do) refactor bad code by myself. Is there any bad python code (or project) with proper size? # I found a lot of bad PHP code in github, but didn't find bad Python code. -- regards, makoto kuwata On Wed, Feb 15, 2017 at 3:28 PM, Steven D'Aprano wrote: > On Wed, 15 Feb 2017 07:44:03 +0900, Makoto Kuwata wrote: > > > Hi, > > > > Is there any *just right* python code to refactor? > > In other words, I'm finding bad code example in python. > > > Try looking at the ActiveState website for recipes in Python. Especially > look at the ones with negative ratings, but even positively rated recipes > are often nonsense. > > E.g. http://code.activestate.com/recipes/580750 > > does nothing more that define > > echo = sys.stdout.write > > Why not use sys.stdout.write directly? Or print? If I saw somebody using > this recipe in production code, in the way shown, I'd refactor it to just > use print. There's no advantage to re-inventing the wheel this way. > > > > -- > Steve > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: WANT: bad code in python (for refactoring example)
Thanks Erik, On Thu, Feb 16, 2017 at 6:53 AM, Erik wrote: > (which is what I think you mean by "proper size") > As I explained at my first post, I'm teaching Python to novice programmers. Therefore refactoring example code should be in the size what they can understand. It is hard for them to read and understand over than thousand lines of code. Almost of all projects have code over than thousand lines of code, but it is possible to quote a part of them for refactoring example, I think. > > (Python code examples of what you think is "bad" vs "good" would be > useful). > You are right. Bad code Example: # https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming from random import random def move_cars(car_positions): return map(lambda x: x + 1 if random() > 0.3 else x, car_positions) def output_car(car_position): return '-' * car_position def run_step_of_race(state): return {'time': state['time'] - 1, 'car_positions': move_cars(state['car_positions'])} def draw(state): print '' print '\n'.join(map(output_car, state['car_positions'])) def race(state): draw(state) if state['time']: race(run_step_of_race(state)) race({'time': 5, 'car_positions': [1, 1, 1]}) Refactoring example: from random import random class Car(object): def __init__(self): self.position = 1 def move(self): if random() > 0.3: self.position += 1 return self.position class Race(object): def __init__(self, n_cars=3): self._cars = [ Car() for _ in range(n_cars) ] def round(self): for car in self._cars: car.move() def report(self): print("") for car in self._cars: print('-' * car.position) def run(self, n_rounds=5): self.report() for _ in range(n_rounds): self.round() self.report() if __name__ == '__main__': Race(3).run(5) -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list
Re: WANT: bad code in python (for refactoring example)
On Thu, Feb 16, 2017 at 6:34 AM, Dotan Cohen wrote: > I think that we can help each other! This is my own code, back when I > was writing Python like PHP: > https://github.com/dotancohen/burton Year, this is a good example code for me to do refactoring. I created a pull request. This will be shown to my students. https://github.com/dotancohen/burton/pull/20/files I hope you favor this PR. -- regards, makoto kuwata -- https://mail.python.org/mailman/listinfo/python-list