diff options
| author | Casey Duncan <casey.duncan@gmail.com> | 2010-11-17 22:42:47 -0700 |
|---|---|---|
| committer | Casey Duncan <casey.duncan@gmail.com> | 2010-11-17 22:42:47 -0700 |
| commit | 42247963d8ddf569e0e73040d90bca7c803323c4 (patch) | |
| tree | cbd3779c5f6cace9cd692b5e32328278794636f5 | |
| parent | 05354db0c0351a1f1543c9370c6e639d1fe5d1b5 (diff) | |
| parent | 0511437d5250d249accda26ba6435ab737f8c0c5 (diff) | |
| download | pyramid-42247963d8ddf569e0e73040d90bca7c803323c4.tar.gz pyramid-42247963d8ddf569e0e73040d90bca7c803323c4.tar.bz2 pyramid-42247963d8ddf569e0e73040d90bca7c803323c4.zip | |
Merge https://github.com/Pylons/pyramid
42 files changed, 736 insertions, 514 deletions
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/ diff --git a/CHANGES.txt b/CHANGES.txt index b9f6a69c7..604f28cf4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,63 @@ 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 +--------- + +- 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``. + +- 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 +--------------------------- + +- The ``pyramid.testing.zcml_configure`` API has been removed. It had been + advertised as removed since 1.2a1, but hadn't actually been. + +Deprecations +------------ + +- The ``pyramid.settings.get_settings`` API is now deprecated. Use + ``pyramid.threadlocals.get_current_registry().settings`` instead or use the + ``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. + +Internal +-------- + +- Replace Twill with WebTest in internal integration tests (avoid deprecation + warnings generated by Twill). + +1.0a3 (2010-11-16) +================== + +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. @@ -13,9 +70,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 @@ -1,5 +1,80 @@ -:mod:`repoze.bfg` TODOs -======================= +Pyramid 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: + + <RaFromBRC> 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 + + <RaFromBRC> mcdonc: especially in the pylons_sqla ini file, where the db + initialization is mixed in w/ the app config... + + <RaFromBRC> ... 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 + + <RaFromBRC> 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. @@ -44,94 +119,13 @@ 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. - 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? - -- 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 - function named ``route_path``). - -- SQLAlchemy idiomatics: - - <RaFromBRC> 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 - - <RaFromBRC> mcdonc: especially in the pylons_sqla ini file, where the db - initialization is mixed in w/ the app config... - - <RaFromBRC> ... 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 - - <RaFromBRC> 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. - -- Non-bwcompat use of threadlocals: - - 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. - -- Add deprecation warnings for: - - - Use of chameleon_zpt and chameleon_text templating functions (use - renderer API instead). - - - settings.get_settings - - - zcml.zcml_configure - - - zcml.file_configure - -- Add static_url as method of request. - - - +- Update App engine chapter with less creaky directions. +- Add functionality that mocks the behavior of ``repoze.browserid``. 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 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/docs/conf.py b/docs/conf.py index c2ecb1e8d..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 @@ -73,7 +76,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/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 <http://www.electrosoup.co.uk>`_. 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/narr/environment.rst b/docs/narr/environment.rst index 2aa4064cd..ecf85e464 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/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/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/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`` 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 <http://docs.repoze.org/session/usage.html>`_. - If you don't want to use ZODB to do sessioning, you might choose to - use a relational/filestorage sessioning system such as `Beaker - <http://pypi.python.org/pypi/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 -<http://docs.repoze.org/session/>`_ and the `repoze.browserid -documentation <http://pypi.python.org/pypi/repoze.browserid>`_. diff --git a/pyramid/chameleon_text.py b/pyramid/chameleon_text.py index 1f31f3add..6eb7af4d0 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( + 'get_template', + '(pyramid.chameleon_text.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` 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..5c2d6f70f 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_to_response', + '(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/configuration.py b/pyramid/configuration.py index cee65a982..3f959aabf 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 @@ -1562,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/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: 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 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 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) diff --git a/pyramid/request.py b/pyramid/request.py index 891c33fff..2f9ca5819 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -8,8 +8,10 @@ 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 +from pyramid.url import route_path class TemplateContext(object): pass @@ -220,6 +222,75 @@ 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 ``<static>`` 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) + + 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`. + + 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/settings.py b/pyramid/settings.py index 96ad3336a..64b108421 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_current_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_current_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..c6c999147 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -1,4 +1,5 @@ import copy +import os from zope.configuration.xmlconfig import _clearContext @@ -20,9 +21,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() @@ -121,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. """ @@ -153,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_ @@ -277,7 +275,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 +285,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 @@ -736,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_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_chameleon_text.py b/pyramid/tests/test_chameleon_text.py index a42b92bfa..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): @@ -11,9 +12,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 @@ -58,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() @@ -66,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() @@ -74,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() @@ -83,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() @@ -92,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() @@ -101,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() @@ -109,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() @@ -123,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() @@ -136,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) @@ -147,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) @@ -156,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): @@ -171,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: @@ -188,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 8f0b3f03c..786e96129 100644 --- a/pyramid/tests/test_chameleon_zpt.py +++ b/pyramid/tests/test_chameleon_zpt.py @@ -1,13 +1,18 @@ import unittest from pyramid.testing import cleanUp +from pyramid.testing import skip_on 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 @@ -51,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() @@ -60,6 +66,7 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase): self.assertEqual(result, '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') + @skip_on('java') def test_template_reified(self): minimal = self._getTemplatePath('minimal.pt') lookup = DummyLookup() @@ -68,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() @@ -76,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() @@ -85,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() @@ -94,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() @@ -103,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() @@ -112,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() @@ -133,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) @@ -141,16 +156,11 @@ class RenderTemplateTests(Base, unittest.TestCase): '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') 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) + @skip_on('java') def test_it(self): minimal = self._getTemplatePath('minimal.pt') result = self._callFUT(minimal) @@ -161,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): @@ -176,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: @@ -193,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_integration.py b/pyramid/tests/test_integration.py index e8d119e79..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 @@ -65,192 +63,181 @@ 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 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) - 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): - 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()) - - browser.go('http://localhost:6543/third') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK3' in browser.get_html()) - -class TestViewPermissionBug(TwillBase): + def _configure_mako(self): + tmpldir = os.path.join(os.path.dirname(__file__), 'viewdecoratorapp', + 'views') + self.config.registry.settings['mako.directories'] = tmpldir + + 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(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/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 1dab39a6e..102a23f92 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -137,10 +137,10 @@ 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 = os.path.abspath(__file__).split('$')[0] # jython + if path.endswith('.pyc'): path = path[:-1] - self.assertEqual(factory.path, path) + self.failUnless(factory.path.startswith(path)) self.assertEqual(factory.kw, {}) def test_reload_resources_true(self): diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index d12b47642..ab985694b 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -266,6 +266,41 @@ 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 = { + '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 +358,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 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 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 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/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/tests/viewdecoratorapp/views/templates/foo.pt b/pyramid/tests/viewdecoratorapp/views/templates/foo.mak index 6a2f701b6..6a2f701b6 100644 --- a/pyramid/tests/viewdecoratorapp/views/templates/foo.pt +++ b/pyramid/tests/viewdecoratorapp/views/templates/foo.mak 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'} diff --git a/pyramid/url.py b/pyramid/url.py index b740aaca7..76d95689c 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 @@ -149,6 +153,34 @@ 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, any ``_app_url`` pass within the ``**kw`` values to + ``route_path`` will be ignored. + """ + kw['_app_url'] = '' + return route_url(route_name, request, *elements, **kw) + def model_url(model, request, *elements, **kw): """ Generate a string representing the absolute URL of the ``model`` @@ -157,6 +189,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 +305,9 @@ def static_url(path, request, **kw): :term:`configuration declaration` or the ``<static>`` 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) => 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``. 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: @@ -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') |
