Hello community, here is the log from the commit of package python-pecan for openSUSE:Factory checked in at 2014-01-13 13:49:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pecan (Old) and /work/SRC/openSUSE:Factory/.python-pecan.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pecan" Changes: -------- --- /work/SRC/openSUSE:Factory/python-pecan/python-pecan.changes 2013-12-06 09:44:04.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python-pecan.new/python-pecan.changes 2014-01-13 13:49:59.000000000 +0100 @@ -1,0 +2,20 @@ +Fri Jan 10 17:21:45 UTC 2014 - [email protected] + +- update to 0.4.4: + * Removed memoization of certain controller attributes, which can lead to + a memory leak in dynamic controller lookups. + * Fixed several bugs for RestController. + * Fixed a bug in security handling for generic controllers. + * Resolved a bug in `_default` handlers used in `RestController`. + * Persist `pecan.request.context` across internal redirects. +- reenable make check + +------------------------------------------------------------------- +Tue Dec 10 10:00:03 UTC 2013 - [email protected] + +- fix requires after the version update to 0.4.2, it was even + documented in the .changes file: + * Replaced the ``simplegeneric`` dependency with the new + ``functools.singledispatch`` function in preparation for Python 3.4 support. + +------------------------------------------------------------------- Old: ---- pecan-0.4.2.tar.gz New: ---- pecan-0.4.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pecan.spec ++++++ --- /var/tmp/diff_new_pack.c4aY2D/_old 2014-01-13 13:50:00.000000000 +0100 +++ /var/tmp/diff_new_pack.c4aY2D/_new 2014-01-13 13:50:00.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pecan # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python-pecan -Version: 0.4.2 +Version: 0.4.4 Release: 0 Summary: A WSGI object-dispatching web framework, designed to be lean and fast License: BSD-3-Clause @@ -27,23 +27,27 @@ BuildRequires: python-devel BuildRequires: python-setuptools # Test requirements: -#BuildRequires: python-Genshi -#BuildRequires: python-Jinja2 -#BuildRequires: python-Mako >= 0.4.0 -#BuildRequires: python-WebOb >= 1.2dev -#BuildRequires: python-WebTest >= 1.3.1 -#BuildRequires: python-gunicorn -#BuildRequires: python-simplegeneric >= 0.8 -#BuildRequires: python-virtualenv +%if 0%{?suse_version} >= 1230 +BuildRequires: python-Genshi +BuildRequires: python-Jinja2 +BuildRequires: python-Kajiki +BuildRequires: python-Mako >= 0.4.0 +BuildRequires: python-SQLAlchemy +BuildRequires: python-WebTest >= 1.3.1 +BuildRequires: python-gunicorn +BuildRequires: python-mock +BuildRequires: python-singledispatch +BuildRequires: python-virtualenv +%endif BuildRequires: python-six %if 0%{?suse_version} && 0%{?suse_version} <= 1110 Requires: python-logutils %endif -Requires: python-Mako >= 0.6.2 -Requires: python-MarkupSafe >= 0.15 -Requires: python-WebOb >= 1.2b3 -Requires: python-WebTest >= 1.3.3 -Requires: python-simplegeneric >= 0.8.1 +Requires: python-Mako >= 0.4.0 +Requires: python-WebOb >= 1.2dev +Requires: python-WebTest >= 1.3.1 +Requires: python-singledispatch +Requires: python-six Suggests: python-Jinja2 Suggests: python-Genshi Suggests: python-gunicorn @@ -68,8 +72,10 @@ %install python setup.py install --prefix=%{_prefix} --root=%{buildroot} -#%%check -#python setup.py test +%if 0%{?suse_version} >= 1230 +%check +python setup.py test +%endif %files %defattr(-,root,root,-) ++++++ pecan-0.4.2.tar.gz -> pecan-0.4.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/.coveragerc new/pecan-0.4.4/.coveragerc --- old/pecan-0.4.2/.coveragerc 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/.coveragerc 2014-01-08 16:14:17.000000000 +0100 @@ -1,3 +1,2 @@ [run] source=pecan -omit=pecan/compat/dictconfig.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/PKG-INFO new/pecan-0.4.4/PKG-INFO --- old/pecan-0.4.2/PKG-INFO 2013-09-27 23:33:55.000000000 +0200 +++ new/pecan-0.4.4/PKG-INFO 2014-01-08 16:14:27.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pecan -Version: 0.4.2 +Version: 0.4.4 Summary: A WSGI object-dispatching web framework, designed to be lean and fast, with few dependancies. Home-page: http://github.com/stackforge/pecan Author: Jonathan LaCour diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/docs/source/changes.rst new/pecan-0.4.4/docs/source/changes.rst --- old/pecan-0.4.2/docs/source/changes.rst 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/docs/source/changes.rst 2014-01-08 16:14:17.000000000 +0100 @@ -1,3 +1,15 @@ +0.4.4 +===== +* Removed memoization of certain controller attributes, which can lead to + a memory leak in dynamic controller lookups. + +0.4.3 +===== +* Fixed several bugs for RestController. +* Fixed a bug in security handling for generic controllers. +* Resolved a bug in `_default` handlers used in `RestController`. +* Persist `pecan.request.context` across internal redirects. + 0.4.2 ===== * Remove a routing optimization that breaks the WSME pecan plugin. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/core.py new/pecan-0.4.4/pecan/core.py --- old/pecan-0.4.2/pecan/core.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/core.py 2014-01-08 16:14:17.000000000 +0100 @@ -14,6 +14,7 @@ from webob import Request, Response, exc, acceptparse from .compat import urlparse, unquote_plus, izip +from .secure import handle_security from .templating import RendererFactory from .routing import lookup_controller, NonCanonicalPath from .util import _cfg, encode_if_needed @@ -119,6 +120,7 @@ if internal: if code is not None: raise ValueError('Cannot specify a code for internal redirects') + request.environ['pecan.recursive.context'] = request.context raise ForwardRequestException(location) if code is None: code = 302 @@ -428,6 +430,7 @@ im_self = six.get_method_self(controller) handlers = cfg['generic_handlers'] controller = handlers.get(req.method, handlers['DEFAULT']) + handle_security(controller, im_self) cfg = _cfg(controller) # add the controller to the state so that hooks can use it @@ -561,7 +564,7 @@ # handle the request try: # add context and environment to the request - req.context = {} + req.context = environ.get('pecan.recursive.context', {}) req.pecan = dict(content_type=None) self.handle_request(req, resp) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/rest.py new/pecan-0.4.4/pecan/rest.py --- old/pecan-0.4.2/pecan/rest.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/rest.py 2014-01-08 16:14:17.000000000 +0100 @@ -54,7 +54,11 @@ return result # handle the request - handler = getattr(self, '_handle_%s' % method, self._handle_custom) + handler = getattr( + self, + '_handle_%s' % method, + self._handle_unknown_method + ) try: result = handler(method, args) @@ -140,9 +144,9 @@ remainder[fixed_args + 1:] ) - def _handle_custom(self, method, remainder): + def _handle_unknown_method(self, method, remainder): ''' - Routes ``_custom`` actions to the appropriate controller. + Routes undefined actions (like RESET) to the appropriate controller. ''' # try finding a post_{custom} or {custom} method first controller = self._find_controller('post_%s' % method, method) @@ -180,14 +184,10 @@ if controller: return controller, remainder[:-1] - # check for custom GET requests - if method.upper() in self._custom_actions.get(method_name, []): - controller = self._find_controller( - 'get_%s' % method_name, - method_name - ) - if controller: - return controller, remainder[:-1] + match = self._handle_custom_action(method, remainder) + if match: + return match + controller = getattr(self, remainder[0], None) if controller and not ismethod(controller): return lookup_controller(controller, remainder[1:]) @@ -204,6 +204,10 @@ Routes ``DELETE`` actions to the appropriate controller. ''' if remainder: + match = self._handle_custom_action(method, remainder) + if match: + return match + controller = getattr(self, remainder[0], None) if controller and not ismethod(controller): return lookup_controller(controller, remainder[1:]) @@ -230,14 +234,10 @@ ''' # check for custom POST/PUT requests if remainder: - method_name = remainder[-1] - if method.upper() in self._custom_actions.get(method_name, []): - controller = self._find_controller( - '%s_%s' % (method, method_name), - method_name - ) - if controller: - return controller, remainder[:-1] + match = self._handle_custom_action(method, remainder) + if match: + return match + controller = getattr(self, remainder[0], None) if controller and not ismethod(controller): return lookup_controller(controller, remainder[1:]) @@ -252,6 +252,25 @@ def _handle_put(self, method, remainder): return self._handle_post(method, remainder) + def _handle_custom_action(self, method, remainder): + remainder = [r for r in remainder if r] + if remainder: + if method in ('put', 'delete'): + # For PUT and DELETE, additional arguments are supplied, e.g., + # DELETE /foo/XYZ + method_name = remainder[0] + remainder = remainder[1:] + else: + method_name = remainder[-1] + remainder = remainder[:-1] + if method.upper() in self._custom_actions.get(method_name, []): + controller = self._find_controller( + '%s_%s' % (method, method_name), + method_name + ) + if controller: + return controller, remainder + def _set_routing_args(self, args): ''' Sets default routing arguments. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/routing.py new/pecan-0.4.4/pecan/routing.py --- old/pecan-0.4.2/pecan/routing.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/routing.py 2014-01-08 16:14:17.000000000 +0100 @@ -36,7 +36,7 @@ obj, remainder = find_object(obj, remainder, notfound_handlers) handle_security(obj) return obj, remainder - except PecanNotFound: + except (exc.HTTPNotFound, PecanNotFound): while notfound_handlers: name, obj, remainder = notfound_handlers.pop() if name == '_default': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/secure.py new/pecan-0.4.4/pecan/secure.py --- old/pecan-0.4.2/pecan/secure.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/secure.py 2014-01-08 16:14:17.000000000 +0100 @@ -119,7 +119,6 @@ To secure a class, invoke with two arguments: secure(<obj instance>, <check_permissions_method>) """ - if _allowed_check_permissions_types(func_or_obj): return _secure_method(func_or_obj) else: @@ -199,14 +198,14 @@ # methods to evaluate security during routing -def handle_security(controller): +def handle_security(controller, im_self=None): """ Checks the security of a controller. """ if controller._pecan.get('secured', False): check_permissions = controller._pecan['check_permissions'] if isinstance(check_permissions, six.string_types): check_permissions = getattr( - six.get_method_self(controller), + im_self or six.get_method_self(controller), check_permissions ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/tests/config_fixtures/bad/syntaxerror.py new/pecan-0.4.4/pecan/tests/config_fixtures/bad/syntaxerror.py --- old/pecan-0.4.2/pecan/tests/config_fixtures/bad/syntaxerror.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/tests/config_fixtures/bad/syntaxerror.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -if false -var = 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/tests/test_base.py new/pecan-0.4.4/pecan/tests/test_base.py --- old/pecan-0.4.2/pecan/tests/test_base.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/tests/test_base.py 2014-01-08 16:14:17.000000000 +0100 @@ -1,5 +1,6 @@ import sys import os +import json import warnings if sys.version_info < (2, 7): import unittest2 as unittest # pragma: nocover @@ -873,6 +874,39 @@ assert res.request.environ['HTTP_X_FORWARDED_PROTO'] == 'https' +class TestInternalRedirectContext(PecanTestCase): + + @property + def app_(self): + class RootController(object): + + @expose() + def redirect_with_context(self): + request.context['foo'] = 'bar' + redirect('/testing') + + @expose() + def internal_with_context(self): + request.context['foo'] = 'bar' + redirect('/testing', internal=True) + + @expose('json') + def testing(self): + return request.context + + return TestApp(make_app(RootController(), debug=False)) + + def test_internal_with_request_context(self): + r = self.app_.get('/internal_with_context') + assert r.status_int == 200 + assert json.loads(r.body.decode()) == {'foo': 'bar'} + + def test_context_does_not_bleed(self): + r = self.app_.get('/redirect_with_context').follow() + assert r.status_int == 200 + assert json.loads(r.body.decode()) == {} + + class TestStreamedResponse(PecanTestCase): def test_streaming_response(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/tests/test_conf.py new/pecan-0.4.4/pecan/tests/test_conf.py --- old/pecan-0.4.2/pecan/tests/test_conf.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/tests/test_conf.py 2014-01-08 16:14:17.000000000 +0100 @@ -1,7 +1,9 @@ import os import sys +import tempfile from pecan.tests import PecanTestCase +from six import b as b_ __here__ = os.path.dirname(__file__) @@ -131,14 +133,16 @@ def test_config_with_syntax_error(self): from pecan import configuration - path = ('bad', 'syntaxerror.py') - configuration.Config({}) - - self.assertRaises( - SyntaxError, - configuration.conf_from_file, - os.path.join(__here__, 'config_fixtures', *path) - ) + with tempfile.NamedTemporaryFile('wb') as f: + f.write(b_('\n'.join(['if false', 'var = 3']))) + f.flush() + configuration.Config({}) + + self.assertRaises( + SyntaxError, + configuration.conf_from_file, + f.name + ) def test_config_with_bad_import(self): from pecan import configuration diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/tests/test_rest.py new/pecan-0.4.4/pecan/tests/test_rest.py --- old/pecan-0.4.2/pecan/tests/test_rest.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/tests/test_rest.py 2014-01-08 16:14:17.000000000 +0100 @@ -670,6 +670,67 @@ r = app.request('/things', method='RESET', status=404) assert r.status_int == 404 + def test_custom_with_trailing_slash(self): + + class CustomController(RestController): + + _custom_actions = { + 'detail': ['GET'], + 'create': ['POST'], + 'update': ['PUT'], + 'remove': ['DELETE'], + } + + @expose() + def detail(self): + return 'DETAIL' + + @expose() + def create(self): + return 'CREATE' + + @expose() + def update(self, id): + return id + + @expose() + def remove(self, id): + return id + + app = TestApp(make_app(CustomController())) + + r = app.get('/detail') + assert r.status_int == 200 + assert r.body == b_('DETAIL') + + r = app.get('/detail/') + assert r.status_int == 200 + assert r.body == b_('DETAIL') + + r = app.post('/create') + assert r.status_int == 200 + assert r.body == b_('CREATE') + + r = app.post('/create/') + assert r.status_int == 200 + assert r.body == b_('CREATE') + + r = app.put('/update/123') + assert r.status_int == 200 + assert r.body == b_('123') + + r = app.put('/update/123/') + assert r.status_int == 200 + assert r.body == b_('123') + + r = app.delete('/remove/456') + assert r.status_int == 200 + assert r.body == b_('456') + + r = app.delete('/remove/456/') + assert r.status_int == 200 + assert r.body == b_('456') + def test_custom_delete(self): class OthersController(object): @@ -1057,6 +1118,23 @@ assert r.status_int == 200 assert r.body == b_('POST-2') + def test_nested_rest_with_default(self): + + class FooController(RestController): + + @expose() + def _default(self, *remainder): + return "DEFAULT %s" % remainder + + class RootController(RestController): + foo = FooController() + + app = TestApp(make_app(RootController())) + + r = app.get('/foo/missing') + assert r.status_int == 200 + assert r.body == b_("DEFAULT missing") + def test_dynamic_rest_lookup(self): class BarController(RestController): @expose() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/tests/test_secure.py new/pecan-0.4.4/pecan/tests/test_secure.py --- old/pecan-0.4.2/pecan/tests/test_secure.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/tests/test_secure.py 2014-01-08 16:14:17.000000000 +0100 @@ -174,6 +174,134 @@ assert response.status_int == 200 assert response.body == b_('Hello from sub!') + def test_secured_generic_controller(self): + authorized = False + + class RootController(object): + + @classmethod + def check_permissions(cls): + return authorized + + @expose(generic=True) + def index(self): + return 'Index' + + @secure('check_permissions') + @index.when(method='POST') + def index_post(self): + return 'I should not be allowed' + + @secure('check_permissions') + @expose(generic=True) + def secret(self): + return 'I should not be allowed' + + app = TestApp(make_app( + RootController(), + debug=True, + static_root='tests/static' + )) + response = app.get('/') + assert response.status_int == 200 + response = app.post('/', expect_errors=True) + assert response.status_int == 401 + response = app.get('/secret/', expect_errors=True) + assert response.status_int == 401 + + def test_secured_generic_controller_lambda(self): + authorized = False + + class RootController(object): + + @expose(generic=True) + def index(self): + return 'Index' + + @secure(lambda: authorized) + @index.when(method='POST') + def index_post(self): + return 'I should not be allowed' + + @secure(lambda: authorized) + @expose(generic=True) + def secret(self): + return 'I should not be allowed' + + app = TestApp(make_app( + RootController(), + debug=True, + static_root='tests/static' + )) + response = app.get('/') + assert response.status_int == 200 + response = app.post('/', expect_errors=True) + assert response.status_int == 401 + response = app.get('/secret/', expect_errors=True) + assert response.status_int == 401 + + def test_secured_generic_controller_secure_attribute(self): + authorized = False + + class SecureController(object): + + @expose(generic=True) + def index(self): + return 'I should not be allowed' + + @index.when(method='POST') + def index_post(self): + return 'I should not be allowed' + + @expose(generic=True) + def secret(self): + return 'I should not be allowed' + + class RootController(object): + sub = secure(SecureController(), lambda: authorized) + + app = TestApp(make_app( + RootController(), + debug=True, + static_root='tests/static' + )) + response = app.get('/sub/', expect_errors=True) + assert response.status_int == 401 + response = app.post('/sub/', expect_errors=True) + assert response.status_int == 401 + response = app.get('/sub/secret/', expect_errors=True) + assert response.status_int == 401 + + def test_secured_generic_controller_secure_attribute_with_unlocked(self): + + class RootController(SecureController): + + @unlocked + @expose(generic=True) + def index(self): + return 'Unlocked!' + + @unlocked + @index.when(method='POST') + def index_post(self): + return 'Unlocked!' + + @expose(generic=True) + def secret(self): + return 'I should not be allowed' + + app = TestApp(make_app( + RootController(), + debug=True, + static_root='tests/static' + )) + response = app.get('/') + assert response.status_int == 200 + response = app.post('/') + assert response.status_int == 200 + response = app.get('/secret/', expect_errors=True) + assert response.status_int == 401 + def test_state_attribute(self): from pecan.secure import Any, Protected assert repr(Any) == '<SecureState Any>' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan/util.py new/pecan-0.4.4/pecan/util.py --- old/pecan-0.4.2/pecan/util.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/pecan/util.py 2014-01-08 16:14:17.000000000 +0100 @@ -1,21 +1,10 @@ import sys -def memodict(f): - """ Memoization decorator for a function taking a single argument """ - class memodict(dict): - def __missing__(self, key): - ret = self[key] = f(key) - return ret - return memodict().__getitem__ - - -@memodict def iscontroller(obj): return getattr(obj, 'exposed', False) -@memodict def _cfg(f): if not hasattr(f, '_pecan'): f._pecan = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan.egg-info/PKG-INFO new/pecan-0.4.4/pecan.egg-info/PKG-INFO --- old/pecan-0.4.2/pecan.egg-info/PKG-INFO 2013-09-27 23:33:55.000000000 +0200 +++ new/pecan-0.4.4/pecan.egg-info/PKG-INFO 2014-01-08 16:14:27.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pecan -Version: 0.4.2 +Version: 0.4.4 Summary: A WSGI object-dispatching web framework, designed to be lean and fast, with few dependancies. Home-page: http://github.com/stackforge/pecan Author: Jonathan LaCour diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/pecan.egg-info/SOURCES.txt new/pecan-0.4.4/pecan.egg-info/SOURCES.txt --- old/pecan-0.4.2/pecan.egg-info/SOURCES.txt 2013-09-27 23:33:55.000000000 +0200 +++ new/pecan-0.4.4/pecan.egg-info/SOURCES.txt 2014-01-08 16:14:27.000000000 +0100 @@ -128,7 +128,6 @@ pecan/tests/config_fixtures/forcedict.py pecan/tests/config_fixtures/bad/importerror.py pecan/tests/config_fixtures/bad/module_and_underscore.py -pecan/tests/config_fixtures/bad/syntaxerror.py pecan/tests/middleware/__init__.py pecan/tests/middleware/test_debug.py pecan/tests/middleware/test_errordocument.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/setup.py new/pecan-0.4.4/setup.py --- old/pecan-0.4.2/setup.py 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/setup.py 2014-01-08 16:14:17.000000000 +0100 @@ -2,7 +2,7 @@ from setuptools import setup, find_packages -version = '0.4.2' +version = '0.4.4' # # determine requirements diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pecan-0.4.2/tox.ini new/pecan-0.4.4/tox.ini --- old/pecan-0.4.2/tox.ini 2013-09-27 23:33:46.000000000 +0200 +++ new/pecan-0.4.4/tox.ini 2014-01-08 16:14:17.000000000 +0100 @@ -54,6 +54,61 @@ pep8 --repeat --show-source testing123/setup.py testing123/testing123 {envpython} {toxinidir}/pecan/tests/scaffold_builder.py +[testenv:wsme-stable] +basepython = python2.7 +deps = nose +# Manually download the source from PyPI and build it with the --editable flag. +# This gives us access to run the wsmeext (pecan) tests. +commands = pip install --pre --no-deps --no-install wsme + pip install --no-clean -ve {envdir}/build/wsme/ + nosetests -v {envdir}/build/wsme/tests/pecantest + +[testenv:wsme-tip] +basepython = python2.7 +deps = -egit+http://git.openstack.org/cgit/stackforge/wsme#egg=wsme + nose +changedir = {envdir}/src/wsme +commands = nosetests -v tests/pecantest + +[testenv:ceilometer-stable] +basepython = python2.6 +deps = -egit+http://git.openstack.org/cgit/openstack/ceilometer@stable/havana#egg=ceilometer +changedir = {envdir}/src/ceilometer +usedevelop = True +setenv = VIRTUAL_ENV={envdir} + LANG=en_US.UTF-8 + LANGUAGE=en_US:en + LC_ALL=C + EVENTLET_NO_GREENDNS=yes +install_command = pip install -U {opts} {packages} +commands = pip install -vrrequirements.txt + pip install -vrtest-requirements.txt + bash -x run-tests.sh {posargs} + +[testenv:ceilometer-tip] +basepython = python2.6 +deps = -egit+http://git.openstack.org/cgit/openstack/ceilometer#egg=ceilometer +changedir = {envdir}/src/ceilometer +usedevelop = True +setenv = VIRTUAL_ENV={envdir} + LANG=en_US.UTF-8 + LANGUAGE=en_US:en + LC_ALL=C + EVENTLET_NO_GREENDNS=yes +install_command = pip install -U {opts} {packages} +commands = pip install -vrrequirements.txt + pip install -vrtest-requirements.txt + bash -x run-tests.sh {posargs} + +[testenv:ironic-tip] +basepython = python2.7 +deps = -egit+http://git.openstack.org/cgit/openstack/ironic#egg=ironic +changedir = {envdir}/src/ironic +commands = pip install -vrrequirements.txt + pip install -vrtest-requirements.txt + {envpython} setup.py develop + {envpython} setup.py testr --slowest --testr-args='{posargs}' + [testenv:pep8] deps = pep8 commands = pep8 --repeat --show-source pecan setup.py -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
