From 43a52989c77bbe07b9906bd6f971034b49b1c12c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 15 Nov 2010 06:09:08 -0500 Subject: whitespace --- TODO.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/TODO.txt b/TODO.txt index 66fc6c0ff..09cba3bb2 100644 --- a/TODO.txt +++ b/TODO.txt @@ -130,8 +130,3 @@ - zcml.file_configure - Add static_url as method of request. - - - - - -- cgit v1.2.3 From b1e3633b3874d565c7b6debcf5051bf4e638d4f4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 15 Nov 2010 06:09:52 -0500 Subject: less aggressive caching of settings n case someone uses a renderer at module scope --- pyramid/renderers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 94b58cf92..ba29f80d0 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -171,16 +171,16 @@ class ChameleonRendererLookup(object): spec = resource_spec_from_abspath(spec, package) return spec - @reify # wait until completely necessary to look up translator + @property # wait until completely necessary to look up translator def translate(self): return self.registry.queryUtility(IChameleonTranslate) - @reify # wait until completely necessary to look up debug_templates + @property # wait until completely necessary to look up debug_templates def debug(self): settings = self.registry.settings or {} return settings.get('debug_templates', False) - @reify # wait until completely necessary to look up reload_templates + @property # wait until completely necessary to look up reload_templates def auto_reload(self): settings = self.registry.settings or {} return settings.get('reload_templates', False) -- cgit v1.2.3 From 9e2e1cfa5d7b00b952b79a628347a89d2263f777 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 15 Nov 2010 22:52:46 -0500 Subject: add convenience static_url method to request --- CHANGES.txt | 6 +++--- TODO.txt | 1 - pyramid/request.py | 35 ++++++++++++++++++++++++++++++++++- pyramid/tests/test_request.py | 26 ++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index b9f6a69c7..f1e55ffce 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,9 +13,9 @@ Features - New API method: ``pyramid.settings.asbool``. -- New API methods for ``pyramid.request.Request``: ``model_url`` and - ``route_url``. These are simple passthroughs for their respective - functions in ``pyramid.url``. +- New API methods for ``pyramid.request.Request``: ``model_url``, + ``route_url``, and ``static_url``. These are simple passthroughs for their + respective functions in ``pyramid.url``. - The ``settings`` object which used to be available only when ``request.settings.get_settings`` was called is now available as diff --git a/TODO.txt b/TODO.txt index 09cba3bb2..afe9e8532 100644 --- a/TODO.txt +++ b/TODO.txt @@ -129,4 +129,3 @@ - zcml.file_configure -- Add static_url as method of request. diff --git a/pyramid/request.py b/pyramid/request.py index 891c33fff..dff70d93c 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -8,8 +8,9 @@ from pyramid.interfaces import ISessionFactory from pyramid.exceptions import ConfigurationError from pyramid.decorator import reify -from pyramid.url import route_url from pyramid.url import model_url +from pyramid.url import route_url +from pyramid.url import static_url class TemplateContext(object): pass @@ -220,6 +221,38 @@ class Request(WebobRequest): """ return model_url(model, self, *elements, **kw) + def static_url(self, path, **kw): + """ Generates a fully qualified URL for a static :term:`resource`. + The resource must live within a location defined via the + :meth:`pyramid.configuration.Configurator.add_static_view` + :term:`configuration declaration` or the ```` ZCML + directive (see :ref:`static_resources_section`). + + This is a convenience method. The result of calling + :meth:`pyramid.request.Request.static_url` is the same as calling + :func:`pyramid.url.static_url` with an explicit ``request`` parameter. + + The :meth:`pyramid.request.Request.static_url` method calls the + :func:`pyramid.url.static_url` function using the Request object as + the ``request`` argument. The ``*kw`` arguments passed to + :meth:`pyramid.request.Request.static_url` are passed through to + :func:`pyramid.url.static_url` unchanged and its result is returned. + + This call to :meth:`pyramid.request.Request.static_url`:: + + request.static_url('mypackage:static/foo.css') + + Is completely equivalent to calling :func:`pyramid.url.static_url` + like this:: + + from pyramid.url import static_url + static_url('mypackage:static/foo.css, request) + + See :func:`pyramid.url.static_url` for more information + + """ + return static_url(path, self, **kw) + # override default WebOb "environ['adhoc_attr']" mutation behavior __getattr__ = object.__getattribute__ __setattr__ = object.__setattr__ diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index d12b47642..a398bf3af 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -266,6 +266,24 @@ class TestRequest(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + def test_static_url(self): + from pyramid.interfaces import IStaticURLInfo + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'5432', + 'QUERY_STRING':'', + 'wsgi.url_scheme':'http', + } + request = self._makeOne(environ) + info = DummyStaticURLInfo('abc') + self.config.registry.registerUtility(info, IStaticURLInfo) + result = request.static_url('pyramid.tests:static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, {}) ) + + class Test_route_request_iface(unittest.TestCase): def _callFUT(self, name): from pyramid.request import route_request_iface @@ -323,3 +341,11 @@ class DummyRoute: def generate(self, kw): self.kw = kw return self.result + +class DummyStaticURLInfo: + def __init__(self, result): + self.result = result + + def generate(self, path, request, **kw): + self.args = path, request, kw + return self.result -- cgit v1.2.3 From 36c1596c229bbaf7745c2a1f2c4dfcfdefb5535d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 15 Nov 2010 22:58:14 -0500 Subject: docs backrefs --- pyramid/url.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pyramid/url.py b/pyramid/url.py index b740aaca7..fa15e6364 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -18,6 +18,9 @@ def route_url(route_name, request, *elements, **kw): """Generates a fully qualified URL for a named :app:`Pyramid` :term:`route configuration`. + .. note:: Calling :meth:`pyramid.Request.route_url` can be used to + achieve the same result as :func:`pyramid.url.route_url`. + Use the route's ``name`` as the first positional argument. Use a request object as the second positional argument. Additional positional arguments are appended to the URL as path segments @@ -102,6 +105,7 @@ def route_url(route_name, request, *elements, **kw): If the route object which matches the ``route_name`` argument has a :term:`pregenerator`, the ``*elements`` and ``**kw`` arguments arguments passed to this function might be augmented or changed. + """ try: reg = request.registry @@ -157,6 +161,9 @@ def model_url(model, request, *elements, **kw): overall result of this function is always a UTF-8 encoded string (never Unicode). + .. note:: Calling :meth:`pyramid.Request.model_url` can be used to + achieve the same result as :func:`pyramid.url.model_url`. + Examples:: model_url(context, request) => @@ -270,6 +277,9 @@ def static_url(path, request, **kw): :term:`configuration declaration` or the ```` ZCML directive (see :ref:`static_resources_section`). + .. note:: Calling :meth:`pyramid.Request.static_url` can be used to + achieve the same result as :func:`pyramid.url.static_url`. + Example:: static_url('mypackage:static/foo.css', request) => -- cgit v1.2.3 From ae60bafb11bcf3a85a8ed3c78b8fc57961e8c3b6 Mon Sep 17 00:00:00 2001 From: Ben Bangert Date: Tue, 16 Nov 2010 10:46:23 -0800 Subject: - Added Mako TemplateLookup settings for ``mako.error_handler``, ``mako.default_filters``, and ``mako.imports``. --- CHANGES.txt | 3 +++ docs/narr/environment.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++ pyramid/mako_templating.py | 6 ++++++ 3 files changed, 57 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index f1e55ffce..e8595d6fc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,9 @@ Next release Features -------- +- Added Mako TemplateLookup settings for ``mako.error_handler``, + ``mako.default_filters``, and ``mako.imports``. + - Normalized all paster templates: each now uses the name ``main`` to represent the function that returns a WSGI application, each now uses WebError, each now has roughly the same shape of development.ini style. diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 2aa4064cd..6df0998d6 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -201,6 +201,54 @@ should be changed accordingly. | | +-----------------------------+ +Mako Error Handler +++++++++++++++++++ + +Python callable which is called whenever Mako compile or runtime exceptions +occur. The callable is passed the current context as well as the exception. If +the callable returns True, the exception is considered to be handled, else it +is re-raised after the function completes. Is used to provide custom +error-rendering functions. + ++-----------------------------+ +| Config File Setting Name | ++=============================+ +| ``mako.error_handler`` _ | +| | +| | +| | ++-----------------------------+ + +Mako Default Filters +++++++++++++++++++++ + +List of string filter names that will be applied to all Mako expressions. + ++-----------------------------+ +| Config File Setting Name | ++=============================+ +| ``mako.default_filters`` _ | +| | +| | +| | ++-----------------------------+ + +Mako Import ++++++++++++ + +String list of Python statements, typically individual “import” lines, which +will be placed into the module level preamble of all generated Python modules. + + ++-----------------------------+ +| Config File Setting Name | ++=============================+ +| ``mako.imports``________ _ | +| | +| | +| | ++-----------------------------+ + Examples -------- diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index b63009e2c..e2330f3ad 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -64,6 +64,9 @@ def renderer_factory(info): directories = settings.get('mako.directories') module_directory = settings.get('mako.module_directory') input_encoding = settings.get('mako.input_encoding', 'utf-8') + error_handler = settings.get('mako.error_handler', None) + default_filters = settings.get('mako.default_filters', []) + imports = settings.get('mako.imports', []) if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') @@ -72,6 +75,9 @@ def renderer_factory(info): lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, + error_handler=error_handler, + default_filters=default_filters, + imports=imports, filesystem_checks=reload_templates) registry_lock.acquire() try: -- cgit v1.2.3 From 3dbf5edd33172b7ee70783dfde77949c2a3c3641 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 15:40:39 -0500 Subject: fix rendering --- docs/narr/environment.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 6df0998d6..ecf85e464 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -213,7 +213,7 @@ error-rendering functions. +-----------------------------+ | Config File Setting Name | +=============================+ -| ``mako.error_handler`` _ | +| ``mako.error_handler`` | | | | | | | @@ -227,7 +227,7 @@ List of string filter names that will be applied to all Mako expressions. +-----------------------------+ | Config File Setting Name | +=============================+ -| ``mako.default_filters`` _ | +| ``mako.default_filters`` | | | | | | | @@ -243,7 +243,7 @@ will be placed into the module level preamble of all generated Python modules. +-----------------------------+ | Config File Setting Name | +=============================+ -| ``mako.imports``________ _ | +| ``mako.imports`` | | | | | | | -- cgit v1.2.3 From 3fa99493e9ba3d1dc05d8e917ee2f1bc1b6ed14e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 15:51:22 -0500 Subject: prep for 1.0a3 --- CHANGES.txt | 4 ++-- docs/conf.py | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e8595d6fc..942720112 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ -Next release -============ +1.0a3 (2010-11-16) +================== Features -------- diff --git a/docs/conf.py b/docs/conf.py index c2ecb1e8d..b4448b803 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -73,7 +73,7 @@ copyright = '%s, Agendaless Consulting' % datetime.datetime.now().year # other places throughout the built documents. # # The short X.Y version. -version = '1.0a2' +version = '1.0a3' # The full version, including alpha/beta/rc tags. release = version diff --git a/setup.py b/setup.py index b220d2914..6dddc7643 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ # ############################################################################## -__version__ = '0.0' +__version__ = '1.0a3' import os import platform -- cgit v1.2.3 From 745a613c164c3129113508afbf7ea5dedcdbcadb Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 15:58:04 -0500 Subject: back to development --- CHANGES.txt | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 942720112..7dee3f99d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +Next release +============ + + 1.0a3 (2010-11-16) ================== diff --git a/setup.py b/setup.py index 6dddc7643..b220d2914 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ # ############################################################################## -__version__ = '1.0a3' +__version__ = '0.0' import os import platform -- cgit v1.2.3 From 111a6fbae020f99c206b97459920908baad604cd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 18:17:54 -0500 Subject: - Add deprecation warnings to import of ``pyramid.chameleon_text`` and ``pyramid.chameleon_zpt`` of ``get_renderer``, ``get_template``, ``render_template``, and ``render_template_to_response``. --- CHANGES.txt | 7 +++++++ TODO.txt | 3 --- pyramid/chameleon_text.py | 23 +++++++++++++++++++++++ pyramid/chameleon_zpt.py | 22 ++++++++++++++++++++++ pyramid/tests/test_chameleon_text.py | 4 ++++ pyramid/tests/test_chameleon_zpt.py | 4 ++++ 6 files changed, 60 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7dee3f99d..f25d0e83f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,13 @@ Next release ============ +Bug Fixes +--------- + +- Add deprecation warnings to import of ``pyramid.chameleon_text`` and + ``pyramid.chameleon_zpt`` of ``get_renderer``, ``get_template``, + ``render_template``, and ``render_template_to_response``. + 1.0a3 (2010-11-16) ================== diff --git a/TODO.txt b/TODO.txt index afe9e8532..33d39a825 100644 --- a/TODO.txt +++ b/TODO.txt @@ -120,9 +120,6 @@ - Add deprecation warnings for: - - Use of chameleon_zpt and chameleon_text templating functions (use - renderer API instead). - - settings.get_settings - zcml.zcml_configure diff --git a/pyramid/chameleon_text.py b/pyramid/chameleon_text.py index 1f31f3add..f8d96ddf5 100644 --- a/pyramid/chameleon_text.py +++ b/pyramid/chameleon_text.py @@ -1,5 +1,6 @@ import sys +from zope.deprecation import deprecated from zope.interface import implements try: @@ -80,6 +81,11 @@ def get_renderer(path): factory = renderers.RendererHelper(path, package=package) return factory.get_renderer() +deprecated( + 'get_renderer', + '(pyramid.chameleon_text.get_renderer is deprecated ' + 'as of Pyramid 1.0; instead use pyramid.renderers.get_renderer)') + def get_template(path): """ Return the underyling object representing a :term:`Chameleon` text template using the template implied by the ``path`` argument. @@ -94,6 +100,12 @@ def get_template(path): factory = renderers.RendererHelper(path, package=package) return factory.get_renderer().implementation() +deprecated( + 'render_template', + '(pyramid.chameleon_text.render_template is deprecated ' + 'as of Pyramid 1.0; instead use ' + 'pyramid.renderers.get_renderer().implementation())') + def render_template(path, **kw): """ Render a :term:`Chameleon` text template using the template implied by the ``path`` argument. The ``path`` argument may be a @@ -110,6 +122,11 @@ def render_template(path, **kw): renderer = renderers.RendererHelper(path, package=package) return renderer.render(kw, None, request=request) +deprecated( + 'render_template', + '(pyramid.chameleon_text.render_template is deprecated ' + 'as of Pyramid 1.0; instead use pyramid.renderers.render)') + def render_template_to_response(path, **kw): """ Render a :term:`Chameleon` text template using the template implied by the ``path`` argument. The ``path`` argument may be a @@ -126,3 +143,9 @@ def render_template_to_response(path, **kw): request = kw.pop('request', None) renderer = renderers.RendererHelper(path, package=package) return renderer.render_to_response(kw, None, request=request) + +deprecated( + 'render_template_to_response', + '(pyramid.chameleon_text.render_template_to_response is deprecated ' + 'as of Pyramid 1.0; instead use pyramid.renderers.render_to_response)') + diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py index 6aae59a87..55bef1d0c 100644 --- a/pyramid/chameleon_zpt.py +++ b/pyramid/chameleon_zpt.py @@ -1,6 +1,7 @@ import sys import threading +from zope.deprecation import deprecated from zope.interface import implements try: @@ -65,6 +66,11 @@ def get_renderer(path): factory = renderers.RendererHelper(name=path, package=package) return factory.get_renderer() +deprecated( + 'get_renderer', + '(pyramid.chameleon_zpt.get_renderer is deprecated ' + 'as of Pyramid 1.0; instead use pyramid.renderers.get_renderer)') + def get_template(path): """ Return the underyling object representing a :term:`Chameleon` ZPT template using the template implied by the ``path`` argument. @@ -79,6 +85,12 @@ def get_template(path): factory = renderers.RendererHelper(name=path, package=package) return factory.get_renderer().implementation() +deprecated( + 'get_template', + '(pyramid.chameleon_zpt.get_template is deprecated ' + 'as of Pyramid 1.0; instead use ' + 'pyramid.renderers.get_renderer().implementation())') + def render_template(path, **kw): """ Render a :term:`Chameleon` ZPT template using the template implied by the ``path`` argument. The ``path`` argument may be a @@ -95,6 +107,11 @@ def render_template(path, **kw): renderer = renderers.RendererHelper(name=path, package=package) return renderer.render(kw, None, request=request) +deprecated( + 'render_template', + '(pyramid.chameleon_zpt.render_template is deprecated as of Pyramid 1.0; ' + 'instead use pyramid.renderers.render)') + def render_template_to_response(path, **kw): """ Render a :term:`Chameleon` ZPT template using the template implied by the ``path`` argument. The ``path`` argument may be a @@ -111,3 +128,8 @@ def render_template_to_response(path, **kw): request = kw.pop('request', None) renderer = renderers.RendererHelper(name=path, package=package) return renderer.render_to_response(kw, None, request=request) + +deprecated( + 'render_template', + '(pyramid.chameleon_zpt.render_template_to_response is deprecated; as of ' + 'Pyramid 1.0, instead use pyramid.renderers.render_to_response)') diff --git a/pyramid/tests/test_chameleon_text.py b/pyramid/tests/test_chameleon_text.py index a42b92bfa..027fa9474 100644 --- a/pyramid/tests/test_chameleon_text.py +++ b/pyramid/tests/test_chameleon_text.py @@ -11,9 +11,13 @@ class Base: os.unlink(self._getTemplatePath('minimal.txt.py')) except: pass + from zope.deprecation import __show__ + __show__.off() def tearDown(self): cleanUp() + from zope.deprecation import __show__ + __show__.on() def _getTemplatePath(self, name): import os diff --git a/pyramid/tests/test_chameleon_zpt.py b/pyramid/tests/test_chameleon_zpt.py index 8f0b3f03c..3e508ce6a 100644 --- a/pyramid/tests/test_chameleon_zpt.py +++ b/pyramid/tests/test_chameleon_zpt.py @@ -5,9 +5,13 @@ from pyramid.testing import cleanUp class Base(object): def setUp(self): cleanUp() + from zope.deprecation import __show__ + __show__.off() def tearDown(self): cleanUp() + from zope.deprecation import __show__ + __show__.on() def _getTemplatePath(self, name): import os -- cgit v1.2.3 From ff3bc6597257903a4a05cc95fc9276f4fa120eb8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 20:14:37 -0500 Subject: get deprecations right --- pyramid/chameleon_text.py | 4 ++-- pyramid/chameleon_zpt.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/chameleon_text.py b/pyramid/chameleon_text.py index f8d96ddf5..6eb7af4d0 100644 --- a/pyramid/chameleon_text.py +++ b/pyramid/chameleon_text.py @@ -101,8 +101,8 @@ def get_template(path): return factory.get_renderer().implementation() deprecated( - 'render_template', - '(pyramid.chameleon_text.render_template is deprecated ' + 'get_template', + '(pyramid.chameleon_text.get_template is deprecated ' 'as of Pyramid 1.0; instead use ' 'pyramid.renderers.get_renderer().implementation())') diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py index 55bef1d0c..5c2d6f70f 100644 --- a/pyramid/chameleon_zpt.py +++ b/pyramid/chameleon_zpt.py @@ -130,6 +130,6 @@ def render_template_to_response(path, **kw): return renderer.render_to_response(kw, None, request=request) deprecated( - 'render_template', + 'render_template_to_response', '(pyramid.chameleon_zpt.render_template_to_response is deprecated; as of ' 'Pyramid 1.0, instead use pyramid.renderers.render_to_response)') -- cgit v1.2.3 From f4c3876685fa222eed96985bbdf37347ad362df2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 20:28:59 -0500 Subject: prevent deprecation warning during tests --- pyramid/tests/test_chameleon_zpt.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyramid/tests/test_chameleon_zpt.py b/pyramid/tests/test_chameleon_zpt.py index 3e508ce6a..056b95937 100644 --- a/pyramid/tests/test_chameleon_zpt.py +++ b/pyramid/tests/test_chameleon_zpt.py @@ -145,12 +145,6 @@ class RenderTemplateTests(Base, unittest.TestCase): '
\n
') class RenderTemplateToResponseTests(Base, unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - def _callFUT(self, name, **kw): from pyramid.chameleon_zpt import render_template_to_response return render_template_to_response(name, **kw) -- cgit v1.2.3 From b68aadc3867a95a6376bb2157cc93210eb62a104 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 20:31:04 -0500 Subject: - The ``pyramid.settings.get_settings`` API is now deprecated. Use ``pyramid.threadlocals.get_registry().settings`` instead or use the ``settings`` attribute of the registry available from the request (``request.registry.settings``). --- CHANGES.txt | 7 +++++++ docs/narr/i18n.rst | 9 +++++---- docs/narr/static.rst | 31 +++++++++++++++---------------- pyramid/configuration.py | 23 ++++++++++------------- pyramid/settings.py | 13 +++++++++++++ pyramid/testing.py | 8 ++++---- pyramid/tests/test_settings.py | 4 ++++ 7 files changed, 58 insertions(+), 37 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f25d0e83f..d132b4e71 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,6 +8,13 @@ Bug Fixes ``pyramid.chameleon_zpt`` of ``get_renderer``, ``get_template``, ``render_template``, and ``render_template_to_response``. +Deprecations +------------ + +- The ``pyramid.settings.get_settings`` API is now deprecated. Use + ``pyramid.threadlocals.get_registry().settings`` instead or use the + ``settings`` attribute of the registry available from the request + (``request.registry.settings``). 1.0a3 (2010-11-16) ================== diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 703883fb2..9e2071872 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -773,8 +773,8 @@ If this setting is supplied within the :app:`Pyramid` application .. code-block:: python :linenos: - from pyramid.setttings import get_settings - settings = get_settings() + from pyramid.threadlocal import get_current_registry + settings = get_current_registry().settings default_locale_name = settings['default_locale_name'] "Detecting" Available Languages @@ -822,8 +822,9 @@ Then as a part of the code of a custom :term:`locale negotiator`: .. code-block:: py - from pyramid.settings import get_settings - languages = get_settings()['available_languages'].split() + from pyramid.threadlocal import get_current_registry + settings = get_current_registry().settings + languages = settings['available_languages'].split() This is only a suggestion. You can create your own "available languages" configuration scheme as necessary. diff --git a/docs/narr/static.rst b/docs/narr/static.rst index efeabd012..a01cbbabf 100644 --- a/docs/narr/static.rst +++ b/docs/narr/static.rst @@ -69,22 +69,21 @@ when generating a URL using :func:`pyramid.url.static_url`. .. note:: Using :func:`pyramid.url.static_url` in conjunction with a - :meth:`pyramid.configuration.Configurator.add_static_view` makes - it possible to put static media on a separate webserver during - production (if the ``name`` argument to - :meth:`pyramid.configuration.Configurator.add_static_view` is a - URL), while keeping static media package-internal and served by the - development webserver during development (if the ``name`` argument - to :meth:`pyramid.configuration.Configurator.add_static_view` is - a view name). To create such a circumstance, we suggest using the - :func:`pyramid.settings.get_settings` API in conjunction with a - setting in the application ``.ini`` file named ``media_location``. - Then set the value of ``media_location`` to either a view name or a - URL depending on whether the application is being run in - development or in production (use a different `.ini`` file for - production than you do for development). This is just a suggestion - for a pattern; any setting name other than ``media_location`` could - be used. + :meth:`pyramid.configuration.Configurator.add_static_view` makes it + possible to put static media on a separate webserver during production (if + the ``name`` argument to + :meth:`pyramid.configuration.Configurator.add_static_view` is a URL), + while keeping static media package-internal and served by the development + webserver during development (if the ``name`` argument to + :meth:`pyramid.configuration.Configurator.add_static_view` is a view + name). To create such a circumstance, we suggest using the + :attr:`pyramid.registry.Registry.settings` API in conjunction with a + setting in the application ``.ini`` file named ``media_location``. Then + set the value of ``media_location`` to either a view name or a URL + depending on whether the application is being run in development or in + production (use a different `.ini`` file for production than you do for + development). This is just a suggestion for a pattern; any setting name + other than ``media_location`` could be used. For example, :meth:`pyramid.configuration.Configurator.add_static_view` may be fed a ``name`` argument which is ``http://example.com/images``: diff --git a/pyramid/configuration.py b/pyramid/configuration.py index cee65a982..3d1530406 100644 --- a/pyramid/configuration.py +++ b/pyramid/configuration.py @@ -570,11 +570,10 @@ class Configurator(object): return subscriber def add_settings(self, settings=None, **kw): - """Augment the ``settings`` argument passed in to the - Configurator constructor with one or more 'setting' key/value - pairs. A setting is a single key/value pair in the - dictionary-ish object returned from the API - :func:`pyramid.settings.get_settings` and + """Augment the ``settings`` argument passed in to the Configurator + constructor with one or more 'setting' key/value pairs. A setting is + a single key/value pair in the dictionary-ish object returned from + the API :attr:`pyramid.registry.Registry.settings` and :meth:`pyramid.configuration.Configurator.get_settings`. You may pass a dictionary:: @@ -585,11 +584,10 @@ class Configurator(object): config.add_settings(external_uri='http://example.com') - This function is useful when you need to test code that calls the - :func:`pyramid.settings.get_settings` API (or the - :meth:`pyramid.configuration.Configurator.get_settings` API or - accesses ``request.settings``) and which uses return values from that - API. + This function is useful when you need to test code that accesses the + :attr:`pyramid.registry.Registry.settings` API (or the + :meth:`pyramid.configuration.Configurator.get_settings` API) and + which uses values from that API. """ if settings is None: settings = {} @@ -610,9 +608,8 @@ class Configurator(object): .. note:: For backwards compatibility, dictionary keys can also be looked up as attributes of the settings object. - .. note:: the :class:`pyramid.settings.get_settings` and function - performs the same duty and the settings attribute can also be - accessed as :attr:`pyramid.registry.Registry.settings` + .. note:: the :attr:`pyramid.registry.Registry.settings` API + performs the same duty. """ return self.registry.settings diff --git a/pyramid/settings.py b/pyramid/settings.py index 96ad3336a..d6b0a6470 100644 --- a/pyramid/settings.py +++ b/pyramid/settings.py @@ -1,5 +1,6 @@ import os +from zope.deprecation import deprecated from zope.interface import implements from pyramid.interfaces import ISettings @@ -75,10 +76,22 @@ def get_settings(): .. note:: the :class:`pyramid.configuration.Configurator.get_settings` method performs the same duty. + + .. warning:: This method is deprecated as of Pyramid 1.0. Use + ``pyramid.threadlocals.get_registry().settings`` instead or use the + ``settings`` attribute of the registry available from the request + (``request.registry.settings``). """ reg = get_current_registry() return reg.settings +deprecated( + 'get_settings', + '(pyramid.settings.get_settings is deprecated as of Pyramid 1.0. Use' + '``pyramid.threadlocals.get_registry().settings`` instead or use the ' + '``settings`` attribute of the registry available from the request ' + '(``request.registry.settings``)).') + def asbool(s): """ Return the boolean value ``True`` if the case-lowered value of string input ``s`` is any of ``t``, ``true``, ``y``, ``on``, or ``1``, otherwise diff --git a/pyramid/testing.py b/pyramid/testing.py index e8e843bff..84ab77935 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -277,7 +277,7 @@ def registerRoute(pattern, name, factory=None): def registerSettings(dictarg=None, **kw): """Register one or more 'setting' key/value pairs. A setting is a single key/value pair in the dictionary-ish object returned from - the API :func:`pyramid.settings.get_settings`. + the API :attr:`pyramid.registry.Registry.settings`. You may pass a dictionary:: @@ -287,9 +287,9 @@ def registerSettings(dictarg=None, **kw): registerSettings(external_uri='http://example.com') - Use of this function is required when you need to test code that - calls the :func:`pyramid.settings.get_settings` API and which - uses return values from that API. + Use of this function is required when you need to test code that calls + the :attr:`pyramid.registry.Registry.settings` API and which uses return + values from that API. .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. Instead use the diff --git a/pyramid/tests/test_settings.py b/pyramid/tests/test_settings.py index 12b1174de..49c1e928f 100644 --- a/pyramid/tests/test_settings.py +++ b/pyramid/tests/test_settings.py @@ -184,9 +184,13 @@ class TestGetSettings(unittest.TestCase): registry = Registry('testing') self.config = Configurator(registry=registry) self.config.begin() + from zope.deprecation import __show__ + __show__.off() def tearDown(self): self.config.end() + from zope.deprecation import __show__ + __show__.on() def _callFUT(self): from pyramid.settings import get_settings -- cgit v1.2.3 From 34f44d844ffe75738046a154202a6faf4d5dfc38 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 20:50:28 -0500 Subject: - Add deprecation warning for import of ``pyramid.zcml.zcml_configure`` and ``pyramid.zcml.file_configure``. - The ``pyramid.testing.zcml_configure`` API has been removed. It had been advertised as removed since 1.2a1, but hadn't actually been. --- CHANGES.txt | 9 +++++++++ TODO.txt | 7 ------- pyramid/testing.py | 3 --- pyramid/tests/test_zcml.py | 4 ++++ pyramid/zcml.py | 12 ++++++++++++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d132b4e71..28637c1a7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,6 +8,15 @@ Bug Fixes ``pyramid.chameleon_zpt`` of ``get_renderer``, ``get_template``, ``render_template``, and ``render_template_to_response``. +- Add deprecation warning for import of ``pyramid.zcml.zcml_configure`` and + ``pyramid.zcml.file_configure``. + +Backwards Incompatibilities +--------------------------- + +- The ``pyramid.testing.zcml_configure`` API has been removed. It had been + advertised as removed since 1.2a1, but hadn't actually been. + Deprecations ------------ diff --git a/TODO.txt b/TODO.txt index 33d39a825..759b9bb70 100644 --- a/TODO.txt +++ b/TODO.txt @@ -118,11 +118,4 @@ Configurator.add_translation_dirs: not passed any context but a message, can't credibly be removed. -- Add deprecation warnings for: - - - settings.get_settings - - - zcml.zcml_configure - - - zcml.file_configure diff --git a/pyramid/testing.py b/pyramid/testing.py index 84ab77935..4bc4728c0 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -20,9 +20,6 @@ from pyramid.security import Everyone from pyramid.security import has_permission from pyramid.threadlocal import get_current_registry from pyramid.threadlocal import manager -from pyramid.zcml import zcml_configure # API - -zcml_configure # prevent pyflakes from complaining _marker = object() diff --git a/pyramid/tests/test_zcml.py b/pyramid/tests/test_zcml.py index f4a6e81b6..905a53287 100644 --- a/pyramid/tests/test_zcml.py +++ b/pyramid/tests/test_zcml.py @@ -803,6 +803,8 @@ class TestZCMLConfigure(unittest.TestCase): return zcml_configure(path, package) def setUp(self): + from zope.deprecation import __show__ + __show__.off() testing.setUp() self.tempdir = None import sys @@ -822,6 +824,8 @@ class TestZCMLConfigure(unittest.TestCase): self.tempdir = tempdir def tearDown(self): + from zope.deprecation import __show__ + __show__.on() testing.tearDown() import sys import shutil diff --git a/pyramid/zcml.py b/pyramid/zcml.py index a2fdec314..3104ebac0 100644 --- a/pyramid/zcml.py +++ b/pyramid/zcml.py @@ -6,6 +6,8 @@ from zope.configuration.fields import GlobalInterface from zope.configuration.fields import GlobalObject from zope.configuration.fields import Tokens +from zope.deprecation import deprecated + from zope.interface import Interface from zope.interface import implementedBy from zope.interface import providedBy @@ -937,6 +939,16 @@ def zcml_configure(name, package): file_configure = zcml_configure # backwards compat (>0.8.1) +deprecated( + 'zcml_configure', + '(pyramid.zcml.zcml_configure is deprecated as of Pyramid 1.0. Use' + '``pyramid.configuration.Configurator.load_zcml`` instead.) ') + +deprecated( + 'file_configure', + '(pyramid.zcml.file_configure is deprecated as of Pyramid 1.0. Use' + '``pyramid.configuration.Configurator.load_zcml`` instead.) ') + def _rolledUpFactory(factories): def factory(ob): for f in factories: -- cgit v1.2.3 From 84df816470b6745c628c177c99dee9fa844812c4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 20:51:56 -0500 Subject: point at correct location of get_current_registry --- CHANGES.txt | 2 +- pyramid/settings.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 28637c1a7..2737e6893 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -21,7 +21,7 @@ Deprecations ------------ - The ``pyramid.settings.get_settings`` API is now deprecated. Use - ``pyramid.threadlocals.get_registry().settings`` instead or use the + ``pyramid.threadlocals.get_current_registry().settings`` instead or use the ``settings`` attribute of the registry available from the request (``request.registry.settings``). diff --git a/pyramid/settings.py b/pyramid/settings.py index d6b0a6470..64b108421 100644 --- a/pyramid/settings.py +++ b/pyramid/settings.py @@ -78,8 +78,8 @@ def get_settings(): performs the same duty. .. warning:: This method is deprecated as of Pyramid 1.0. Use - ``pyramid.threadlocals.get_registry().settings`` instead or use the - ``settings`` attribute of the registry available from the request + ``pyramid.threadlocals.get_current_registry().settings`` instead or use ' + the ``settings`` attribute of the registry available from the request (``request.registry.settings``). """ reg = get_current_registry() @@ -88,8 +88,8 @@ def get_settings(): deprecated( 'get_settings', '(pyramid.settings.get_settings is deprecated as of Pyramid 1.0. Use' - '``pyramid.threadlocals.get_registry().settings`` instead or use the ' - '``settings`` attribute of the registry available from the request ' + '``pyramid.threadlocals.get_current_registry().settings`` instead or use ' + 'the ``settings`` attribute of the registry available from the request ' '(``request.registry.settings``)).') def asbool(s): -- cgit v1.2.3 From 327b51fe1f1160b98289070c181b088addc16dd0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 21:48:25 -0500 Subject: add ignores for jython usual suspects --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 09439306e..5d46de01f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,13 @@ *.egg *.egg-info *.pyc +*$py.class *.pt.py *.txt.py .coverage env26 env24 env27 +jyenv build/ dist/ -- cgit v1.2.3 From adc1670a54d270f2a17eff6898cc0931eabea450 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 21:49:44 -0500 Subject: make some tests which previously failed on jython pass --- pyramid/tests/test_integration.py | 15 ++++++++++----- pyramid/tests/viewdecoratorapp/views/templates/foo.mak | 3 +++ pyramid/tests/viewdecoratorapp/views/templates/foo.pt | 3 --- pyramid/tests/viewdecoratorapp/views/views.py | 10 ++-------- 4 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 pyramid/tests/viewdecoratorapp/views/templates/foo.mak delete mode 100644 pyramid/tests/viewdecoratorapp/views/templates/foo.pt diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index e8d119e79..bc9d75d33 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -70,6 +70,11 @@ class TwillBase(unittest.TestCase): def setUp(self): import sys import twill + from twill.commands import config as twillconfig + # for benefit of Jython, which cannot import the subprocess module, we + # configure twill to not use tidy + twillconfig('use_tidy', False) + twillconfig('require_tidy', False) from pyramid.configuration import Configurator config = Configurator(root_factory=self.root_factory) config.load_zcml(self.config) @@ -79,7 +84,7 @@ class TwillBase(unittest.TestCase): else: out = open('/dev/null', 'wb') twill.set_output(out) - testing.setUp(registry=config.registry) + self.config = testing.setUp(registry=config.registry) def tearDown(self): import twill @@ -172,6 +177,10 @@ class TestRestBugApp(TwillBase): class TestViewDecoratorApp(TwillBase): config = 'pyramid.tests.viewdecoratorapp:configure.zcml' def test_it(self): + # we use mako here instead of chameleon because it works on Jython + tmpldir = os.path.join(os.path.dirname(__file__), 'viewdecoratorapp', + 'views') + self.config.registry.settings['mako.directories'] = tmpldir import twill.commands browser = twill.commands.get_browser() browser.go('http://localhost:6543/first') @@ -182,10 +191,6 @@ class TestViewDecoratorApp(TwillBase): self.assertEqual(browser.get_code(), 200) self.failUnless('OK2' in browser.get_html()) - browser.go('http://localhost:6543/third') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK3' in browser.get_html()) - class TestViewPermissionBug(TwillBase): # view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html config = 'pyramid.tests.permbugapp:configure.zcml' diff --git a/pyramid/tests/viewdecoratorapp/views/templates/foo.mak b/pyramid/tests/viewdecoratorapp/views/templates/foo.mak new file mode 100644 index 000000000..6a2f701b6 --- /dev/null +++ b/pyramid/tests/viewdecoratorapp/views/templates/foo.mak @@ -0,0 +1,3 @@ + +${result} + diff --git a/pyramid/tests/viewdecoratorapp/views/templates/foo.pt b/pyramid/tests/viewdecoratorapp/views/templates/foo.pt deleted file mode 100644 index 6a2f701b6..000000000 --- a/pyramid/tests/viewdecoratorapp/views/templates/foo.pt +++ /dev/null @@ -1,3 +0,0 @@ - -${result} - diff --git a/pyramid/tests/viewdecoratorapp/views/views.py b/pyramid/tests/viewdecoratorapp/views/views.py index c59bc87ed..0b3147c86 100644 --- a/pyramid/tests/viewdecoratorapp/views/views.py +++ b/pyramid/tests/viewdecoratorapp/views/views.py @@ -1,17 +1,11 @@ -import os from pyramid.view import view_config -@view_config(renderer='templates/foo.pt', name='first') +@view_config(renderer='templates/foo.mak', name='first') def first(request): return {'result':'OK1'} -@view_config(renderer='pyramid.tests.viewdecoratorapp.views:templates/foo.pt', +@view_config(renderer='pyramid.tests.viewdecoratorapp.views:templates/foo.mak', name='second') def second(request): return {'result':'OK2'} -here = os.path.normpath(os.path.dirname(os.path.abspath(__file__))) -foo = os.path.join(here, 'templates', 'foo.pt') -@view_config(renderer=foo, name='third') -def third(request): - return {'result':'OK3'} -- cgit v1.2.3 From 35c5a3a77ff2f17aa06ae25032d2b2baeb75e096 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Nov 2010 22:06:14 -0500 Subject: skip Chameleon tests on Jython --- pyramid/testing.py | 14 ++++++++++++++ pyramid/tests/test_chameleon_text.py | 15 +++++++++++++++ pyramid/tests/test_chameleon_zpt.py | 15 +++++++++++++++ pyramid/tests/test_testing.py | 24 ++++++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/pyramid/testing.py b/pyramid/testing.py index 4bc4728c0..deb6c8d8e 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -1,4 +1,5 @@ import copy +import os from zope.configuration.xmlconfig import _clearContext @@ -733,3 +734,16 @@ class MockTemplate(object): def __call__(self, *arg, **kw): self._received.update(kw) return self.response + +def skip_on(*platforms): + def decorator(func): + def wrapper(*args, **kw): + for platform in platforms: + if skip_on.os_name.startswith(platform): + return + return func(*args, **kw) + wrapper.__name__ = func.__name__ + wrapper.__doc__ = func.__doc__ + return wrapper + return decorator +skip_on.os_name = os.name # for testing diff --git a/pyramid/tests/test_chameleon_text.py b/pyramid/tests/test_chameleon_text.py index 027fa9474..654cfdf3b 100644 --- a/pyramid/tests/test_chameleon_text.py +++ b/pyramid/tests/test_chameleon_text.py @@ -1,6 +1,7 @@ import unittest from pyramid.testing import cleanUp +from pyramid.testing import skip_on class Base: def setUp(self): @@ -62,6 +63,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): from pyramid.interfaces import ITemplateRenderer verifyClass(ITemplateRenderer, self._getTargetClass()) + @skip_on('java') def test_template_reified(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -70,6 +72,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template, instance.__dict__['template']) + @skip_on('java') def test_template_with_ichameleon_translate(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -78,6 +81,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.translate, lookup.translate) + @skip_on('java') def test_template_with_debug_templates(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -87,6 +91,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.debug, True) + @skip_on('java') def test_template_with_reload_templates(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -96,6 +101,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.auto_reload, True) + @skip_on('java') def test_template_without_reload_templates(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -105,6 +111,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.auto_reload, False) + @skip_on('java') def test_call(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -113,12 +120,14 @@ class TextTemplateRendererTests(Base, unittest.TestCase): self.failUnless(isinstance(result, str)) self.assertEqual(result, 'Hello.\n') + @skip_on('java') def test_call_with_nondict_value(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() instance = self._makeOne(minimal, lookup) self.assertRaises(ValueError, instance, None, {}) + @skip_on('java') def test_call_nonminimal(self): nonminimal = self._getTemplatePath('nonminimal.txt') lookup = DummyLookup() @@ -127,6 +136,7 @@ class TextTemplateRendererTests(Base, unittest.TestCase): self.failUnless(isinstance(result, str)) self.assertEqual(result, 'Hello, Chris!\n') + @skip_on('java') def test_implementation(self): minimal = self._getTemplatePath('minimal.txt') lookup = DummyLookup() @@ -140,6 +150,7 @@ class RenderTemplateTests(Base, unittest.TestCase): from pyramid.chameleon_text import render_template return render_template(name, **kw) + @skip_on('java') def test_it(self): minimal = self._getTemplatePath('minimal.txt') result = self._callFUT(minimal) @@ -151,6 +162,7 @@ class RenderTemplateToResponseTests(Base, unittest.TestCase): from pyramid.chameleon_text import render_template_to_response return render_template_to_response(name, **kw) + @skip_on('java') def test_minimal(self): minimal = self._getTemplatePath('minimal.txt') result = self._callFUT(minimal) @@ -160,6 +172,7 @@ class RenderTemplateToResponseTests(Base, unittest.TestCase): self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) + @skip_on('java') def test_iresponsefactory_override(self): from webob import Response class Response2(Response): @@ -175,6 +188,7 @@ class GetRendererTests(Base, unittest.TestCase): from pyramid.chameleon_text import get_renderer return get_renderer(name) + @skip_on('java') def test_it(self): from pyramid.interfaces import IRendererFactory class Dummy: @@ -192,6 +206,7 @@ class GetTemplateTests(Base, unittest.TestCase): from pyramid.chameleon_text import get_template return get_template(name) + @skip_on('java') def test_it(self): from pyramid.interfaces import IRendererFactory class Dummy: diff --git a/pyramid/tests/test_chameleon_zpt.py b/pyramid/tests/test_chameleon_zpt.py index 056b95937..786e96129 100644 --- a/pyramid/tests/test_chameleon_zpt.py +++ b/pyramid/tests/test_chameleon_zpt.py @@ -1,6 +1,7 @@ import unittest from pyramid.testing import cleanUp +from pyramid.testing import skip_on class Base(object): def setUp(self): @@ -55,6 +56,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): from pyramid.interfaces import ITemplateRenderer verifyClass(ITemplateRenderer, self._getTargetClass()) + @skip_on('java') def test_call(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -64,6 +66,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): self.assertEqual(result, '
\n
') + @skip_on('java') def test_template_reified(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -72,6 +75,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template, instance.__dict__['template']) + @skip_on('java') def test_template_with_ichameleon_translate(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -80,6 +84,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.translate, lookup.translate) + @skip_on('java') def test_template_with_debug_templates(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -89,6 +94,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.debug, True) + @skip_on('java') def test_template_without_debug_templates(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -98,6 +104,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.debug, False) + @skip_on('java') def test_template_with_reload_templates(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -107,6 +114,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.auto_reload, True) + @skip_on('java') def test_template_without_reload_templates(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -116,12 +124,14 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): template = instance.template self.assertEqual(template.auto_reload, False) + @skip_on('java') def test_call_with_nondict_value(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() instance = self._makeOne(minimal, lookup) self.assertRaises(ValueError, instance, None, {}) + @skip_on('java') def test_implementation(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -137,6 +147,7 @@ class RenderTemplateTests(Base, unittest.TestCase): from pyramid.chameleon_zpt import render_template return render_template(name, **kw) + @skip_on('java') def test_it(self): minimal = self._getTemplatePath('minimal.pt') result = self._callFUT(minimal) @@ -149,6 +160,7 @@ class RenderTemplateToResponseTests(Base, unittest.TestCase): from pyramid.chameleon_zpt import render_template_to_response return render_template_to_response(name, **kw) + @skip_on('java') def test_it(self): minimal = self._getTemplatePath('minimal.pt') result = self._callFUT(minimal) @@ -159,6 +171,7 @@ class RenderTemplateToResponseTests(Base, unittest.TestCase): self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) + @skip_on('java') def test_iresponsefactory_override(self): from webob import Response class Response2(Response): @@ -174,6 +187,7 @@ class GetRendererTests(Base, unittest.TestCase): from pyramid.chameleon_zpt import get_renderer return get_renderer(name) + @skip_on('java') def test_it(self): from pyramid.interfaces import IRendererFactory class Dummy: @@ -191,6 +205,7 @@ class GetTemplateTests(Base, unittest.TestCase): from pyramid.chameleon_zpt import get_template return get_template(name) + @skip_on('java') def test_it(self): from pyramid.interfaces import IRendererFactory class Dummy: diff --git a/pyramid/tests/test_testing.py b/pyramid/tests/test_testing.py index 8336bcec5..f05e7fc01 100644 --- a/pyramid/tests/test_testing.py +++ b/pyramid/tests/test_testing.py @@ -693,6 +693,30 @@ class TestMockTemplate(unittest.TestCase): template = self._makeOne('123') self.assertEqual(template(), '123') +class Test_skip_on(unittest.TestCase): + def setUp(self): + from pyramid.testing import skip_on + self.os_name = skip_on.os_name + skip_on.os_name = 'wrong' + + def tearDown(self): + from pyramid.testing import skip_on + skip_on.os_name = self.os_name + + def _callFUT(self, *platforms): + from pyramid.testing import skip_on + return skip_on(*platforms) + + def test_wrong_platform(self): + def foo(): return True + decorated = self._callFUT('wrong')(foo) + self.assertEqual(decorated(), None) + + def test_ok_platform(self): + def foo(): return True + decorated = self._callFUT('ok')(foo) + self.assertEqual(decorated(), True) + from zope.interface import Interface from zope.interface import implements -- cgit v1.2.3 From 1e00f3a5f3a1ae01999f99d412a35ec46abc827c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 00:33:42 -0500 Subject: - The ``pyramid_alchemy`` paster template had a typo, preventing an import from working. --- CHANGES.txt | 3 +++ pyramid/paster_templates/alchemy/+package+/__init__.py_tmpl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2737e6893..c775bd422 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,9 @@ Bug Fixes - Add deprecation warning for import of ``pyramid.zcml.zcml_configure`` and ``pyramid.zcml.file_configure``. +- The ``pyramid_alchemy`` paster template had a typo, preventing an import + from working. + Backwards Incompatibilities --------------------------- diff --git a/pyramid/paster_templates/alchemy/+package+/__init__.py_tmpl b/pyramid/paster_templates/alchemy/+package+/__init__.py_tmpl index a245bf141..748f58692 100755 --- a/pyramid/paster_templates/alchemy/+package+/__init__.py_tmpl +++ b/pyramid/paster_templates/alchemy/+package+/__init__.py_tmpl @@ -1,5 +1,5 @@ from pyramid.configuration import Configurator -from pramid.settings import asbool +from pyramid.settings import asbool from {{package}}.models import appmaker -- cgit v1.2.3 From 991a26169252e498e8e0576fc6d88514624b72d3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 00:44:33 -0500 Subject: fix test for jython --- pyramid/tests/test_renderers.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 1dab39a6e..4c1971d04 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -137,10 +137,8 @@ class TestTemplateRendererFactory(unittest.TestCase): }) result = self._callFUT(info, factory) self.failUnless(result is renderer) - path = os.path.abspath(__file__) - if path.endswith('pyc'): # pragma: no cover - path = path[:-1] - self.assertEqual(factory.path, path) + path = os.path.abspath(__file__).split('$')[0] # jython + self.failUnless(factory.path.startswith(path)) self.assertEqual(factory.kw, {}) def test_reload_resources_true(self): -- cgit v1.2.3 From e6e0741dbfd90a8d6006bc195bfb5bdf8492ecfe Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 01:28:14 -0500 Subject: make test pass on jython --- pyramid/tests/test_authentication.py | 2 +- pyramid/tests/test_renderers.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index 8bae18fba..69762fdb0 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -411,7 +411,7 @@ class TestAuthTktCookieHelper(unittest.TestCase): def test_identify_cookie_reissue(self): import time - plugin = self._makeOne('secret', timeout=5, reissue_time=0) + plugin = self._makeOne('secret', timeout=5000, reissue_time=0) plugin.auth_tkt.timestamp = time.time() request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=bogus'}) result = plugin.identify(request) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 4c1971d04..102a23f92 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -138,6 +138,8 @@ class TestTemplateRendererFactory(unittest.TestCase): result = self._callFUT(info, factory) self.failUnless(result is renderer) path = os.path.abspath(__file__).split('$')[0] # jython + if path.endswith('.pyc'): + path = path[:-1] self.failUnless(factory.path.startswith(path)) self.assertEqual(factory.kw, {}) -- cgit v1.2.3 From bfee0aa99963ec88ccb9cdf0b41f40e72ee371e4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 01:33:29 -0500 Subject: fix for jython --- pyramid/path.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyramid/path.py b/pyramid/path.py index 2b557af5f..10647c073 100644 --- a/pyramid/path.py +++ b/pyramid/path.py @@ -44,7 +44,8 @@ def package_of(pkg_or_module): def caller_package(level=2, caller_module=caller_module): # caller_module in arglist for tests module = caller_module(level+1) - if '__init__.py' in getattr(module, '__file__', ''): # empty at >>> + f = getattr(module, '__file__', '') + if (('__init__.py' in f) or ('__init__$py' in f)): # empty at >>> # Module is a package return module # Go up one level to get package -- cgit v1.2.3 From 03331655743a4826eaec56986720b9fa98c9ad13 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 02:06:36 -0500 Subject: gardening --- TODO.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO.txt b/TODO.txt index 759b9bb70..ded470d78 100644 --- a/TODO.txt +++ b/TODO.txt @@ -118,4 +118,7 @@ Configurator.add_translation_dirs: not passed any context but a message, can't credibly be removed. +- Stop using Twill in integration tests (too much of a pain in the ass to + make work without deprecation warnings). +- Send patch to Ian for pastescript so it works on Jython. -- cgit v1.2.3 From 4f8c69f2ce04b5cb02b07c3891180cb46abd6aa2 Mon Sep 17 00:00:00 2001 From: d2m Date: Wed, 17 Nov 2010 19:02:51 +0100 Subject: paster templates now use the name "main" to represent the function that returns a WSGI application --- docs/tutorials/gae/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/gae/index.rst b/docs/tutorials/gae/index.rst index a2b190a31..9c8e8c07e 100644 --- a/docs/tutorials/gae/index.rst +++ b/docs/tutorials/gae/index.rst @@ -72,13 +72,13 @@ system. #. Edit ``config.py`` Edit the ``APP_NAME`` and ``APP_ARGS`` settings within - ``config.py``. The ``APP_NAME`` must be ``pyramidapp:app``, and + ``config.py``. The ``APP_NAME`` must be ``pyramidapp:main``, and the APP_ARGS must be ``({},)``. Any other settings in ``config.py`` should remain the same. .. code-block:: python - APP_NAME = 'pyramidapp:app' + APP_NAME = 'pyramidapp:main' APP_ARGS = ({},) #. Edit ``runner.py`` -- cgit v1.2.3 From 06c20074f0e3e624ba69ed6b6e4d0b17649ce9e6 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Wed, 17 Nov 2010 20:05:16 +0200 Subject: ReStructuredText fix in docstring of view_config. --- pyramid/view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/view.py b/pyramid/view.py index ee2774aca..2ac51406e 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -177,7 +177,7 @@ class view_config(object): :class:`pyramid.view.bfg_view`. The following arguments are supported as arguments to - :class:`pyramid.view.view_config``: ``context``, ``permission``, + :class:`pyramid.view.view_config`: ``context``, ``permission``, ``name``, ``request_type``, ``route_name``, ``request_method``, ``request_param``, ``containment``, ``xhr``, ``accept``, ``header`` and ``path_info``. -- cgit v1.2.3 From 8c6a4cea3ed0e588ffa395a99859cb1ac780360f Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Wed, 17 Nov 2010 20:38:00 +0200 Subject: More ReStructuredText fixes in docstrings. (After a recursive grep for ':[a-z]*:`[A-Z0-9a-z._]*``') --- docs/narr/hybrid.rst | 2 +- pyramid/configuration.py | 2 +- pyramid/interfaces.py | 2 +- pyramid/testing.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 61ac68d5d..b89d10c9f 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -358,7 +358,7 @@ Using the ``traverse`` Argument In a Route Definition Rather than using the ``*traverse`` remainder marker in a pattern, you can use the ``traverse`` argument to the -:meth:`pyramid.configuration.Configurator.add_route`` method. +:meth:`pyramid.configuration.Configurator.add_route` method. When you use the ``*traverse`` remainder marker, the traversal path is limited to being the remainder segments of a request URL when a route diff --git a/pyramid/configuration.py b/pyramid/configuration.py index 3d1530406..3f959aabf 100644 --- a/pyramid/configuration.py +++ b/pyramid/configuration.py @@ -1559,7 +1559,7 @@ class Configurator(object): By default, ``categories`` is ``None`` which will execute *all* Venusian decorator callbacks including :app:`Pyramid`-related decorators such as - :class:`pyramid.view.view_config``. If this is not desirable + :class:`pyramid.view.view_config`. If this is not desirable because the codebase has other Venusian-using decorators that aren't meant to be invoked during a particular scan, use ``('pyramid',)`` as a ``categories`` value to limit the execution diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 47bccf71f..9b895e020 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -166,7 +166,7 @@ class IRequestFactory(Interface): def blank(path): """ Return an empty request object (see - :meth:`pyramid.request.Request.blank``)""" + :meth:`pyramid.request.Request.blank`)""" class IViewClassifier(Interface): """ *Internal only* marker interface for views.""" diff --git a/pyramid/testing.py b/pyramid/testing.py index deb6c8d8e..c6c999147 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -119,7 +119,7 @@ def registerTemplateRenderer(path, renderer=None): .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. Instead use the - :meth:`pyramid.configuration.Configurator.testing_add_template`` + :meth:`pyramid.configuration.Configurator.testing_add_template` method in your unit and integration tests. """ @@ -151,7 +151,7 @@ def registerView(name, result='', view=None, for_=(Interface, Interface), .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. Instead use the - :meth:`pyramid.configuration.Configurator.add_view`` + :meth:`pyramid.configuration.Configurator.add_view` method in your unit and integration tests. """ for_ = (IViewClassifier, ) + for_ -- cgit v1.2.3 From 54cf7cb2572f43bc70cfb9f7c156095de68d41e6 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Wed, 17 Nov 2010 21:07:02 +0200 Subject: Make 'make -C docs html' check out the pylons sphinx theme, if needed. --- docs/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 768efb9df..b74c55bd5 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -25,7 +25,7 @@ help: clean: -rm -rf _build/* -html: +html: _themes/ mkdir -p _build/html _build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html @echo @@ -47,7 +47,7 @@ pickle: web: pickle -htmlhelp: +htmlhelp: _themes mkdir -p _build/htmlhelp _build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp @echo @@ -83,3 +83,6 @@ epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) _build/epub @echo @echo "Build finished. The epub file is in _build/epub." + +_themes: + git clone git://github.com/Pylons/pylons_sphinx_theme.git _themes -- cgit v1.2.3 From 851957066a91278089b9a58f7493b0d1fb2903c6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 14:12:05 -0500 Subject: note marius' contributions --- docs/copyright.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/copyright.rst b/docs/copyright.rst index 64a0f819b..fa564a785 100644 --- a/docs/copyright.rst +++ b/docs/copyright.rst @@ -49,7 +49,8 @@ Attributions ------------ Contributors: - Ben Bangert, Blaise Laflamme, Carlos de la Guardia, Paul Everitt + Ben Bangert, Blaise Laflamme, Carlos de la Guardia, Paul Everitt, + Marius Gedminas .. Cover Designer: .. Nat Hardwick of `Electrosoup `_. -- cgit v1.2.3 From c7342c556303462fcdac54430be80a4d814e7869 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 15:22:06 -0500 Subject: gardening --- TODO.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index ded470d78..e7f8b2d92 100644 --- a/TODO.txt +++ b/TODO.txt @@ -121,4 +121,5 @@ - Stop using Twill in integration tests (too much of a pain in the ass to make work without deprecation warnings). -- Send patch to Ian for pastescript so it works on Jython. +- Use ``@register_view`` instead of ``@view_config`` and change view docs to + use "view registration" instead of "view configuration". -- cgit v1.2.3 From cb96e27f0a4c0bf730c5dfdd5eb7c0c8420e3c7d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 17:26:20 -0500 Subject: - Removed ``zodbsessions`` tutorial chapter. It's still useful, but we now have a SessionFactory abstraction which competes with it, and maintaining documentation on both ways to do it is a distraction. --- CHANGES.txt | 7 ++ docs/index.rst | 1 - docs/latexindex.rst | 1 - docs/tutorials/zodbsessions/index.rst | 189 ---------------------------------- 4 files changed, 7 insertions(+), 191 deletions(-) delete mode 100644 docs/tutorials/zodbsessions/index.rst diff --git a/CHANGES.txt b/CHANGES.txt index c775bd422..7f1390186 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -28,6 +28,13 @@ Deprecations ``settings`` attribute of the registry available from the request (``request.registry.settings``). +Documentation +------------- + +- Removed ``zodbsessions`` tutorial chapter. It's still useful, but we now + have a SessionFactory abstraction which competes with it, and maintaining + documentation on both ways to do it is a distraction. + 1.0a3 (2010-11-16) ================== diff --git a/docs/index.rst b/docs/index.rst index 4efb25dde..bfe956af2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -80,7 +80,6 @@ applications to various platforms. tutorials/gae/index.rst tutorials/modwsgi/index.rst tutorials/zeo/index.rst - tutorials/zodbsessions/index.rst tutorials/catalog/index.rst Reference Material diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 4efb193bd..388297de7 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -71,7 +71,6 @@ Tutorials tutorials/gae/index.rst tutorials/modwsgi/index.rst tutorials/zeo/index.rst - tutorials/zodbsessions/index.rst tutorials/catalog/index.rst .. _api_reference: diff --git a/docs/tutorials/zodbsessions/index.rst b/docs/tutorials/zodbsessions/index.rst deleted file mode 100644 index 9582e5de4..000000000 --- a/docs/tutorials/zodbsessions/index.rst +++ /dev/null @@ -1,189 +0,0 @@ -.. _zodb_sessions: - -Using ZODB-Based Sessions -========================= - -Sessions are server-side namespaces which are associated with a site -user that expire automatically after some period of disuse. - -If your application is ZODB-based (e.g. you've created an application -from the ``bfg_zodb`` paster template, or you've followed the -instructions in :ref:`zodb_with_zeo`), you can make use of the -``repoze.session`` and ``repoze.browserid`` packages to add -sessioning to your application. - -.. note:: You can use the ``repoze.session`` package even if your - application is not ZODB-based, but its backing store requires ZODB, - so it makes the most sense to use this package if your application - already uses ZODB. This tutorial does not cover usage of - ``repoze.session``-based sessions in applications that don't - already use ZODB. For this, see `the standalone repoze.session - usage documentation `_. - If you don't want to use ZODB to do sessioning, you might choose to - use a relational/filestorage sessioning system such as `Beaker - `_. :app:`Pyramid` is fully - compatible with this system too. - -Installing Dependencies ------------------------ - -#. Edit your :app:`Pyramid` application's ``setup.py`` file, adding - the following packages to the ``install_requires`` of the - application: - - - ``repoze.session`` - - - ``repoze.browserid`` - - For example, the relevant portion of your application's - ``setup.py`` file might look like so when you're finished adding - the dependencies. - - .. code-block:: python - :linenos: - - setup( - # ... other elements left out for brevity - install_requires=[ - 'pyramid', - 'repoze.folder', - 'repoze.retry', - 'repoze.tm2', - 'repoze.zodbconn', - 'repoze.session' - 'repoze.browserid', - ], - # ... other elements left out for brevity - ) - -#. Rerun your application's ``setup.py`` file (e.g. using ``python - setup.py develop``) to get these packages installed. - -Configuration -------------- - -#. Edit your application's Paste ``.ini`` file. - - If you already have an ``app`` section in the ``.ini`` file named - ``main``, rename this section to ``myapp`` (e.g. ``app:main`` -> - ``app:myapp``). Add a key to it named ``zodb_uri``, e.g. - - .. code-block:: python - :linenos: - - [app:myapp] - use = egg:myapp#app - zodb_uri = zeo://%(here)s/zeo.sock - reload_templates = true - debug_authorization = false - debug_notfound = false - - Add a ``filter`` section to the ``.ini`` file named "browserid": - - .. code-block:: python - :linenos: - - [filter:browserid] - use = egg:repoze.browserid#browserid - secret_key = my-secret-key - - Replace ``my-secret-key`` with any random string. This string - represents the value which the client-side "browser id" cookie is - encrypted with, to prevent tampering. - - If a ``pipeline`` named ``main`` does not already exist in the - paste ``.ini`` file , add a ``pipeline`` section named ``main``. - Put the names ``connector``, ``egg:repoze.retry#retry``, and - ``egg:repoze.tm2#tm`` to the top of the pipeline. - - .. code-block:: python - :linenos: - - [pipeline:main] - pipeline = - browserid - egg:repoze.retry#retry - egg:repoze.tm2#tm - myapp - - When you're finished, your ``.ini`` file might look like so: - - .. code-block:: ini - :linenos: - - [DEFAULT] - debug = true - - [app:myapp] - use = egg:myapp#app - zodb_uri = zeo://%(here)s/zeo.sock - reload_templates = true - debug_authorization = false - debug_notfound = false - - [filter:browserid] - use = egg:repoze.browserid#browserid - secret_key = my-secret-key - - [pipeline:main] - pipeline = - browserid - egg:repoze.retry#retry - egg:repoze.tm2#tm - myapp - - [server:main] - use = egg:Paste#http - host = 0.0.0.0 - port = 6543 - - See :ref:`MyProject_ini` for more information about project Paste - ``.ini`` files. - -#. Add a ``get_session`` API to your application. I've chosen to add - it directly to my ``views.py`` file, although it can live anywhere. - - .. code-block:: python - :linenos: - - from repoze.session.manager import SessionDataManager - from pyramid.traversal import find_root - - def get_session(context, request): - root = find_root(context) - if not hasattr(root, '_sessions'): - root._sessions = SessionDataManager(3600, 5) - session = root._sessions.get(request.environ['repoze.browserid']) - return session - - Note in the call to ``SessionDataManager`` that '3600' represents - the disuse timeout (60 minutes == 3600 seconds), and '5' represents - a write granularity time (the session will be marked as active at - most every five seconds). Vary these values as necessary. - -#. Whenever you want to use a session in your application, call this API: - - .. code-block:: python - :linenos: - - from repoze.session.manager import SessionDataManager - from pyramid.traversal import find_root - from pyramid.chameleon_zpt import render_template_to_response - - def my_view(context, request): - session = get_session(context, request) - session['abc'] = '123' - return render_template_to_response('templates/mytemplate.pt', - request = request, - project = 'sess') - - def get_session(context, request): - root = find_root(context) - if not hasattr(root, '_sessions'): - root._sessions = SessionDataManager(3600, 5) - session = root._sessions.get(request.environ['repoze.browserid']) - return session - -For more information, see the `repoze.session documentation -`_ and the `repoze.browserid -documentation `_. -- cgit v1.2.3 From ab1b77143424c73bf126126d1bc5ceecdbf05ddb Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 17:27:21 -0500 Subject: gardening --- TODO.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index e7f8b2d92..03e42e438 100644 --- a/TODO.txt +++ b/TODO.txt @@ -77,9 +77,6 @@ - RendererHelper -> RendererInfo? -- Do something about ZODB session chapter: either remove or create a - pyramid_zodbsessions package. - - translationdir ZCML directive use of ``path_spec`` should maybe die. - Option for route_url to omit the host and port (perhaps a different -- cgit v1.2.3 From dbaa08e18d1bf50264faabb6e7dfce12f2c0ea71 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 18:11:48 -0500 Subject: - Replace Twill with WebTest in internal integration tests (avoid deprecation warnings generated by Twill). --- CHANGES.txt | 6 + TODO.txt | 3 - pyramid/tests/test_integration.py | 321 ++++++++++++++++++++------------------ setup.py | 4 +- 4 files changed, 174 insertions(+), 160 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7f1390186..fd0cead61 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -35,6 +35,12 @@ Documentation have a SessionFactory abstraction which competes with it, and maintaining documentation on both ways to do it is a distraction. +Internal +-------- + +- Replace Twill with WebTest in internal integration tests (avoid deprecation + warnings generated by Twill). + 1.0a3 (2010-11-16) ================== diff --git a/TODO.txt b/TODO.txt index 03e42e438..d8160eb67 100644 --- a/TODO.txt +++ b/TODO.txt @@ -115,8 +115,5 @@ Configurator.add_translation_dirs: not passed any context but a message, can't credibly be removed. -- Stop using Twill in integration tests (too much of a pain in the ass to - make work without deprecation warnings). - - Use ``@register_view`` instead of ``@view_config`` and change view docs to use "view registration" instead of "view configuration". diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index bc9d75d33..a502c2ff6 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -65,197 +65,208 @@ class TestStaticApp(unittest.TestCase): result.body, open(os.path.join(here, 'fixtures/minimal.pt'), 'r').read()) -class TwillBase(unittest.TestCase): +class IntegrationBase(unittest.TestCase): root_factory = None + ## def setUp(self): + ## import sys + ## import twill + ## from twill.commands import config as twillconfig + ## # for benefit of Jython, which cannot import the subprocess module, we + ## # configure twill to not use tidy + ## twillconfig('use_tidy', False) + ## twillconfig('require_tidy', False) + ## from pyramid.configuration import Configurator + ## config = Configurator(root_factory=self.root_factory) + ## config.load_zcml(self.config) + ## twill.add_wsgi_intercept('localhost', 6543, config.make_wsgi_app) + ## if sys.platform is 'win32': # pragma: no cover + ## out = open('nul:', 'wb') + ## else: + ## out = open('/dev/null', 'wb') + ## twill.set_output(out) + ## self.config = testing.setUp(registry=config.registry) + + ## def tearDown(self): + ## import twill + ## import twill.commands + ## twill.commands.reset_browser() + ## twill.remove_wsgi_intercept('localhost', 6543) + ## twill.set_output(None) + ## testing.tearDown() + def setUp(self): - import sys - import twill - from twill.commands import config as twillconfig - # for benefit of Jython, which cannot import the subprocess module, we - # configure twill to not use tidy - twillconfig('use_tidy', False) - twillconfig('require_tidy', False) from pyramid.configuration import Configurator config = Configurator(root_factory=self.root_factory) + config.begin() config.load_zcml(self.config) - twill.add_wsgi_intercept('localhost', 6543, config.make_wsgi_app) - if sys.platform is 'win32': # pragma: no cover - out = open('nul:', 'wb') - else: - out = open('/dev/null', 'wb') - twill.set_output(out) - self.config = testing.setUp(registry=config.registry) + app = config.make_wsgi_app() + from webtest import TestApp + self.testapp = TestApp(app) + self.config = config def tearDown(self): - import twill - import twill.commands - twill.commands.reset_browser() - twill.remove_wsgi_intercept('localhost', 6543) - twill.set_output(None) - testing.tearDown() - -class TestFixtureApp(TwillBase): + self.config.end() + +class TestFixtureApp(IntegrationBase): config = 'pyramid.tests.fixtureapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/another.html') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'fixture') - browser.go('http://localhost:6543') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'fixture') - browser.go('http://localhost:6543/dummyskin.html') - self.assertEqual(browser.get_code(), 404) - browser.go('http://localhost:6543/error.html') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed') - browser.go('http://localhost:6543/protected.html') - self.assertEqual(browser.get_code(), 401) - -class TestCCBug(TwillBase): + def test_another(self): + res = self.testapp.get('/another.html', status=200) + self.assertEqual(res.body, 'fixture') + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertEqual(res.body, 'fixture') + + def test_dummyskin(self): + self.testapp.get('/dummyskin.html', status=404) + + def test_error(self): + res = self.testapp.get('/error.html', status=200) + self.assertEqual(res.body, 'supressed') + + def test_protected(self): + self.testapp.get('/protected.html', status=401) + +class TestCCBug(IntegrationBase): # "unordered" as reported in IRC by author of # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ config = 'pyramid.tests.ccbugapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/licenses/1/v1/rdf') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'rdf') - browser.go('http://localhost:6543/licenses/1/v1/juri') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'juri') - -class TestHybridApp(TwillBase): + def test_rdf(self): + res = self.testapp.get('/licenses/1/v1/rdf', status=200) + self.assertEqual(res.body, 'rdf') + + def test_juri(self): + res = self.testapp.get('/licenses/1/v1/juri', status=200) + self.assertEqual(res.body, 'juri') + +class TestHybridApp(IntegrationBase): # make sure views registered for a route "win" over views registered # without one, even though the context of the non-route view may # be more specific than the route view. config = 'pyramid.tests.hybridapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'global') - browser.go('http://localhost:6543/abc') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'route') - browser.go('http://localhost:6543/def') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'route2') - browser.go('http://localhost:6543/ghi') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'global') - browser.go('http://localhost:6543/jkl') - self.assertEqual(browser.get_code(), 404) - browser.go('http://localhost:6543/mno/global2') - self.assertEqual(browser.get_code(), 404) - browser.go('http://localhost:6543/pqr/global2') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'global2') - browser.go('http://localhost:6543/error') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed') - browser.go('http://localhost:6543/error2') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed2') - browser.go('http://localhost:6543/error_sub') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed2') - -class TestRestBugApp(TwillBase): + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertEqual(res.body, 'global') + + def test_abc(self): + res = self.testapp.get('/abc', status=200) + self.assertEqual(res.body, 'route') + + def test_def(self): + res = self.testapp.get('/def', status=200) + self.assertEqual(res.body, 'route2') + + def test_ghi(self): + res = self.testapp.get('/ghi', status=200) + self.assertEqual(res.body, 'global') + + def test_jkl(self): + self.testapp.get('/jkl', status=404) + + def test_mno(self): + self.testapp.get('/mno', status=404) + + def test_pqr_global2(self): + res = self.testapp.get('/pqr/global2', status=200) + self.assertEqual(res.body, 'global2') + + def test_error(self): + res = self.testapp.get('/error', status=200) + self.assertEqual(res.body, 'supressed') + + def test_error2(self): + res = self.testapp.get('/error2', status=200) + self.assertEqual(res.body, 'supressed2') + + def test_error_sub(self): + res = self.testapp.get('/error_sub', status=200) + self.assertEqual(res.body, 'supressed2') + +class TestRestBugApp(IntegrationBase): # test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515) config = 'pyramid.tests.restbugapp:configure.zcml' def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/pet') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'gotten') + res = self.testapp.get('/pet', status=200) + self.assertEqual(res.body, 'gotten') -class TestViewDecoratorApp(TwillBase): +class TestViewDecoratorApp(IntegrationBase): config = 'pyramid.tests.viewdecoratorapp:configure.zcml' - def test_it(self): - # we use mako here instead of chameleon because it works on Jython + def _configure_mako(self): tmpldir = os.path.join(os.path.dirname(__file__), 'viewdecoratorapp', 'views') self.config.registry.settings['mako.directories'] = tmpldir - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/first') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK' in browser.get_html()) - browser.go('http://localhost:6543/second') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK2' in browser.get_html()) + def test_first(self): + # we use mako here instead of chameleon because it works on Jython + self._configure_mako() + res = self.testapp.get('/first', status=200) + self.failUnless('OK' in res.body) + + def test_second(self): + # we use mako here instead of chameleon because it works on Jython + self._configure_mako() + res = self.testapp.get('/second', status=200) + self.failUnless('OK2' in res.body) -class TestViewPermissionBug(TwillBase): +class TestViewPermissionBug(IntegrationBase): # view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html config = 'pyramid.tests.permbugapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/test') - self.assertEqual(browser.get_code(), 200) - self.failUnless('ACLDenied' in browser.get_html()) - browser.go('http://localhost:6543/x') - self.assertEqual(browser.get_code(), 401) - -class TestDefaultViewPermissionBug(TwillBase): + def test_test(self): + res = self.testapp.get('/test', status=200) + self.failUnless('ACLDenied' in res.body) + + def test_x(self): + self.testapp.get('/x', status=401) + +class TestDefaultViewPermissionBug(IntegrationBase): # default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html config = 'pyramid.tests.defpermbugapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/x') - self.assertEqual(browser.get_code(), 401) - self.failUnless('failed permission check' in browser.get_html()) - browser.go('http://localhost:6543/y') - self.assertEqual(browser.get_code(), 401) - self.failUnless('failed permission check' in browser.get_html()) - browser.go('http://localhost:6543/z') - self.assertEqual(browser.get_code(), 200) - self.failUnless('public' in browser.get_html()) + def test_x(self): + res = self.testapp.get('/x', status=401) + self.failUnless('failed permission check' in res.body) + + def test_y(self): + res = self.testapp.get('/y', status=401) + self.failUnless('failed permission check' in res.body) + + def test_z(self): + res = self.testapp.get('/z', status=200) + self.failUnless('public' in res.body) from pyramid.tests.exceptionviewapp.models import AnException, NotAnException excroot = {'anexception':AnException(), 'notanexception':NotAnException()} -class TestExceptionViewsApp(TwillBase): +class TestExceptionViewsApp(IntegrationBase): config = 'pyramid.tests.exceptionviewapp:configure.zcml' root_factory = lambda *arg: excroot - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/') - self.assertEqual(browser.get_code(), 200) - self.failUnless('maybe' in browser.get_html()) - - browser.go('http://localhost:6543/notanexception') - self.assertEqual(browser.get_code(), 200) - self.failUnless('no' in browser.get_html()) - - browser.go('http://localhost:6543/anexception') - self.assertEqual(browser.get_code(), 200) - self.failUnless('yes' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception') - self.assertEqual(browser.get_code(), 200) - self.failUnless('yes' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception2') - self.assertEqual(browser.get_code(), 200) - self.failUnless('yes' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception3') - self.assertEqual(browser.get_code(), 200) - self.failUnless('whoa' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception4') - self.assertEqual(browser.get_code(), 200) - self.failUnless('whoa' in browser.get_html()) + def test_root(self): + res = self.testapp.get('/', status=200) + self.failUnless('maybe' in res.body) + + def test_notanexception(self): + res = self.testapp.get('/notanexception', status=200) + self.failUnless('no' in res.body) + + def test_anexception(self): + res = self.testapp.get('/anexception', status=200) + self.failUnless('yes' in res.body) + + def test_route_raise_exception(self): + res = self.testapp.get('/route_raise_exception', status=200) + self.failUnless('yes' in res.body) + + def test_route_raise_exception2(self): + res = self.testapp.get('/route_raise_exception2', status=200) + self.failUnless('yes' in res.body) + + def test_route_raise_exception3(self): + res = self.testapp.get('/route_raise_exception3', status=200) + self.failUnless('whoa' in res.body) + + def test_route_raise_exception4(self): + res = self.testapp.get('/route_raise_exception4', status=200) + self.failUnless('whoa' in res.body) class DummyContext(object): pass diff --git a/setup.py b/setup.py index b220d2914..c2d11384f 100644 --- a/setup.py +++ b/setup.py @@ -45,10 +45,10 @@ install_requires=[ ] if platform.system() == 'Java': - tests_require = install_requires + ['twill'] + tests_require = install_requires + ['WebTest'] else: tests_require= install_requires + ['Sphinx', 'docutils', 'coverage', - 'twill', 'repoze.sphinx.autointerface'] + 'WebTest', 'repoze.sphinx.autointerface'] if sys.version_info[:2] < (2, 6): install_requires.append('simplejson') -- cgit v1.2.3 From 20fa5619608f55ab85d431de4d806f7f337c5384 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 18:13:21 -0500 Subject: remove unused code --- pyramid/tests/test_integration.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index a502c2ff6..c70985e79 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -7,8 +7,6 @@ from pyramid.view import static from zope.interface import Interface -from pyramid import testing - class INothing(Interface): pass @@ -67,33 +65,6 @@ class TestStaticApp(unittest.TestCase): class IntegrationBase(unittest.TestCase): root_factory = None - ## def setUp(self): - ## import sys - ## import twill - ## from twill.commands import config as twillconfig - ## # for benefit of Jython, which cannot import the subprocess module, we - ## # configure twill to not use tidy - ## twillconfig('use_tidy', False) - ## twillconfig('require_tidy', False) - ## from pyramid.configuration import Configurator - ## config = Configurator(root_factory=self.root_factory) - ## config.load_zcml(self.config) - ## twill.add_wsgi_intercept('localhost', 6543, config.make_wsgi_app) - ## if sys.platform is 'win32': # pragma: no cover - ## out = open('nul:', 'wb') - ## else: - ## out = open('/dev/null', 'wb') - ## twill.set_output(out) - ## self.config = testing.setUp(registry=config.registry) - - ## def tearDown(self): - ## import twill - ## import twill.commands - ## twill.commands.reset_browser() - ## twill.remove_wsgi_intercept('localhost', 6543) - ## twill.set_output(None) - ## testing.tearDown() - def setUp(self): from pyramid.configuration import Configurator config = Configurator(root_factory=self.root_factory) -- cgit v1.2.3 From 2c9d148493aaa977c69e77072466685a3367ad0b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 18:48:42 -0500 Subject: - Add a ``pyramid.url.route_path`` API, allowing folks to generate relative URLs. Calling ``route_path`` is the same as calling ``pyramid.url.route_url`` with the argument ``_app_url`` equal to the empty string. - Add a ``pyramid.request.Request.route_path`` API. This is a convenience method of the request which calls ``pyramid.url.route_url``. --- CHANGES.txt | 11 +++++++++++ TODO.txt | 5 ----- docs/api/url.rst | 2 ++ pyramid/request.py | 43 ++++++++++++++++++++++++++++++++++++++++++- pyramid/tests/test_request.py | 17 +++++++++++++++++ pyramid/tests/test_url.py | 21 +++++++++++++++++++++ pyramid/url.py | 27 +++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index fd0cead61..604f28cf4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,17 @@ Next release ============ +Features +-------- + +- Add a ``pyramid.url.route_path`` API, allowing folks to generate relative + URLs. Calling ``route_path`` is the same as calling + ``pyramid.url.route_url`` with the argument ``_app_url`` equal to the empty + string. + +- Add a ``pyramid.request.Request.route_path`` API. This is a convenience + method of the request which calls ``pyramid.url.route_url``. + Bug Fixes --------- diff --git a/TODO.txt b/TODO.txt index d8160eb67..def6fe687 100644 --- a/TODO.txt +++ b/TODO.txt @@ -44,8 +44,6 @@ action = '^foo$' mypackage.views.MyView.foo_GET -- Ability to use configurator as a context manager. - - Provide a response_cookies attribute on the request for rendered responses that can be used as input to response.set_cookie. @@ -79,9 +77,6 @@ - translationdir ZCML directive use of ``path_spec`` should maybe die. -- Option for route_url to omit the host and port (perhaps a different - function named ``route_path``). - - SQLAlchemy idiomatics: mcdonc: those paster templates all look pretty good... the diff --git a/docs/api/url.rst b/docs/api/url.rst index 71987498a..8c702a3fb 100644 --- a/docs/api/url.rst +++ b/docs/api/url.rst @@ -9,6 +9,8 @@ .. autofunction:: route_url + .. autofunction:: route_path + .. autofunction:: static_url .. autofunction:: urlencode diff --git a/pyramid/request.py b/pyramid/request.py index dff70d93c..43a4a3aa2 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -11,6 +11,7 @@ from pyramid.decorator import reify from pyramid.url import model_url from pyramid.url import route_url from pyramid.url import static_url +from pyramid.url import route_path class TemplateContext(object): pass @@ -246,13 +247,53 @@ class Request(WebobRequest): like this:: from pyramid.url import static_url - static_url('mypackage:static/foo.css, request) + static_url('mypackage:static/foo.css', request) See :func:`pyramid.url.static_url` for more information """ return static_url(path, self, **kw) + def route_path(self, route_name, *elements, **kw): + """Generates a path (aka a 'relative URL', a URL minus the host, + scheme, and port) for a named :app:`Pyramid` + :term:`route configuration`. + + .. note:: Calling :meth:`pyramid.Request.route_path` can be used to + achieve the same result as :func:`pyramid.url.route_path`. + + This is a convenience method. The result of calling + :meth:`pyramid.request.Request.route_path` is the same as calling + :func:`pyramid.url.route_path` with an explicit ``request`` + parameter. + + This method accepts the same arguments as + :meth:`pyramid.request.Request.route_url` and performs the same duty. + It just omits the host, port, and scheme information in the return + value; only the path, query parameters, and anchor data are present + in the returned string. + + The :meth:`pyramid.request.Request.route_path` method calls the + :func:`pyramid.url.route_path` function using the Request object as + the ``request`` argument. The ``*elements`` and ``*kw`` arguments + passed to :meth:`pyramid.request.Request.route_path` are passed + through to :func:`pyramid.url.route_path` unchanged and its result is + returned. + + This call to :meth:`pyramid.request.Request.route_path`:: + + request.route_path('foobar') + + Is completely equivalent to calling :func:`pyramid.url.route_path` + like this:: + + from pyramid.url import route_path + route_path('foobar', request) + + See :func:`pyramid.url.route_path` for more information + """ + return route_path(route_name, self, *elements, **kw) + # override default WebOb "environ['adhoc_attr']" mutation behavior __getattr__ = object.__getattribute__ __setattr__ = object.__setattr__ diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index a398bf3af..ab985694b 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -266,6 +266,23 @@ class TestRequest(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + def test_route_path(self): + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'5432', + 'QUERY_STRING':'la=La%20Pe%C3%B1a', + 'wsgi.url_scheme':'http', + } + from pyramid.interfaces import IRoutesMapper + inst = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + self.config.registry.registerUtility(mapper, IRoutesMapper) + result = inst.route_path('flub', 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=u"foo") + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + def test_static_url(self): from pyramid.interfaces import IStaticURLInfo environ = { diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 332ff3f11..aad969ca7 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -209,6 +209,27 @@ class TestRouteUrl(unittest.TestCase): self.assertEqual(result, 'http://example2.com/1/2/3/a') self.assertEqual(route.kw, {}) # shouldnt have anchor/query +class TestRoutePath(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg, **kw): + from pyramid.url import route_path + return route_path(*arg, **kw) + + def test_with_elements(self): + from pyramid.interfaces import IRoutesMapper + request = _makeRequest() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = self._callFUT('flub', request, 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=u"foo") + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + class TestStaticUrl(unittest.TestCase): def setUp(self): cleanUp() diff --git a/pyramid/url.py b/pyramid/url.py index fa15e6364..fca2582de 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -153,6 +153,33 @@ def route_url(route_name, request, *elements, **kw): return app_url + path + suffix + qs + anchor +def route_path(route_name, request, *elements, **kw): + """Generates a path (aka a 'relative URL', a URL minus the host, scheme, + and port) for a named :app:`Pyramid` :term:`route configuration`. + + .. note:: Calling :meth:`pyramid.Request.route_path` can be used to + achieve the same result as :func:`pyramid.url.route_path`. + + This function accepts the same argument as :func:`pyramid.url.route_url` + and performs the same duty. It just omits the host, port, and scheme + information in the return value; only the path, query parameters, + and anchor data are present in the returned string. + + For example, if you've defined a route named 'foobar' with the path + ``/:foo/:bar``, this call to ``route_path``:: + + route_path('foobar', request, foo='1', bar='2') + + Will return the string ``/1/2``. + + .. note:: Calling ``route_path('route', request)`` is the same as calling + ``route_url('route', request, _app_url='')``. ``route_path`` is, in + fact, implemented in terms of ``route_url`` in just this way. As a + result, passing ``_app_url`` within the ``**kw`` values passed to + ``route_path`` will result in an exception. + """ + return route_url(route_name, request, *elements, _app_url='', **kw) + def model_url(model, request, *elements, **kw): """ Generate a string representing the absolute URL of the ``model`` -- cgit v1.2.3 From 50fb1030b7491d5430d03a71a44e152180f22bc3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 19:00:28 -0500 Subject: suppress deprecation warnings while building docs --- docs/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index b4448b803..81096da3b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,6 +13,9 @@ import sys, os import datetime +import warnings + +warnings.simplefilter('ignore', DeprecationWarning) # skip raw nodes from sphinx.writers.text import TextTranslator -- cgit v1.2.3 From 647815ef5fb2ca795b2d4ceb8f6740acefb7c695 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 19:06:27 -0500 Subject: fix route_url on Jython --- pyramid/url.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyramid/url.py b/pyramid/url.py index fca2582de..76d95689c 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -175,10 +175,11 @@ def route_path(route_name, request, *elements, **kw): .. note:: Calling ``route_path('route', request)`` is the same as calling ``route_url('route', request, _app_url='')``. ``route_path`` is, in fact, implemented in terms of ``route_url`` in just this way. As a - result, passing ``_app_url`` within the ``**kw`` values passed to - ``route_path`` will result in an exception. + result, any ``_app_url`` pass within the ``**kw`` values to + ``route_path`` will be ignored. """ - return route_url(route_name, request, *elements, _app_url='', **kw) + kw['_app_url'] = '' + return route_url(route_name, request, *elements, **kw) def model_url(model, request, *elements, **kw): """ -- cgit v1.2.3 From 8964ac5a6c041430efcc5bc9d40a13a2d472c968 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 19:59:25 -0500 Subject: get rid of extraneous note --- pyramid/request.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyramid/request.py b/pyramid/request.py index 43a4a3aa2..2f9ca5819 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -259,9 +259,6 @@ class Request(WebobRequest): scheme, and port) for a named :app:`Pyramid` :term:`route configuration`. - .. note:: Calling :meth:`pyramid.Request.route_path` can be used to - achieve the same result as :func:`pyramid.url.route_path`. - This is a convenience method. The result of calling :meth:`pyramid.request.Request.route_path` is the same as calling :func:`pyramid.url.route_path` with an explicit ``request`` -- cgit v1.2.3 From 485ef6938f8314567ad49c16589de9e31fac383f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 21:58:55 -0500 Subject: gardening --- TODO.txt | 137 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 60 deletions(-) diff --git a/TODO.txt b/TODO.txt index def6fe687..959f16af9 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,81 @@ :mod:`repoze.bfg` TODOs ======================= +Must-Have (before 1.0) +---------------------- + +- Test on GAE, Jython, PyPy, IronPython. + +- Add docs for httpexceptions module for each webob.exc class that inherits + from WSGIHTTPException. + +- Add a ``handler`` ZCML directive. This implies some slightly dicey + refactoring of the configurator to allow it to generate ZCML + "discriminators" for views and routes. + +- Provide a .flash API on session object. + +- Make default renderer work (renderer registered with no name, which is + active for every view unless the view names a specific renderer). + +- Use ``@register_view`` instead of ``@view_config`` and change view docs to + use "view registration" instead of "view configuration". + +- Remove calls to config.begin()/config.end() from startup config code in + tutorials and paster templates (no longer required). + +- SQLAlchemy idiomatics: + + mcdonc: those paster templates all look pretty good... the + only thing i'd consider is adjusting your config variable names to match + exactly what sqlalchemy uses as parameter names, see here: + http://www.sqlalchemy.org/docs/core/engines.html + + mcdonc: especially in the pylons_sqla ini file, where the db + initialization is mixed in w/ the app config... + + ... i'd use "sqlalchemy.PARAMETER" for all of the sqla + settings, so it could easily be handed to engine_from_config w/o any need + to parse by hand + + mcdonc: in the other ini files, where sqlalchemy is given its + own part, the "sqlalchemy." prefix probably isn't necessary, but matching + the parameter names (e.g. 'url' instead of 'db_string') is still probably + a good idea + +- Non-bwcompat use of threadlocals that need to be documented or ameliorated: + + security.principals_allowed_by_permission + + resource.OverrideProvider._get_overrides: can't credibly be removed, + because it stores an overrideprovider as a module-scope global. + + traversal.traverse: this API is a stepchild, and needs to be changed. + + Configurator.add_translation_dirs: not passed any context but a message, + can't credibly be removed. + +- Better ``config.add_handler`` documentation. + +Should-Have +----------- + +- Create a ``docs`` directory for each paster template. + +- Remove "BFG" from Pyramid-specific environ variables. + +- translationdir ZCML directive use of ``path_spec`` should maybe die. + +- Add CRSF token creation/checking machinery (only "should have" vs. "must + have" because I'm not sure it belongs in Pyramid.. it definitely must exist + in formgen libraries, and *might* belong in Pyramid). + +- Change "Cleaning up After a Request" in the urldispatch chapter to + use ``request.add_response_callback``. + +Nice-to-Have +------------ + - Supply ``X-Vhm-Host`` support. - Basic WSGI documentation (pipeline / app / server). @@ -50,65 +125,7 @@ - Raise an exception when a value in response_headerlist is not a string or decide to encode. -- Change "Cleaning up After a Request" in the urldispatch chapter to - use ``request.add_response_callback``. - -- Update App engine chapter. - -- Browser id? - -- .flash API on session. - -- CRSF token machinery - -- ``add_handler`` documentation. - -- ``handler`` ZCML directive. - -- ``docs`` directory for each paster template. - -- "BFG" in environ variables. - -- Test on GAE, Jython, PyPy, IronPython. - -- Add docs for httpexceptions. - -- RendererHelper -> RendererInfo? - -- translationdir ZCML directive use of ``path_spec`` should maybe die. - -- SQLAlchemy idiomatics: - - mcdonc: those paster templates all look pretty good... the - only thing i'd consider is adjusting your config variable names to match - exactly what sqlalchemy uses as parameter names, see here: - http://www.sqlalchemy.org/docs/core/engines.html - - mcdonc: especially in the pylons_sqla ini file, where the db - initialization is mixed in w/ the app config... - - ... i'd use "sqlalchemy.PARAMETER" for all of the sqla - settings, so it could easily be handed to engine_from_config w/o any need - to parse by hand - - mcdonc: in the other ini files, where sqlalchemy is given its - own part, the "sqlalchemy." prefix probably isn't necessary, but matching - the parameter names (e.g. 'url' instead of 'db_string') is still probably - a good idea - -- Default renderer. +- Update App engine chapter with less creaky directions. -- Non-bwcompat use of threadlocals: +- Add functionality that mocks the behavior of ``repoze.browserid``. - security.principals_allowed_by_permission - - resource.OverrideProvider._get_overrides: can't credibly be removed, - because it stores an overrideprovider as a module-scope global. - - traversal.traverse: this API is a stepchild, and needs to be changed. - - Configurator.add_translation_dirs: not passed any context but a message, - can't credibly be removed. - -- Use ``@register_view`` instead of ``@view_config`` and change view docs to - use "view registration" instead of "view configuration". -- cgit v1.2.3 From 0511437d5250d249accda26ba6435ab737f8c0c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 17 Nov 2010 21:59:21 -0500 Subject: not BFG no mo --- TODO.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.txt b/TODO.txt index 959f16af9..f12dcee73 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,5 @@ -:mod:`repoze.bfg` TODOs -======================= +Pyramid TODOs +============= Must-Have (before 1.0) ---------------------- -- cgit v1.2.3