Merge branch 'master' of github.com:Pylons/pyramid
4 files deleted
1 files added
45 files modified
| | |
| | | Next release |
| | | ============ |
| | | |
| | | |
| | | Bug Fixes |
| | | --------- |
| | | |
| | |
| | | HEAD is a variant of GET that omits the body, and WebOb has special support |
| | | to return an empty body when a HEAD is used. |
| | | |
| | | - ``config.set_request_method`` has been introduced to support extending |
| | | - ``config.add_request_method`` has been introduced to support extending |
| | | request objects with arbitrary callables. This method expands on the |
| | | previous ``config.set_request_property`` by supporting methods as well as |
| | | properties. This method now causes less code to be executed at |
| | |
| | | to influence how the sessions are marshalled (by default this is done |
| | | with HMAC+pickle). |
| | | |
| | | - ``pyramid.testing.DummyRequest`` now supports methods supplied by the |
| | | ``pyramid.util.InstancePropertyMixin`` class such as ``set_property``. |
| | | |
| | | - Request properties and methods added via ``config.set_request_property`` or |
| | | ``config.add_request_method`` are now available to tweens. |
| | | |
| | | - Request properties and methods added via ``config.set_request_property`` or |
| | | ``config.add_request_method`` are now available to tweens. |
| | | |
| | | - Request properties and methods added via ``config.set_request_property`` or |
| | | ``config.add_request_method`` are now available in the request object |
| | | returned from ``pyramid.paster.bootstrap``. |
| | | |
| | | - ``request.context`` of environment request during ``bootstrap`` is now the |
| | | root object if a context isn't already set on a provided request. |
| | | |
| | | Deprecations |
| | | ------------ |
| | | |
| | | - The ``pyramid.config.Configurator.set_request_property`` has been |
| | | documentation-deprecated. The method remains usable but the more |
| | | featureful ``pyramid.config.Configurator.set_request_method`` should be |
| | | featureful ``pyramid.config.Configurator.add_request_method`` should be |
| | | used in its place (it has all of the same capabilities but can also extend |
| | | the request object with methods). |
| | | |
| | | Backwards Incompatibilities |
| | | --------------------------- |
| | | |
| | | - The Pyramid router no longer adds the values ``bfg.routes.route`` or |
| | | ``bfg.routes.matchdict`` to the request's WSGI environment dictionary. |
| | | These values were docs-deprecated in ``repoze.bfg`` 1.0 (effectively seven |
| | | minor releases ago). If your code depended on these values, use |
| | | request.matched_route and request.matchdict instead. |
| | | |
| | | - It is no longer possible to pass an environ dictionary directly to |
| | | ``pyramid.traversal.ResourceTreeTraverser.__call__`` (aka |
| | | ``ModelGraphTraverser.__call__``). Instead, you must pass a request |
| | | object. Passing an environment instead of a request has generated a |
| | | deprecation warning since Pyramid 1.1. |
| | | |
| | | - Pyramid will no longer work properly if you use the |
| | | ``webob.request.LegacyRequest`` as a request factory. Instances of the |
| | | LegacyRequest class have a ``request.path_info`` which return a string. |
| | | This Pyramid release assumes that ``request.path_info`` will |
| | | unconditionally be Unicode. |
| | | |
| | | - The functions from ``pyramid.chameleon_zpt`` and ``pyramid.chameleon_text`` |
| | | named ``get_renderer``, ``get_template``, ``render_template``, and |
| | | ``render_template_to_response`` have been removed. These have issued a |
| | | deprecation warning upon import since Pyramid 1.0. Use |
| | | ``pyramid.renderers.get_renderer()``, |
| | | ``pyramid.renderers.get_renderer().implementation()``, |
| | | ``pyramid.renderers.render()`` or ``pyramid.renderers.render_to_response`` |
| | | respectively instead of these functions. |
| | | |
| | | - The ``pyramid.configuration`` module was removed. It had been deprecated |
| | | since Pyramid 1.0 and printed a deprecation warning upon its use. Use |
| | | ``pyramid.config`` instead. |
| | | |
| | | - The ``pyramid.paster.PyramidTemplate`` API was removed. It had been |
| | | deprecated since Pyramid 1.1 and issued a warning on import. If your code |
| | | depended on this, adjust your code to import |
| | | ``pyramid.scaffolds.PyramidTemplate`` instead. |
| | | |
| | | - The ``pyramid.settings.get_settings()`` API was removed. It had been |
| | | printing a deprecation warning since Pyramid 1.0. If your code depended on |
| | | this API, use ``pyramid.threadlocal.get_current_registry().settings`` |
| | | instead or use the ``settings`` attribute of the registry available from |
| | | the request (``request.registry.settings``). |
| | | |
| | | - These APIs from the ``pyramid.testing`` module were removed. They have |
| | | been printing deprecation warnings since Pyramid 1.0: |
| | | |
| | | * ``registerDummySecurityPolicy``, use |
| | | ``pyramid.config.Configurator.testing_securitypolicy`` instead. |
| | | |
| | | * ``registerResources`` (aka ``registerModels``, use |
| | | ``pyramid.config.Configurator.testing_resources`` instead. |
| | | |
| | | * ``registerEventListener``, use |
| | | ``pyramid.config.Configurator.testing_add_subscriber`` instead. |
| | | |
| | | * ``registerTemplateRenderer`` (aka `registerDummyRenderer``), use |
| | | ``pyramid.config.Configurator.testing_add_template`` instead. |
| | | |
| | | * ``registerView``, use ``pyramid.config.Configurator.add_view`` instead. |
| | | |
| | | * ``registerUtility``, use |
| | | ``pyramid.config.Configurator.registry.registerUtility`` instead. |
| | | |
| | | * ``registerAdapter``, use |
| | | ``pyramid.config.Configurator.registry.registerAdapter`` instead. |
| | | |
| | | * ``registerSubscriber``, use |
| | | ``pyramid.config.Configurator.add_subscriber`` instead. |
| | | |
| | | * ``registerRoute``, use |
| | | ``pyramid.config.Configurator.add_route`` instead. |
| | | |
| | | * ``registerSettings``, use |
| | | ``pyramid.config.Configurator.add_settings`` instead. |
| | | |
| | | Documentation |
| | | ------------- |
| | | |
| | | - Added an "Upgrading Pyramid" chapter to the narrative documentation. It |
| | | describes how to cope with deprecations and removals of Pyramid APIs. |
| | | |
| | | Dependencies |
| | | ------------ |
| | | |
| | | - Pyramid now requires WebOb 1.2b3+ (the prior Pyramid release only relied on |
| | | 1.2dev+). This is to ensure that we obtain a version of WebOb that returns |
| | | ``request.path_info`` as text. |
| | | |
| | |
| | | |
| | | - Update App engine chapter with less creaky directions. |
| | | |
| | | - Idea from Zart: |
| | | |
| | | diff --git a/pyramid/paster.py b/pyramid/paster.py |
| | | index b0e4d79..b3bd82a 100644 |
| | | --- a/pyramid/paster.py |
| | | +++ b/pyramid/paster.py |
| | | @@ -8,6 +8,7 @@ from paste.deploy import ( |
| | | from pyramid.compat import configparser |
| | | from logging.config import fileConfig |
| | | from pyramid.scripting import prepare |
| | | +from pyramid.config import Configurator |
| | | |
| | | def get_app(config_uri, name=None, loadapp=loadapp): |
| | | """ Return the WSGI application named ``name`` in the PasteDeploy |
| | | @@ -111,3 +112,10 @@ def bootstrap(config_uri, request=None): |
| | | env['app'] = app |
| | | return env |
| | | |
| | | +def make_pyramid_app(global_conf, app=None, **settings): |
| | | + """Return pyramid application configured with provided settings""" |
| | | + config = Configurator(package='pyramid', settings=settings) |
| | | + if app: |
| | | + config.include(app) |
| | | + app = config.make_wsgi_app() |
| | | + return app |
| | | diff --git a/setup.py b/setup.py |
| | | index 03ebb42..91e0e21 100644 |
| | | --- a/setup.py |
| | | +++ b/setup.py |
| | | @@ -118,6 +118,8 @@ setup(name='pyramid', |
| | | [paste.server_runner] |
| | | wsgiref = pyramid.scripts.pserve:wsgiref_server_runner |
| | | cherrypy = pyramid.scripts.pserve:cherrypy_server_runner |
| | | + [paster.app_factory] |
| | | + main = pyramid.paster:make_pyramid_app |
| | | """ |
| | | ) |
| | | |
| | | |
| | | Future |
| | | ------ |
| | | |
| | | - 1.4: Kill off ``bfg.routes`` envvars in router. |
| | | |
| | | - 1.4: Remove ``chameleon_text`` / ``chameleon_zpt`` deprecated functions |
| | | (render_*) |
| | | |
| | | - 1.4: Remove ``pyramid.configuration`` (deprecated). |
| | | |
| | | - 1.4: Remove ``pyramid.paster.PyramidTemplate`` (deprecated). |
| | | |
| | | - 1.4: Remove ``pyramid.settings.get_settings`` (deprecated). |
| | | |
| | | - 1.5: Remove all deprecated ``pyramid.testing`` functions. |
| | | - 1.5: remove ``pyramid.view.static`` and ``pyramid.view.is_response``. |
| | | |
| | | - 1.5: turn ``pyramid.settings.Settings`` into a function that returns the |
| | | original dict (after ``__getattr__`` deprecation period, it was deprecated |
| | |
| | | |
| | | - 1.5: Remove ``pyramid.requests.DeprecatedRequestMethodsMixin``. |
| | | |
| | | - 1.6: Maybe? deprecate set_request_property in favor of pointing people at |
| | | set_request_method. |
| | | - 1.5: Maybe? deprecate set_request_property in favor of pointing people at |
| | | add_request_method, schedule removal for 1.8? |
| | | |
| | | - 1.6: Remove IContextURL and TraversalContextURL. |
| | | |
| | |
| | | |
| | | api/authorization |
| | | api/authentication |
| | | api/chameleon_text |
| | | api/chameleon_zpt |
| | | api/compat |
| | | api/config |
| | | api/events |
| | |
| | | |
| | | :methodcategory:`Extending the Request Object` |
| | | |
| | | .. automethod:: set_request_method |
| | | .. automethod:: add_request_method |
| | | .. automethod:: set_request_property |
| | | |
| | | :methodcategory:`Using I18N` |
| | |
| | | |
| | | .. automodule:: pyramid.settings |
| | | |
| | | .. autofunction:: get_settings |
| | | |
| | | .. autofunction:: asbool |
| | | |
| | | .. autofunction:: aslist |
| | |
| | | .. _changelog: |
| | | |
| | | :app:`Pyramid` Change History |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | |
| | | narr/advconfig |
| | | narr/extconfig |
| | | narr/scaffolding |
| | | narr/upgrading |
| | | narr/threadlocals |
| | | narr/zca |
| | | |
| | |
| | | |
| | | api/authorization |
| | | api/authentication |
| | | api/chameleon_text |
| | | api/chameleon_zpt |
| | | api/config |
| | | api/events |
| | | api/exceptions |
| | |
| | | :meth:`~pyramid.config.Configurator.add_view`, |
| | | :meth:`~pyramid.config.Configurator.add_route`, |
| | | :meth:`~pyramid.config.Configurator.add_renderer`, |
| | | :meth:`~pyramid.config.Configurator.add_request_method`, |
| | | :meth:`~pyramid.config.Configurator.set_request_factory`, |
| | | :meth:`~pyramid.config.Configurator.set_session_factory`, |
| | | :meth:`~pyramid.config.Configurator.set_request_method`, |
| | | :meth:`~pyramid.config.Configurator.set_request_property`, |
| | | :meth:`~pyramid.config.Configurator.set_root_factory`, |
| | | :meth:`~pyramid.config.Configurator.set_view_mapper`, |
| | |
| | | {'foo':1, 'bar':2}, |
| | | request=request) |
| | | |
| | | .. warning:: |
| | | |
| | | Earlier iterations of this documentation |
| | | (pre-version-1.3) encouraged the application developer to use |
| | | ZPT-specific APIs such as |
| | | :func:`pyramid.chameleon_zpt.render_template_to_response` and |
| | | :func:`pyramid.chameleon_zpt.render_template` to render templates |
| | | directly. This style of rendering still works, but at least for |
| | | purposes of this documentation, those functions are deprecated. |
| | | Application developers are encouraged instead to use the functions |
| | | available in the :mod:`pyramid.renderers` module to perform |
| | | rendering tasks. This set of functions works to render templates |
| | | for all renderer extensions registered with :app:`Pyramid`. |
| | | |
| | | The ``sample_view`` :term:`view callable` function above returns a |
| | | :term:`response` object which contains the body of the |
| | | ``templates/foo.pt`` template. In this case, the ``templates`` |
| | |
| | | .. warning:: |
| | | |
| | | Only :term:`Chameleon` templates support defining a renderer for a |
| | | template relative to the location of the module where the view |
| | | callable is defined. Mako templates, and other templating system |
| | | bindings work differently. In particular, Mako templates use a |
| | | "lookup path" as defined by the ``mako.directories`` configuration |
| | | file instead of treating relative paths as relative to the current |
| | | view module. See :ref:`mako_templates`. |
| | | template relative to the location of the module where the view callable is |
| | | defined. Mako templates, and other templating system bindings work |
| | | differently. In particular, Mako templates use a "lookup path" as defined |
| | | by the ``mako.directories`` configuration file instead of treating |
| | | relative paths as relative to the current view module. See |
| | | :ref:`mako_templates`. |
| | | |
| | | The path can alternately be a :term:`asset specification` in the form |
| | | ``some.dotted.package_name:relative/path``. This makes it possible to |
| | |
| | | .. code-block:: text |
| | | |
| | | Hello, world! |
| | | |
| | | If you'd rather use templates directly within a view callable (without |
| | | the indirection of using a renderer), see :ref:`chameleon_text_module` |
| | | for the API description. |
| | | |
| | | See also :ref:`built_in_renderers` for more general information about |
| | | renderers, including Chameleon text renderers. |
| | |
| | | application is the Python :mod:`unittest` module. Although this module is |
| | | named :mod:`unittest`, it is actually capable of driving both unit and |
| | | integration tests. A good :mod:`unittest` tutorial is available within `Dive |
| | | Into Python <http://diveintopython.nfshost.com/unit_testing/index.html>`_ by Mark |
| | | Into Python <http://www.diveintopython.net/unit_testing/index.html>`_ by Mark |
| | | Pilgrim. |
| | | |
| | | :app:`Pyramid` provides a number of facilities that make unit, integration, |
New file |
| | |
| | | Upgrading Pyramid |
| | | ================= |
| | | |
| | | When a new version of Pyramid is released, it will sometimes deprecate a |
| | | feature or remove a feature that was deprecated in an older release. When |
| | | features are removed from Pyramid, applications that depend on those features |
| | | will begin to break. This chapter explains how to ensure your Pyramid |
| | | applications keep working when you upgrade the Pyramid version you're using. |
| | | |
| | | .. sidebar:: About Release Numbering |
| | | |
| | | Conventionally, application version numbering in Python is described as |
| | | ``major.minor.micro``. If your Pyramid version is "1.2.3", it means |
| | | you're running a version of Pyramid with the major version "1", the minor |
| | | version "2" and the micro version "3". A "major" release is one that |
| | | increments the first-dot number; 2.X.X might follow 1.X.X. A "minor" |
| | | release is one that increments the second-dot number; 1.3.X might follow |
| | | 1.2.X. A "micro" release is one that increments the third-dot number; |
| | | 1.2.3 might follow 1.2.2. In general, micro releases are "bugfix-only", |
| | | and contain no new features, minor releases contain new features but are |
| | | largely backwards compatible with older versions, and a major release |
| | | indicates a large set of backwards incompatibilities. |
| | | |
| | | The Pyramid core team is conservative when it comes to removing features. We |
| | | don't remove features unnecessarily, but we're human, and we make mistakes |
| | | which cause some features to be evolutionary dead ends. Though we are |
| | | willing to support dead-end features for some amount of time, some eventually |
| | | have to be removed when the cost of supporting them outweighs the benefit of |
| | | keeping them around, because each feature in Pyramid represents a certain |
| | | documentation and maintenance burden. |
| | | |
| | | Deprecation and Removal Policy |
| | | ------------------------------ |
| | | |
| | | When a feature is scheduled for removal from Pyramid or any of its official |
| | | add-ons, the core development team takes these steps: |
| | | |
| | | - Using the feature will begin to generate a `DeprecationWarning`, indicating |
| | | the version in which the feature became deprecated. |
| | | |
| | | - A note is added to the documentation indicating that the feature is |
| | | deprecated. |
| | | |
| | | - A note is added to the :ref:`changelog` about the deprecation. |
| | | |
| | | When a deprecated feature is eventually removed: |
| | | |
| | | - The feature is removed. |
| | | |
| | | - A note is added to the :ref:`changelog` about the removal. |
| | | |
| | | Features are never removed in *micro* releases. They are only removed in |
| | | minor and major releases. Deprecated features are kept around for at least |
| | | *three* minor releases from the time the feature became deprecated. |
| | | Therefore, if a feature is added in Pyramid 1.0, but it's deprecated in |
| | | Pyramid 1.1, it will be kept around through all 1.1.X releases, all 1.2.X |
| | | releases and all 1.3.X releases. It will finally be removed in the first |
| | | 1.4.X release. |
| | | |
| | | Sometimes features are "docs-deprecated" instead of formally deprecated. |
| | | This means that the feature will be kept around indefinitely, but it will be |
| | | removed from the documentation or a note will be added to the documentation |
| | | telling folks to use some other newer feature. This happens when the cost of |
| | | keeping an old feature around is very minimal and the support and |
| | | documentation burden is very low. For example, we might rename a function |
| | | that is an API without changing the arguments it accepts. In this case, |
| | | we'll often rename the function, and change the docs to point at the new |
| | | function name, but leave around a backwards compatibility alias to the old |
| | | function name so older code doesn't break. |
| | | |
| | | "Docs deprecated" features tend to work "forever", meaning that they won't be |
| | | removed, and they'll never generate a deprecation warning. However, such |
| | | changes are noted in the :ref:`changelog`, so it's possible to know that you |
| | | should change older spellings to newer ones to ensure that people reading |
| | | your code can find the APIs you're using in the Pyramid docs. |
| | | |
| | | Consulting the Change History |
| | | ----------------------------- |
| | | |
| | | Your first line of defense against application failures caused by upgrading |
| | | to a newer Pyramid release is always to read the :ref:`changelog`. to find |
| | | the deprecations and removals for each release between the release you're |
| | | currently running and the one you wish to upgrade to. The change history |
| | | notes every deprecation within a ``Deprecation`` section and every removal |
| | | within a ``Backwards Incompatibilies`` section for each release. |
| | | |
| | | The change history often contains instructions for changing your code to |
| | | avoid deprecation warnings and how to change docs-deprecated spellings to |
| | | newer ones. You can follow along with each deprecation explanation in the |
| | | change history, simply doing a grep or other code search to your application, |
| | | using the change log examples to remediate each potential problem. |
| | | |
| | | .. _testing_under_new_release: |
| | | |
| | | Testing Your Application Under a New Pyramid Release |
| | | ---------------------------------------------------- |
| | | |
| | | Once you've upgraded your application to a new Pyramid release and you've |
| | | remediated as much as possible by using the change history notes, you'll want |
| | | to run your application's tests (see :ref:`running_tests`) in such a way that |
| | | you can see DeprecationWarnings printed to the console when the tests run. |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ python -Wd setup.py test -q |
| | | |
| | | The ``-Wd`` argument is an argument that tells Python to print deprecation |
| | | warnings to the console. Note that the ``-Wd`` flag is only required for |
| | | Python 2.7 and better: Python versions 2.6 and older print deprecation |
| | | warnings to the console by default. See `the Python -W flag documentation |
| | | <http://docs.python.org/using/cmdline.html#cmdoption-W>`_ for more |
| | | information. |
| | | |
| | | As your tests run, deprecation warnings will be printed to the console |
| | | explaining the deprecation and providing instructions about how to prevent |
| | | the deprecation warning from being issued. For example: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ python -Wd setup.py test -q |
| | | # .. elided ... |
| | | running build_ext |
| | | /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: |
| | | DeprecationWarning: static: The "pyramid.view.static" class is deprecated |
| | | as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with |
| | | the "use_subpath" argument set to True. |
| | | from pyramid.view import static |
| | | . |
| | | ---------------------------------------------------------------------- |
| | | Ran 1 test in 0.014s |
| | | |
| | | OK |
| | | |
| | | In the above case, it's line #3 in the ``myproj.views`` module (``from |
| | | pyramid.view import static``) that is causing the problem: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | from pyramid.view import view_config |
| | | |
| | | from pyramid.view import static |
| | | myview = static('static', 'static') |
| | | |
| | | The deprecation warning tells me how to fix it, so I can change the code to |
| | | do things the newer way: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | from pyramid.view. import view_config |
| | | |
| | | from pyramid.static import static_view |
| | | myview = static_view('static', 'static', use_subpath=True) |
| | | |
| | | When I run the tests again, the deprecation warning is no longer printed to |
| | | my console: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ python -Wd setup.py test -q |
| | | # .. elided ... |
| | | running build_ext |
| | | . |
| | | ---------------------------------------------------------------------- |
| | | Ran 1 test in 0.014s |
| | | |
| | | OK |
| | | |
| | | |
| | | My Application Doesn't Have Any Tests or Has Few Tests |
| | | ------------------------------------------------------ |
| | | |
| | | If your application has no tests, or has only moderate test coverage, running |
| | | tests won't tell you very much, because the Pyramid codepaths that generate |
| | | deprecation warnings won't be executed. |
| | | |
| | | In this circumstance, you can start your application interactively under a |
| | | server run with the ``PYTHONWARNINGS`` environment variable set to |
| | | ``default``. On UNIX, you can do that via: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | $ PYTHONWARNINGS=default bin/pserve development.ini |
| | | |
| | | On Windows, you need to issue two commands: |
| | | |
| | | .. code-block:: bash |
| | | |
| | | C:\> set PYTHONWARNINGS=default |
| | | C:\> Scripts/pserve.exe development.ini |
| | | |
| | | At this point, it's ensured that deprecation warnings will be printed to the |
| | | console whenever a codepath is hit that generates one. You can then click |
| | | around in your application interactively to try to generate them, and |
| | | remediate as explained in :ref:`testing_under_new_release`. |
| | | |
| | | See `the PYTHONWARNINGS environment variable documentation |
| | | <http://docs.python.org/using/cmdline.html#envvar-PYTHONWARNINGS>`_ or `the |
| | | Python -W flag documentation |
| | | <http://docs.python.org/using/cmdline.html#cmdoption-W>`_ for more |
| | | information. |
| | | |
| | | Upgrading to the Very Latest Pyramid Release |
| | | -------------------------------------------- |
| | | |
| | | When you upgrade your application to the very most recent Pyramid release, |
| | | it's advisable to upgrade step-wise through each most recent minor release, |
| | | beginning with the one that you know your application currently runs under, |
| | | and ending on the most recent release. For example, if your application is |
| | | running in production on Pyramid 1.2.1, and the most recent Pyramid 1.3 |
| | | release is Pyramid 1.3.3, and the most recent Pyramid release is 1.4.4, it's |
| | | advisable to do this: |
| | | |
| | | - Upgrade your environment to the most recent 1.2 release. For example, the |
| | | most recent 1.2 release might be 1.2.3, so upgrade to it. Then run your |
| | | application's tests under 1.2.3 as described in |
| | | :ref:`testing_under_new_release`. Note any deprecation warnings and |
| | | remediate. |
| | | |
| | | - Upgrade to the most recent 1.3 release, 1.3.3. Run your application's |
| | | tests, note any deprecation warnings and remediate. |
| | | |
| | | - Upgrade to 1.4.4. Run your application's tests, note any deprecation |
| | | warnings and remediate. |
| | | |
| | | If you skip testing your application under each minor release (for example if |
| | | you upgrade directly from 1.2.1 to 1.4.4), you might miss a deprecation |
| | | warning and waste more time trying to figure out an error caused by a feature |
| | | removal than it would take to upgrade stepwise through each minor release. |
| | | |
| | | |
| | |
| | | It allows :term:`WSGI` programs to be served using the Apache web |
| | | server. |
| | | |
| | | This guide will outline broad steps that can be used to get a |
| | | :app:`Pyramid` application running under Apache via ``mod_wsgi``. |
| | | This particular tutorial was developed under Apple's Mac OS X platform |
| | | (Snow Leopard, on a 32-bit Mac), but the instructions should be |
| | | largely the same for all systems, delta specific path information for |
| | | commands and files. |
| | | This guide will outline broad steps that can be used to get a :app:`Pyramid` |
| | | application running under Apache via ``mod_wsgi``. This particular tutorial |
| | | was developed under Apple's Mac OS X platform (Snow Leopard, on a 32-bit |
| | | Mac), but the instructions should be largely the same for all systems, delta |
| | | specific path information for commands and files. |
| | | |
| | | .. note:: Unfortunately these instructions almost certainly won't work for |
| | | deploying a :app:`Pyramid` application on a Windows system using |
| | |
| | | `logging` module to allow logging within your application. |
| | | See :ref:`logging_config`. |
| | | |
| | | #. Make the ``pyramid.wsgi`` script executable. |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ cd ~/modwsgi/env |
| | | $ chmod 755 pyramid.wsgi |
| | | There is no need to make the ``pyramid.wsgi`` script executable. |
| | | However, you'll need to make sure that *two* users have access to change |
| | | into the ``~/modwsgi/env`` directory: your current user (mine is |
| | | ``chrism`` and the user that Apache will run as often named ``apache`` or |
| | | ``httpd``). Make sure both of these users can "cd" into that directory. |
| | | |
| | | #. Edit your Apache configuration and add some stuff. I happened to |
| | | create a file named ``/etc/apache2/other/modwsgi.conf`` on my own |
| | |
| | | renderer='templates/edit.pt', |
| | | permission='edit') |
| | | def add_page(context, request): |
| | | name = request.subpath[0] |
| | | pagename = request.subpath[0] |
| | | if 'form.submitted' in request.params: |
| | | body = request.params['body'] |
| | | page = Page(body) |
| | | page.__name__ = name |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | context[name] = page |
| | | context[pagename] = page |
| | | return HTTPFound(location = request.resource_url(page)) |
| | | save_url = request.resource_url(context, 'add_page', name) |
| | | save_url = request.resource_url(context, 'add_page', pagename) |
| | | page = Page('') |
| | | page.__name__ = name |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | |
| | | return dict(page = page, save_url = save_url, |
| | |
| | | renderer='templates/edit.pt', |
| | | permission='edit') |
| | | def add_page(context, request): |
| | | name = request.subpath[0] |
| | | pagename = request.subpath[0] |
| | | if 'form.submitted' in request.params: |
| | | body = request.params['body'] |
| | | page = Page(body) |
| | | page.__name__ = name |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | context[name] = page |
| | | context[pagename] = page |
| | | return HTTPFound(location = request.resource_url(page)) |
| | | save_url = request.resource_url(context, 'add_page', name) |
| | | save_url = request.resource_url(context, 'add_page', pagename) |
| | | page = Page('') |
| | | page.__name__ = name |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | |
| | | return dict(page = page, save_url = save_url, |
| | |
| | | @view_config(name='add_page', context='.models.Wiki', |
| | | renderer='templates/edit.pt') |
| | | def add_page(context, request): |
| | | name = request.subpath[0] |
| | | pagename = request.subpath[0] |
| | | if 'form.submitted' in request.params: |
| | | body = request.params['body'] |
| | | page = Page(body) |
| | | page.__name__ = name |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | context[name] = page |
| | | context[pagename] = page |
| | | return HTTPFound(location = request.resource_url(page)) |
| | | save_url = request.resource_url(context, 'add_page', name) |
| | | save_url = request.resource_url(context, 'add_page', pagename) |
| | | page = Page('') |
| | | page.__name__ = name |
| | | page.__name__ = pagename |
| | | page.__parent__ = context |
| | | return dict(page = page, save_url = save_url) |
| | | |
| | |
| | | @view_config(route_name='add_page', renderer='templates/edit.pt', |
| | | permission='edit') |
| | | def add_page(request): |
| | | name = request.matchdict['pagename'] |
| | | pagename = request.matchdict['pagename'] |
| | | if 'form.submitted' in request.params: |
| | | body = request.params['body'] |
| | | page = Page(name, body) |
| | | page = Page(pagename, body) |
| | | DBSession.add(page) |
| | | return HTTPFound(location = request.route_url('view_page', |
| | | pagename=name)) |
| | | save_url = request.route_url('add_page', pagename=name) |
| | | pagename=pagename)) |
| | | save_url = request.route_url('add_page', pagename=pagename) |
| | | page = Page('', '') |
| | | return dict(page=page, save_url=save_url, |
| | | logged_in=authenticated_userid(request)) |
| | |
| | | @view_config(route_name='edit_page', renderer='templates/edit.pt', |
| | | permission='edit') |
| | | def edit_page(request): |
| | | name = request.matchdict['pagename'] |
| | | page = DBSession.query(Page).filter_by(name=name).one() |
| | | pagename = request.matchdict['pagename'] |
| | | page = DBSession.query(Page).filter_by(name=pagename).one() |
| | | if 'form.submitted' in request.params: |
| | | page.data = request.params['body'] |
| | | DBSession.add(page) |
| | | return HTTPFound(location = request.route_url('view_page', |
| | | pagename=name)) |
| | | pagename=pagename)) |
| | | return dict( |
| | | page=page, |
| | | save_url = request.route_url('edit_page', pagename=name), |
| | | save_url = request.route_url('edit_page', pagename=pagename), |
| | | logged_in=authenticated_userid(request), |
| | | ) |
| | | |
| | |
| | | @view_config(route_name='add_page', renderer='templates/edit.pt', |
| | | permission='edit') |
| | | def add_page(request): |
| | | name = request.matchdict['pagename'] |
| | | pagename = request.matchdict['pagename'] |
| | | if 'form.submitted' in request.params: |
| | | session = DBSession() |
| | | body = request.params['body'] |
| | | page = Page(name, body) |
| | | page = Page(pagename, body) |
| | | session.add(page) |
| | | return HTTPFound(location = request.route_url('view_page', |
| | | pagename=name)) |
| | | save_url = request.route_url('add_page', pagename=name) |
| | | pagename=pagename)) |
| | | save_url = request.route_url('add_page', pagename=pagename) |
| | | page = Page('', '') |
| | | return dict(page=page, save_url=save_url, |
| | | logged_in=authenticated_userid(request)) |
| | |
| | | @view_config(route_name='edit_page', renderer='templates/edit.pt', |
| | | permission='edit') |
| | | def edit_page(request): |
| | | name = request.matchdict['pagename'] |
| | | pagename = request.matchdict['pagename'] |
| | | session = DBSession() |
| | | page = session.query(Page).filter_by(name=name).one() |
| | | page = session.query(Page).filter_by(name=pagename).one() |
| | | if 'form.submitted' in request.params: |
| | | page.data = request.params['body'] |
| | | session.add(page) |
| | | return HTTPFound(location = request.route_url('view_page', |
| | | pagename=name)) |
| | | pagename=pagename)) |
| | | return dict( |
| | | page=page, |
| | | save_url = request.route_url('edit_page', pagename=name), |
| | | save_url = request.route_url('edit_page', pagename=pagename), |
| | | logged_in=authenticated_userid(request), |
| | | ) |
| | | |
| | |
| | | |
| | | @view_config(route_name='add_page', renderer='templates/edit.pt') |
| | | def add_page(request): |
| | | name = request.matchdict['pagename'] |
| | | pagename = request.matchdict['pagename'] |
| | | if 'form.submitted' in request.params: |
| | | body = request.params['body'] |
| | | page = Page(name, body) |
| | | page = Page(pagename, body) |
| | | DBSession.add(page) |
| | | return HTTPFound(location = request.route_url('view_page', |
| | | pagename=name)) |
| | | save_url = request.route_url('add_page', pagename=name) |
| | | pagename=pagename)) |
| | | save_url = request.route_url('add_page', pagename=pagename) |
| | | page = Page('', '') |
| | | return dict(page=page, save_url=save_url) |
| | | |
| | | @view_config(route_name='edit_page', renderer='templates/edit.pt') |
| | | def edit_page(request): |
| | | name = request.matchdict['pagename'] |
| | | page = DBSession.query(Page).filter_by(name=name).one() |
| | | pagename = request.matchdict['pagename'] |
| | | page = DBSession.query(Page).filter_by(name=pagename).one() |
| | | if 'form.submitted' in request.params: |
| | | page.data = request.params['body'] |
| | | DBSession.add(page) |
| | | return HTTPFound(location = request.route_url('view_page', |
| | | pagename=name)) |
| | | pagename=pagename)) |
| | | return dict( |
| | | page=page, |
| | | save_url = request.route_url('edit_page', pagename=name), |
| | | save_url = request.route_url('edit_page', pagename=pagename), |
| | | ) |
| | |
| | | import sys |
| | | |
| | | from zope.deprecation import deprecated |
| | | from zope.interface import implementer |
| | | |
| | | from pyramid.compat import reraise |
| | |
| | | |
| | | from pyramid.decorator import reify |
| | | from pyramid import renderers |
| | | from pyramid.path import caller_package |
| | | |
| | | def renderer_factory(info): |
| | | return renderers.template_renderer_factory(info, TextTemplateRenderer) |
| | |
| | | def __init__(self, path, lookup, macro=None): |
| | | self.path = path |
| | | self.lookup = lookup |
| | | # text template renderers have no macros, so we ignore the |
| | | # macro arg |
| | | |
| | | @reify # avoid looking up reload_templates before manager pushed |
| | | def template(self): |
| | |
| | | raise ValueError('renderer was passed non-dictionary as value') |
| | | result = self.template(**system) |
| | | return result |
| | | |
| | | def get_renderer(path): |
| | | """ Return a callable object which can be used to render a |
| | | :term:`Chameleon` text template using the template implied by the |
| | | ``path`` argument. The ``path`` argument may be a |
| | | package-relative path, an absolute path, or a :term:`asset |
| | | specification`. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | | package = caller_package() |
| | | 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. |
| | | The ``path`` argument may be a package-relative path, an absolute |
| | | path, or a :term:`asset specification`. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | the ``implementation()`` method of a template renderer retrieved via |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | | package = caller_package() |
| | | 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 |
| | | package-relative path, an absolute path, or a :term:`asset |
| | | specification`. The arguments in ``*kw`` are passed as top-level |
| | | names to the template, and so may be used within the template |
| | | itself. Returns a string. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render` instead. |
| | | """ |
| | | package = caller_package() |
| | | request = kw.pop('request', None) |
| | | 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 |
| | | package-relative path, an absolute path, or a :term:`asset |
| | | specification`. The arguments in ``*kw`` are passed as top-level |
| | | names to the template, and so may be used within the template |
| | | itself. Returns a :term:`Response` object with the body as the |
| | | template result. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render_to_response` instead. |
| | | """ |
| | | package = caller_package() |
| | | 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)') |
| | | |
| | |
| | | import sys |
| | | |
| | | from zope.deprecation import deprecated |
| | | from zope.interface import implementer |
| | | |
| | | from pyramid.compat import reraise |
| | |
| | | from pyramid.interfaces import ITemplateRenderer |
| | | |
| | | from pyramid.decorator import reify |
| | | from pyramid.path import caller_package |
| | | from pyramid import renderers |
| | | |
| | | def renderer_factory(info): |
| | |
| | | result = self.template(**system) |
| | | return result |
| | | |
| | | def get_renderer(path): |
| | | """ Return a callable object which can be used to render a |
| | | :term:`Chameleon` ZPT template using the template implied by the |
| | | ``path`` argument. The ``path`` argument may be a |
| | | package-relative path, an absolute path, or a :term:`asset |
| | | specification`. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | | package = caller_package() |
| | | 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. |
| | | The ``path`` argument may be a package-relative path, an absolute |
| | | path, or a :term:`asset specification`. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | the ``implementation()`` method of a template renderer retrieved via |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | | package = caller_package() |
| | | 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 |
| | | package-relative path, an absolute path, or a :term:`asset |
| | | specification`. The arguments in ``*kw`` are passed as top-level |
| | | names to the template, and so may be used within the template |
| | | itself. Returns a string. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render` instead. |
| | | """ |
| | | package = caller_package() |
| | | request = kw.pop('request', None) |
| | | 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 |
| | | package-relative path, an absolute path, or a :term:`asset |
| | | specification`. The arguments in ``*kw`` are passed as top-level |
| | | names to the template, and so may be used within the template |
| | | itself. Returns a :term:`Response` object with the body as the |
| | | template result. |
| | | |
| | | .. warning:: |
| | | |
| | | This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render_to_response` instead. |
| | | """ |
| | | package = caller_package() |
| | | 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)') |
| | |
| | | :class:`pyramid.request.Request` class (particularly |
| | | ``__call__``, and ``blank``). |
| | | |
| | | See :meth:`pyramid.config.Configurator.set_request_property` |
| | | See :meth:`pyramid.config.Configurator.add_request_method` |
| | | for a less intrusive way to extend the request objects with |
| | | custom properties. |
| | | custom methods and properties. |
| | | |
| | | .. note:: |
| | | |
| | |
| | | self.action(IRequestFactory, register, introspectables=(intr,)) |
| | | |
| | | @action_method |
| | | def set_request_method(self, |
| | | def add_request_method(self, |
| | | callable=None, |
| | | name=None, |
| | | property=False, |
| | |
| | | if exts is None: |
| | | exts = _RequestExtensions() |
| | | self.registry.registerUtility(exts, IRequestExtensions) |
| | | self.registry.registerHandler(_set_request_extensions, |
| | | (INewRequest,)) |
| | | |
| | | plist = exts.descriptors if property else exts.methods |
| | | plist[name] = callable |
| | |
| | | |
| | | .. warning:: |
| | | |
| | | This method has been deprecated as of Pyramid 1.4. |
| | | :meth:`pyramid.config.Configurator.set_request_method` should be |
| | | This method has been docs-deprecated as of Pyramid 1.4. |
| | | :meth:`pyramid.config.Configurator.add_request_method` should be |
| | | used instead. |
| | | |
| | | .. versionadded:: 1.3 |
| | | """ |
| | | self.set_request_method( |
| | | self.add_request_method( |
| | | callable, name=name, property=not reify, reify=reify) |
| | | |
| | | @implementer(IRequestExtensions) |
| | |
| | | self.descriptors = {} |
| | | self.methods = {} |
| | | |
| | | def _set_request_extensions(event): |
| | | request = event.request |
| | | exts = request.registry.queryUtility(IRequestExtensions) |
| | | for name, fn in iteritems_(exts.methods): |
| | | method = fn.__get__(request, request.__class__) |
| | | setattr(request, name, method) |
| | | request._set_properties(exts.descriptors) |
| | |
| | | import os |
| | | |
| | | import zope.deprecation |
| | | |
| | | from paste.deploy import ( |
| | | loadapp, |
| | | appconfig, |
| | |
| | | from pyramid.compat import configparser |
| | | from logging.config import fileConfig |
| | | from pyramid.scripting import prepare |
| | | from pyramid.scaffolds import PyramidTemplate # bw compat |
| | | |
| | | PyramidTemplate = PyramidTemplate # pyflakes |
| | | |
| | | zope.deprecation.deprecated( |
| | | 'PyramidTemplate', ('pyramid.paster.PyramidTemplate was moved to ' |
| | | 'pyramid.scaffolds.PyramidTemplate in Pyramid 1.1'), |
| | | ) |
| | | |
| | | def get_app(config_uri, name=None, loadapp=loadapp): |
| | | """ Return the WSGI application named ``name`` in the PasteDeploy |
| | |
| | | new_request.environ['SCRIPT_NAME'] = new_script_name |
| | | new_request.environ['PATH_INFO'] = new_path_info |
| | | |
| | | # In case downstream WSGI app is a Pyramid app, hack around existence of |
| | | # these envars until we can safely remove them (see router.py); in any |
| | | # case, even if these get removed, it might be better to not copy the |
| | | # existing environ but to create a new one instead. |
| | | if 'bfg.routes.route' in new_request.environ: |
| | | del new_request.environ['bfg.routes.route'] |
| | | if 'bfg.routes.matchdict' in new_request.environ: |
| | | del new_request.environ['bfg.routes.matchdict'] |
| | | |
| | | return new_request.get_response(app) |
| | |
| | | from pyramid.interfaces import ( |
| | | IDebugLogger, |
| | | IRequest, |
| | | IRequestExtensions, |
| | | IRootFactory, |
| | | IRouteRequest, |
| | | IRouter, |
| | |
| | | self.root_factory = q(IRootFactory, default=DefaultRootFactory) |
| | | self.routes_mapper = q(IRoutesMapper) |
| | | self.request_factory = q(IRequestFactory, default=Request) |
| | | self.request_extensions = q(IRequestExtensions) |
| | | tweens = q(ITweens) |
| | | if tweens is None: |
| | | tweens = excview_tween_factory |
| | |
| | | request.url) |
| | | logger and logger.debug(msg) |
| | | else: |
| | | # TODO: kill off bfg.routes.* environ keys |
| | | # when traverser requires request arg, and |
| | | # cant cope with environ anymore (they are |
| | | # docs-deprecated as of BFG 1.3) |
| | | environ = request.environ |
| | | environ['bfg.routes.route'] = route |
| | | environ['bfg.routes.matchdict'] = match |
| | | attrs['matchdict'] = match |
| | | attrs['matched_route'] = route |
| | | |
| | |
| | | request.url, |
| | | route.name, |
| | | request.path_info, |
| | | route.pattern, match, |
| | | route.pattern, |
| | | match, |
| | | ', '.join([p.__text__ for p in route.predicates])) |
| | | ) |
| | | logger and logger.debug(msg) |
| | |
| | | try: |
| | | |
| | | try: |
| | | extensions = self.request_extensions |
| | | if extensions is not None: |
| | | request._set_extensions(extensions) |
| | | response = self.handle_request(request) |
| | | has_listeners and notify(NewResponse(request, response)) |
| | | |
| | |
| | | |
| | | finally: |
| | | manager.pop() |
| | | |
| | |
| | | from pyramid.request import Request |
| | | |
| | | from pyramid.interfaces import ( |
| | | IRequestExtensions, |
| | | IRequestFactory, |
| | | IRootFactory, |
| | | ) |
| | |
| | | 'before trying to activate it.') |
| | | if request is None: |
| | | request = _make_request('/', registry) |
| | | request.registry = registry |
| | | threadlocals = {'registry':registry, 'request':request} |
| | | threadlocal_manager.push(threadlocals) |
| | | extensions = registry.queryUtility(IRequestExtensions) |
| | | if extensions is not None: |
| | | request._set_extensions(extensions) |
| | | def closer(): |
| | | threadlocal_manager.pop() |
| | | root_factory = registry.queryUtility(IRootFactory, |
| | | default=DefaultRootFactory) |
| | | root = root_factory(request) |
| | | if getattr(request, 'context', None) is None: |
| | | request.context = root |
| | | return {'root':root, 'closer':closer, 'registry':registry, |
| | | 'request':request, 'root_factory':root_factory} |
| | | |
| | |
| | | from zope.deprecation import deprecated |
| | | |
| | | from pyramid.threadlocal import get_current_registry |
| | | from pyramid.compat import string_types |
| | | |
| | | def get_settings(): |
| | | """ |
| | | Return a :term:`deployment settings` object for the current application. |
| | | The object is a dictionary-like object that contains key/value pairs |
| | | based on the dictionary passed as the ``settings`` argument to the |
| | | :class:`pyramid.config.Configurator` constructor or the |
| | | :func:`pyramid.router.make_app` API. |
| | | |
| | | .. warning:: This method is deprecated as of Pyramid 1.0. Use |
| | | ``pyramid.threadlocal.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.threadlocal.get_current_registry().settings`` instead or use ' |
| | | 'the ``settings`` attribute of the registry available from the request ' |
| | | '(``request.registry.settings``)).') |
| | | |
| | | truthy = frozenset(('t', 'true', 'y', 'yes', 'on', '1')) |
| | | |
| | |
| | | import copy |
| | | import os |
| | | |
| | | from zope.deprecation import deprecated |
| | | |
| | | from zope.interface import ( |
| | | implementer, |
| | | Interface, |
| | | alsoProvides, |
| | | ) |
| | | |
| | | from pyramid.interfaces import ( |
| | | IRequest, |
| | | IResponseFactory, |
| | | ISecuredView, |
| | | IView, |
| | | IViewClassifier, |
| | | ISession, |
| | | ) |
| | | |
| | |
| | | |
| | | from pyramid.config import Configurator |
| | | from pyramid.decorator import reify |
| | | from pyramid.httpexceptions import HTTPForbidden |
| | | from pyramid.response import Response |
| | | from pyramid.registry import Registry |
| | | |
| | | from pyramid.security import ( |
| | | Authenticated, |
| | | Everyone, |
| | | has_permission, |
| | | ) |
| | | |
| | | from pyramid.threadlocal import ( |
| | |
| | | ) |
| | | |
| | | from pyramid.url import URLMethodsMixin |
| | | from pyramid.util import InstancePropertyMixin |
| | | |
| | | _marker = object() |
| | | |
| | | def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True): |
| | | """ Registers a pair of faux :app:`Pyramid` security policies: |
| | | a :term:`authentication policy` and a :term:`authorization |
| | | policy`. |
| | | |
| | | The behavior of the registered :term:`authorization policy` |
| | | depends on the ``permissive`` argument. If ``permissive`` is |
| | | true, a permissive :term:`authorization policy` is registered; |
| | | this policy allows all access. If ``permissive`` is false, a |
| | | nonpermissive :term:`authorization policy` is registered; this |
| | | policy denies all access. |
| | | |
| | | The behavior of the registered :term:`authentication policy` |
| | | depends on the values provided for the ``userid`` and ``groupids`` |
| | | argument. The authentication policy will return the userid |
| | | identifier implied by the ``userid`` argument and the group ids |
| | | implied by the ``groupids`` argument when the |
| | | :func:`pyramid.security.authenticated_userid` or |
| | | :func:`pyramid.security.effective_principals` APIs are used. |
| | | |
| | | This function is most useful when testing code that uses the APIs named |
| | | :func:`pyramid.security.has_permission`, |
| | | :func:`pyramid.security.authenticated_userid`, |
| | | :func:`pyramid.security.unauthenticated_userid`, |
| | | :func:`pyramid.security.effective_principals`, and |
| | | :func:`pyramid.security.principals_allowed_by_permission`. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.testing_securitypolicy` |
| | | method in your unit and integration tests. |
| | | """ |
| | | registry = get_current_registry() |
| | | config = Configurator(registry=registry) |
| | | result = config.testing_securitypolicy(userid=userid, groupids=groupids, |
| | | permissive=permissive) |
| | | config.commit() |
| | | return result |
| | | |
| | | deprecated('registerDummySecurityPolicy', |
| | | 'The testing.registerDummySecurityPolicy API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.testing_securitypolicy ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerResources(resources): |
| | | """ Registers a dictionary of :term:`resource` objects that can be |
| | | resolved via the :func:`pyramid.traversal.find_resource` API. |
| | | |
| | | The :func:`pyramid.traversal.find_resource` API is called with a |
| | | path as one of its arguments. If the dictionary you register when |
| | | calling this method contains that path as a string key |
| | | (e.g. ``/foo/bar`` or ``foo/bar``), the corresponding value will |
| | | be returned to ``find_resource`` (and thus to your code) when |
| | | :func:`pyramid.traversal.find_resource` is called with an |
| | | equivalent path string or tuple. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.testing_resources` |
| | | method in your unit and integration tests. |
| | | |
| | | .. note:: For ancient backward compatibility purposes, this API can also |
| | | be accessed as :func:`pyramid.testing.registerModels`. |
| | | """ |
| | | registry = get_current_registry() |
| | | config = Configurator(registry=registry) |
| | | result = config.testing_resources(resources) |
| | | config.commit() |
| | | return result |
| | | |
| | | deprecated('registerResources', |
| | | 'The testing.registerResources API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.testing_resources ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | registerModels = registerResources |
| | | |
| | | deprecated('registerModels', |
| | | 'The testing.registerModels API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.testing_resources ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerEventListener(event_iface=None): |
| | | """ Registers an :term:`event` listener (aka :term:`subscriber`) |
| | | listening for events of the type ``event_iface``. This method |
| | | returns a list object which is appended to by the subscriber |
| | | whenever an event is captured. |
| | | |
| | | When an event is dispatched that matches ``event_iface``, that |
| | | event will be appended to the list. You can then compare the |
| | | values in the list to expected event notifications. This method |
| | | is useful when testing code that wants to call |
| | | :meth:`pyramid.registry.Registry.notify`. |
| | | |
| | | The default value of ``event_iface`` (``None``) implies a |
| | | subscriber registered for *any* kind of event. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.testing_add_subscriber` |
| | | method in your unit and integration tests. |
| | | """ |
| | | registry = get_current_registry() |
| | | config = Configurator(registry=registry) |
| | | result = config.testing_add_subscriber(event_iface) |
| | | config.commit() |
| | | return result |
| | | |
| | | deprecated('registerEventListener', |
| | | 'The testing.registerEventListener API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.testing_add_subscriber ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerTemplateRenderer(path, renderer=None): |
| | | """ Register a template renderer at ``path`` (usually a relative |
| | | filename ala ``templates/foo.pt``) and return the renderer object. |
| | | If the ``renderer`` argument is None, a 'dummy' renderer will be |
| | | used. This function is useful when testing code that calls the |
| | | :func:`pyramid.renderers.render` function or |
| | | :func:`pyramid.renderers.render_to_response` function or any |
| | | other ``render_*`` or ``get_*`` API of the |
| | | :mod:`pyramid.renderers` module. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.testing_add_renderer` |
| | | method in your unit and integration tests. |
| | | |
| | | """ |
| | | registry = get_current_registry() |
| | | config = Configurator(registry=registry) |
| | | result = config.testing_add_template(path, renderer) |
| | | config.commit() |
| | | return result |
| | | |
| | | deprecated('registerTemplateRenderer', |
| | | 'The testing.registerTemplateRenderer API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.testing_add_renderer ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | # registerDummyRenderer is a deprecated alias that should never be removed |
| | | # (too much usage in the wild) |
| | | registerDummyRenderer = registerTemplateRenderer |
| | | |
| | | deprecated('registerDummyRenderer', |
| | | 'The testing.registerDummyRenderer API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.testing_add_renderer ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerView(name, result='', view=None, for_=(Interface, Interface), |
| | | permission=None): |
| | | """ Registers a :app:`Pyramid` :term:`view callable` under the |
| | | name implied by the ``name`` argument. The view will return a |
| | | :term:`WebOb` :term:`Response` object with the value implied by |
| | | the ``result`` argument as its ``body`` attribute. To gain more |
| | | control, if you pass in a non-``None`` ``view`` argument, this |
| | | value will be used as a view callable instead of an automatically |
| | | generated view callable (and ``result`` is not used). |
| | | |
| | | To protect the view using a :term:`permission`, pass in a |
| | | non-``None`` value as ``permission``. This permission will be |
| | | checked by any active :term:`authorization policy` when view |
| | | execution is attempted. |
| | | |
| | | This function is useful when testing code which calls |
| | | :func:`pyramid.view.render_view_to_response`. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.add_view` |
| | | method in your unit and integration tests. |
| | | """ |
| | | for_ = (IViewClassifier, ) + for_ |
| | | if view is None: |
| | | def view(context, request): |
| | | return Response(result) |
| | | if permission is None: |
| | | return registerAdapter(view, for_, IView, name) |
| | | else: |
| | | def _secure(context, request): |
| | | if not has_permission(permission, context, request): |
| | | raise HTTPForbidden('no permission') |
| | | else: |
| | | return view(context, request) |
| | | _secure.__call_permissive__ = view |
| | | def permitted(context, request): |
| | | return has_permission(permission, context, request) |
| | | _secure.__permitted__ = permitted |
| | | return registerAdapter(_secure, for_, ISecuredView, name) |
| | | |
| | | deprecated('registerView', |
| | | 'The registerView API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.add_view ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerUtility(impl, iface=Interface, name=''): |
| | | """ Register a ZCA utility component. |
| | | |
| | | The ``impl`` argument specifies the implementation of the utility. |
| | | The ``iface`` argument specifies the :term:`interface` which will |
| | | be later required to look up the utility |
| | | (:class:`zope.interface.Interface`, by default). The ``name`` |
| | | argument implies the utility name; it is the empty string by |
| | | default. |
| | | |
| | | See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for |
| | | more information about ZCA utilities. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the :meth:`pyramid.Registry.registerUtility` |
| | | method. The ``registry`` attribute of a :term:`Configurator` |
| | | in your unit and integration tests is an instance of the |
| | | :class:`pyramid.Registry` class. |
| | | """ |
| | | reg = get_current_registry() |
| | | reg.registerUtility(impl, iface, name=name) |
| | | return impl |
| | | |
| | | deprecated('registerUtility', |
| | | 'The registerUtility API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.registry.registerUtility method (via ' |
| | | 'e.g. "config.registry.registerUtility(..)" ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerAdapter(impl, for_=Interface, provides=Interface, name=''): |
| | | """ Register a ZCA adapter component. |
| | | |
| | | The ``impl`` argument specifies the implementation of the |
| | | component (often a class). The ``for_`` argument implies the |
| | | ``for`` interface type used for this registration; it is |
| | | :class:`zope.interface.Interface` by default. If ``for`` is not a |
| | | tuple or list, it will be converted to a one-tuple before being |
| | | passed to underlying :meth:`pyramid.registry.registerAdapter` |
| | | API. |
| | | |
| | | The ``provides`` argument specifies the ZCA 'provides' interface, |
| | | :class:`zope.interface.Interface` by default. |
| | | |
| | | The ``name`` argument is the empty string by default; it implies |
| | | the name under which the adapter is registered. |
| | | |
| | | See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for |
| | | more information about ZCA adapters. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the :meth:`pyramid.Registry.registerAdapter` |
| | | method. The ``registry`` attribute of a :term:`Configurator` |
| | | in your unit and integration tests is an instance of the |
| | | :class:`pyramid.Registry` class. |
| | | """ |
| | | reg = get_current_registry() |
| | | if not isinstance(for_, (tuple, list)): |
| | | for_ = (for_,) |
| | | reg.registerAdapter(impl, for_, provides, name=name) |
| | | return impl |
| | | |
| | | deprecated('registerAdapter', |
| | | 'The registerAdapter API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.registry.registerAdapter method (via ' |
| | | 'e.g. "config.registry.registerAdapter(..)" ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerSubscriber(subscriber, iface=Interface): |
| | | """ Register a ZCA subscriber component. |
| | | |
| | | The ``subscriber`` argument specifies the implementation of the |
| | | subscriber component (often a function). |
| | | |
| | | The ``iface`` argument is the interface type for which the |
| | | subscriber will be registered (:class:`zope.interface.Interface` |
| | | by default). If ``iface`` is not a tuple or list, it will be |
| | | converted to a one-tuple before being passed to the underlying ZCA |
| | | :meth:`pyramid.registry.registerHandler` method. |
| | | |
| | | See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for |
| | | more information about ZCA subscribers. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.add_subscriber` |
| | | method in your unit and integration tests. |
| | | """ |
| | | registry = get_current_registry() |
| | | config = Configurator(registry) |
| | | result = config.add_subscriber(subscriber, iface=iface) |
| | | config.commit() |
| | | return result |
| | | |
| | | deprecated('registerSubscriber', |
| | | 'The testing.registerSubscriber API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.add_subscriber ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | def registerRoute(pattern, name, factory=None): |
| | | """ Register a new :term:`route` using a pattern |
| | | (e.g. ``:pagename``), a name (e.g. ``home``), and an optional root |
| | | factory. |
| | | |
| | | The ``pattern`` argument implies the route pattern. The ``name`` |
| | | argument implies the route name. The ``factory`` argument implies |
| | | a :term:`root factory` associated with the route. |
| | | |
| | | This API is useful for testing code that calls |
| | | e.g. :func:`pyramid.url.route_url`. |
| | | |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.config.Configurator.add_route` |
| | | method in your unit and integration tests. |
| | | """ |
| | | reg = get_current_registry() |
| | | config = Configurator(registry=reg) |
| | | config.setup_registry() |
| | | result = config.add_route(name, pattern, factory=factory) |
| | | config.commit() |
| | | return result |
| | | |
| | | deprecated('registerRoute', |
| | | 'The testing.registerRoute API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.add_route ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | 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 :attr:`pyramid.registry.Registry.settings`. |
| | | |
| | | You may pass a dictionary:: |
| | | |
| | | registerSettings({'external_uri':'http://example.com'}) |
| | | |
| | | Or a set of key/value pairs:: |
| | | |
| | | registerSettings(external_uri='http://example.com') |
| | | |
| | | 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 |
| | | :meth:`pyramid.config.Configurator.add_settings` |
| | | method in your unit and integration tests. |
| | | """ |
| | | registry = get_current_registry() |
| | | config = Configurator(registry=registry) |
| | | config.add_settings(dictarg, **kw) |
| | | |
| | | deprecated('registerSettings', |
| | | 'The testing.registerSettings API is deprecated as of ' |
| | | 'Pyramid 1.0. Instead use the ' |
| | | 'pyramid.config.Configurator.add_settings ' |
| | | 'method in your unit and integration tests.') |
| | | |
| | | class DummyRootFactory(object): |
| | | __parent__ = None |
| | |
| | | |
| | | @implementer(IRequest) |
| | | class DummyRequest(DeprecatedRequestMethodsMixin, URLMethodsMixin, |
| | | CallbackMethodsMixin): |
| | | CallbackMethodsMixin, InstancePropertyMixin): |
| | | """ A DummyRequest object (incompletely) imitates a :term:`request` object. |
| | | |
| | | The ``params``, ``environ``, ``headers``, ``path``, and |
| | |
| | | <html> |
| | | <metal:m define-macro="foo"> |
| | | Hello! |
| | | </metal:m> |
| | | </html> |
| | | |
| | |
| | | import sys |
| | | import unittest |
| | | |
| | | from pyramid.compat import binary_type |
| | | from pyramid.testing import skip_on |
| | | from pyramid import testing |
| | | |
| | | class Base: |
| | | class Base(object): |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | from zope.deprecation import __show__ |
| | | __show__.off() |
| | | |
| | | def tearDown(self): |
| | | testing.tearDown() |
| | | from zope.deprecation import __show__ |
| | | __show__.on() |
| | | |
| | | def _getTemplatePath(self, name): |
| | | import os |
| | | here = os.path.abspath(os.path.dirname(__file__)) |
| | | return os.path.join(here, 'fixtures', name) |
| | | |
| | | def _registerUtility(self, utility, iface, name=''): |
| | | reg = self.config.registry |
| | | reg.registerUtility(utility, iface, name=name) |
| | | class Test_renderer_factory(Base, unittest.TestCase): |
| | | def _callFUT(self, info): |
| | | from pyramid.chameleon_text import renderer_factory |
| | | return renderer_factory(info) |
| | | |
| | | def test_it(self): |
| | | # this test is way too functional |
| | | from pyramid.chameleon_text import TextTemplateRenderer |
| | | info = DummyInfo() |
| | | result = self._callFUT(info) |
| | | self.assertEqual(result.__class__, TextTemplateRenderer) |
| | | |
| | | class TextTemplateRendererTests(Base, unittest.TestCase): |
| | | def _getTargetClass(self): |
| | |
| | | self.assertTrue(isinstance(result, binary_type)) |
| | | self.assertEqual(result, b'Hello.\n') |
| | | |
| | | class RenderTemplateTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name, **kw): |
| | | 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) |
| | | self.assertTrue(isinstance(result, binary_type)) |
| | | self.assertEqual(result, b'Hello.\n') |
| | | |
| | | class RenderTemplateToResponseTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name, **kw): |
| | | 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) |
| | | from webob import Response |
| | | self.assertTrue(isinstance(result, Response)) |
| | | self.assertEqual(result.app_iter, [b'Hello.\n']) |
| | | 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): |
| | | pass |
| | | from pyramid.interfaces import IResponseFactory |
| | | self._registerUtility(Response2, IResponseFactory) |
| | | minimal = self._getTemplatePath('minimal.txt') |
| | | result = self._callFUT(minimal) |
| | | self.assertTrue(isinstance(result, Response2)) |
| | | |
| | | class GetRendererTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name): |
| | | 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: |
| | | template = object() |
| | | def implementation(self): pass |
| | | renderer = Dummy() |
| | | def rf(spec): |
| | | return renderer |
| | | self._registerUtility(rf, IRendererFactory, name='foo') |
| | | result = self._callFUT('foo') |
| | | self.assertTrue(result is renderer) |
| | | |
| | | class GetTemplateTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name): |
| | | 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: |
| | | template = object() |
| | | def implementation(self): |
| | | return self.template |
| | | renderer = Dummy() |
| | | def rf(spec): |
| | | return renderer |
| | | self._registerUtility(rf, IRendererFactory, name='foo') |
| | | result = self._callFUT('foo') |
| | | self.assertTrue(result is renderer.template) |
| | | |
| | | class DummyLookup(object): |
| | | auto_reload=True |
| | | debug = True |
| | | def translate(self, msg): pass |
| | | |
| | | class DummyRegistry(object): |
| | | def queryUtility(self, iface, name): |
| | | self.queried = iface, name |
| | | return None |
| | | |
| | | def registerUtility(self, impl, iface, name): |
| | | self.registered = impl, iface, name |
| | | |
| | | class DummyInfo(object): |
| | | def __init__(self): |
| | | self.registry = DummyRegistry() |
| | | self.type = '.pt' |
| | | self.name = 'fixtures/minimal.pt' |
| | | self.package = sys.modules[__name__] |
| | | self.settings = {} |
| | | |
| | |
| | | import sys |
| | | import unittest |
| | | |
| | | from pyramid.testing import skip_on |
| | |
| | | class Base(object): |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | from zope.deprecation import __show__ |
| | | __show__.off() |
| | | |
| | | def tearDown(self): |
| | | testing.tearDown() |
| | | from zope.deprecation import __show__ |
| | | __show__.on() |
| | | |
| | | def _getTemplatePath(self, name): |
| | | import os |
| | | here = os.path.abspath(os.path.dirname(__file__)) |
| | | return os.path.join(here, 'fixtures', name) |
| | | |
| | | def _registerUtility(self, utility, iface, name=''): |
| | | reg = self.config.registry |
| | | reg.registerUtility(utility, iface, name=name) |
| | | return reg |
| | | |
| | | class Test_renderer_factory(Base, unittest.TestCase): |
| | | def _callFUT(self, info): |
| | | from pyramid.chameleon_zpt import renderer_factory |
| | | return renderer_factory(info) |
| | | |
| | | def test_it(self): |
| | | # this test is way too functional |
| | | from pyramid.chameleon_zpt import ZPTTemplateRenderer |
| | | info = DummyInfo() |
| | | result = self._callFUT(info) |
| | | self.assertEqual(result.__class__, ZPTTemplateRenderer) |
| | | |
| | | class ZPTTemplateRendererTests(Base, unittest.TestCase): |
| | | def _getTargetClass(self): |
| | | from pyramid.chameleon_zpt import ZPTTemplateRenderer |
| | |
| | | self.assertTrue(isinstance(result, text_type)) |
| | | self.assertEqual(result.rstrip('\n'), |
| | | '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') |
| | | |
| | | def test_macro_supplied(self): |
| | | minimal = self._getTemplatePath('withmacro.pt') |
| | | lookup = DummyLookup() |
| | | instance = self._makeOne(minimal, lookup, macro='foo') |
| | | result = instance.implementation()() |
| | | self.assertEqual(result, '\n Hello!\n') |
| | | |
| | | |
| | | class RenderTemplateTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name, **kw): |
| | | 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) |
| | | self.assertTrue(isinstance(result, text_type)) |
| | | self.assertEqual(result.rstrip('\n'), |
| | | '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') |
| | | |
| | | class RenderTemplateToResponseTests(Base, unittest.TestCase): |
| | | 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) |
| | | from webob import Response |
| | | self.assertTrue(isinstance(result, Response)) |
| | | self.assertEqual(result.app_iter[0].rstrip(b'\n'), |
| | | b'<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') |
| | | 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): |
| | | pass |
| | | from pyramid.interfaces import IResponseFactory |
| | | self._registerUtility(Response2, IResponseFactory) |
| | | minimal = self._getTemplatePath('minimal.pt') |
| | | result = self._callFUT(minimal) |
| | | self.assertTrue(isinstance(result, Response2)) |
| | | |
| | | class GetRendererTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name): |
| | | 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: |
| | | template = object() |
| | | def implementation(self): pass |
| | | renderer = Dummy() |
| | | def rf(spec): |
| | | return renderer |
| | | self._registerUtility(rf, IRendererFactory, name='foo') |
| | | result = self._callFUT('foo') |
| | | self.assertTrue(result is renderer) |
| | | |
| | | class GetTemplateTests(Base, unittest.TestCase): |
| | | def _callFUT(self, name): |
| | | 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: |
| | | template = object() |
| | | def implementation(self): |
| | | return self.template |
| | | renderer = Dummy() |
| | | def rf(spec): |
| | | return renderer |
| | | self._registerUtility(rf, IRendererFactory, name='foo') |
| | | result = self._callFUT('foo') |
| | | self.assertTrue(result is renderer.template) |
| | | |
| | | |
| | | |
| | | class DummyLookup(object): |
| | | auto_reload=True |
| | | debug = True |
| | | def translate(self, msg): pass |
| | | |
| | | class DummyRegistry(object): |
| | | def queryUtility(self, iface, name): |
| | | self.queried = iface, name |
| | | return None |
| | | |
| | | def registerUtility(self, impl, iface, name): |
| | | self.registered = impl, iface, name |
| | | |
| | | class DummyInfo(object): |
| | | def __init__(self): |
| | | self.registry = DummyRegistry() |
| | | self.type = '.pt' |
| | | self.name = 'fixtures/minimal.pt' |
| | | self.package = sys.modules[__name__] |
| | | self.settings = {} |
| | | |
| | |
| | | config.set_request_property(bar, name='bar') |
| | | self.assertRaises(ConfigurationConflictError, config.commit) |
| | | |
| | | def test_set_request_property_subscriber(self): |
| | | from zope.interface import implementer |
| | | from pyramid.interfaces import INewRequest |
| | | config = self._makeOne() |
| | | def foo(r): pass |
| | | config.set_request_property(foo, name='foo') |
| | | config.set_request_property(foo, name='bar', reify=True) |
| | | config.commit() |
| | | @implementer(INewRequest) |
| | | class Event(object): |
| | | request = DummyRequest(config.registry) |
| | | event = Event() |
| | | config.registry.notify(event) |
| | | exts = list(sorted(event.request.extensions)) |
| | | self.assertEqual('bar', exts[0]) |
| | | self.assertEqual('foo', exts[1]) |
| | | |
| | | def test_set_request_method_subscriber(self): |
| | | from zope.interface import implementer |
| | | from pyramid.interfaces import INewRequest |
| | | config = self._makeOne(autocommit=True) |
| | | def foo(r): return 'bar' |
| | | config.set_request_method(foo, name='foo') |
| | | @implementer(INewRequest) |
| | | class Event(object): |
| | | request = DummyRequest(config.registry) |
| | | event = Event() |
| | | config.registry.notify(event) |
| | | self.assertEqual('bar', event.request.foo()) |
| | | |
| | | def test_set_request_method_with_callable(self): |
| | | def test_add_request_method_with_callable(self): |
| | | from pyramid.interfaces import IRequestExtensions |
| | | config = self._makeOne(autocommit=True) |
| | | callable = lambda x: None |
| | | config.set_request_method(callable, name='foo') |
| | | config.add_request_method(callable, name='foo') |
| | | exts = config.registry.getUtility(IRequestExtensions) |
| | | self.assertTrue('foo' in exts.methods) |
| | | |
| | | def test_set_request_method_with_unnamed_callable(self): |
| | | def test_add_request_method_with_unnamed_callable(self): |
| | | from pyramid.interfaces import IRequestExtensions |
| | | config = self._makeOne(autocommit=True) |
| | | def foo(self): pass |
| | | config.set_request_method(foo) |
| | | config.add_request_method(foo) |
| | | exts = config.registry.getUtility(IRequestExtensions) |
| | | self.assertTrue('foo' in exts.methods) |
| | | |
| | |
| | | config = self._makeOne() |
| | | def foo(self): pass |
| | | def bar(self): pass |
| | | config.set_request_method(foo, name='bar') |
| | | config.set_request_method(bar, name='bar') |
| | | config.add_request_method(foo, name='bar') |
| | | config.add_request_method(bar, name='bar') |
| | | self.assertRaises(ConfigurationConflictError, config.commit) |
| | | |
| | | def test_set_request_method_with_None_callable(self): |
| | | def test_add_request_method_with_None_callable(self): |
| | | from pyramid.interfaces import IRequestExtensions |
| | | config = self._makeOne(autocommit=True) |
| | | config.set_request_method(name='foo') |
| | | config.add_request_method(name='foo') |
| | | exts = config.registry.queryUtility(IRequestExtensions) |
| | | self.assertTrue(exts is None) |
| | | |
| | | def test_set_request_method_with_None_callable_conflict(self): |
| | | def test_add_request_method_with_None_callable_conflict(self): |
| | | from pyramid.exceptions import ConfigurationConflictError |
| | | config = self._makeOne() |
| | | def bar(self): pass |
| | | config.set_request_method(name='foo') |
| | | config.set_request_method(bar, name='foo') |
| | | config.add_request_method(name='foo') |
| | | config.add_request_method(bar, name='foo') |
| | | self.assertRaises(ConfigurationConflictError, config.commit) |
| | | |
| | | def test_set_request_method_with_None_callable_and_no_name(self): |
| | | def test_add_request_method_with_None_callable_and_no_name(self): |
| | | config = self._makeOne(autocommit=True) |
| | | self.assertRaises(AttributeError, config.set_request_method) |
| | | self.assertRaises(AttributeError, config.add_request_method) |
| | | |
| | | |
| | | class DummyRequest(object): |
| | | extensions = None |
| | | |
| | | def __init__(self, registry): |
| | | self.registry = registry |
| | | |
| | | def _set_properties(self, properties): |
| | | if self.extensions is None: |
| | | self.extensions = [] |
| | | self.extensions.extend(properties) |
| | | |
| | |
| | | settings = reg.getUtility(ISettings) |
| | | self.assertEqual(settings['a'], 1) |
| | | |
| | | def test_add_settings_settings_None(self): |
| | | from pyramid.registry import Registry |
| | | from pyramid.interfaces import ISettings |
| | | reg = Registry() |
| | | config = self._makeOne(reg) |
| | | config.add_settings(None, a=1) |
| | | settings = reg.getUtility(ISettings) |
| | | self.assertEqual(settings['a'], 1) |
| | | |
| | | class TestSettings(unittest.TestCase): |
| | | |
| | | def _getTargetClass(self): |
| | |
| | | self.assertEqual(result, tests) |
| | | |
| | | def test_it_module(self): |
| | | import pyramid.tests.test_configuration |
| | | import pyramid.tests.test_path |
| | | from pyramid import tests |
| | | package = DummyPackageOrModule(pyramid.tests.test_configuration) |
| | | package = DummyPackageOrModule(pyramid.tests.test_path) |
| | | result = self._callFUT(package) |
| | | self.assertEqual(result, tests) |
| | | |
| | |
| | | self.assertEqual(result, self.__class__) |
| | | |
| | | def test__zope_dottedname_style_resolve_relative_leading_dots(self): |
| | | import pyramid.tests.test_configuration |
| | | import pyramid.tests.test_path |
| | | typ = self._makeOne() |
| | | result = typ._zope_dottedname_style( |
| | | '..tests.test_path.TestDottedNameResolver', pyramid.tests) |
| | |
| | | def renderer(*arg): |
| | | def respond(*arg): |
| | | return arg |
| | | renderer.respond = respond |
| | | return respond |
| | | self.config.registry.registerUtility(renderer, IRendererFactory, |
| | | name='.foo') |
| | |
| | | request=request) |
| | | self.assertEqual(response.body[0], 'values') |
| | | self.assertEqual(response.body[1], {}) |
| | | |
| | | def test_get_renderer(self): |
| | | factory = self._registerRendererFactory() |
| | | helper = self._makeOne('loo.foo') |
| | | self.assertEqual(helper.get_renderer(), factory.respond) |
| | | |
| | | def test_render_view(self): |
| | | self._registerRendererFactory() |
| | |
| | | response = helper._make_response(la.encode('utf-8'), request) |
| | | self.assertEqual(response.body, la.encode('utf-8')) |
| | | |
| | | def test__make_response_result_is_None(self): |
| | | from pyramid.response import Response |
| | | request = testing.DummyRequest() |
| | | request.response = Response() |
| | | helper = self._makeOne('loo.foo') |
| | | response = helper._make_response(None, request) |
| | | self.assertEqual(response.body, b'') |
| | | |
| | | def test__make_response_with_content_type(self): |
| | | from pyramid.response import Response |
| | | request = testing.DummyRequest() |
| | |
| | | self.assertEqual(request.environ['SCRIPT_NAME'], '/' + encoded) |
| | | self.assertEqual(request.environ['PATH_INFO'], '/' + encoded) |
| | | |
| | | def test_it_removes_bfg_routes_info(self): |
| | | request = DummyRequest({}) |
| | | request.environ['bfg.routes.route'] = True |
| | | request.environ['bfg.routes.matchdict'] = True |
| | | response = self._callFUT(request, 'app') |
| | | self.assertTrue(request.copied) |
| | | self.assertEqual(response, 'app') |
| | | self.assertEqual(request.environ['SCRIPT_NAME'], '') |
| | | self.assertEqual(request.environ['PATH_INFO'], '/') |
| | | self.assertFalse('bfg.routes.route' in request.environ) |
| | | self.assertFalse('bfg.routes.matchdict' in request.environ) |
| | | |
| | | class DummyRequest: |
| | | def __init__(self, environ=None): |
| | | if environ is None: |
| | |
| | | self.assertEqual(app_iter, [b'abc']) |
| | | self.assertEqual(start_response.status, '200 OK') |
| | | |
| | | def test_call_with_request_extensions(self): |
| | | from pyramid.interfaces import IViewClassifier |
| | | from pyramid.interfaces import IRequestExtensions |
| | | from pyramid.interfaces import IRequest |
| | | from pyramid.request import Request |
| | | context = DummyContext() |
| | | self._registerTraverserFactory(context) |
| | | class Extensions(object): |
| | | def __init__(self): |
| | | self.methods = {} |
| | | self.descriptors = {} |
| | | extensions = Extensions() |
| | | L = [] |
| | | request = Request.blank('/') |
| | | request.request_iface = IRequest |
| | | request.registry = self.registry |
| | | request._set_extensions = lambda *x: L.extend(x) |
| | | def request_factory(environ): |
| | | return request |
| | | self.registry.registerUtility(extensions, IRequestExtensions) |
| | | environ = self._makeEnviron() |
| | | response = DummyResponse() |
| | | response.app_iter = ['Hello world'] |
| | | view = DummyView(response) |
| | | self._registerView(self.config.derive_view(view), '', |
| | | IViewClassifier, None, None) |
| | | router = self._makeOne() |
| | | router.request_factory = request_factory |
| | | start_response = DummyStartResponse() |
| | | router(environ, start_response) |
| | | self.assertEqual(L, [extensions]) |
| | | |
| | | def test_call_view_registered_nonspecific_default_path(self): |
| | | from pyramid.interfaces import IViewClassifier |
| | | context = DummyContext() |
| | |
| | | self.assertEqual(request.context, context) |
| | | self.assertEqual(request.root, root) |
| | | matchdict = {'action':'action1', 'article':'article1'} |
| | | self.assertEqual(environ['bfg.routes.matchdict'], matchdict) |
| | | self.assertEqual(environ['bfg.routes.route'].name, 'foo') |
| | | self.assertEqual(request.matchdict, matchdict) |
| | | self.assertEqual(request.matched_route.name, 'foo') |
| | | self.assertEqual(len(logger.messages), 1) |
| | |
| | | self.assertEqual(request.context, context) |
| | | self.assertEqual(request.root, root) |
| | | matchdict = {'action':'action1', 'article':'article1'} |
| | | self.assertEqual(environ['bfg.routes.matchdict'], matchdict) |
| | | self.assertEqual(environ['bfg.routes.route'].name, 'foo') |
| | | self.assertEqual(request.matchdict, matchdict) |
| | | self.assertEqual(request.matched_route.name, 'foo') |
| | | self.assertTrue(IFoo.providedBy(request)) |
| | |
| | | from pyramid.scripting import get_root |
| | | return get_root(app, request) |
| | | |
| | | def _makeRegistry(self): |
| | | return DummyRegistry([DummyFactory]) |
| | | |
| | | def test_it_norequest(self): |
| | | app = DummyApp(registry=dummy_registry) |
| | | registry = self._makeRegistry() |
| | | app = DummyApp(registry=registry) |
| | | root, closer = self._callFUT(app) |
| | | self.assertEqual(len(app.threadlocal_manager.pushed), 1) |
| | | pushed = app.threadlocal_manager.pushed[0] |
| | | self.assertEqual(pushed['registry'], dummy_registry) |
| | | self.assertEqual(pushed['registry'], registry) |
| | | self.assertEqual(pushed['request'].registry, app.registry) |
| | | self.assertEqual(len(app.threadlocal_manager.popped), 0) |
| | | closer() |
| | | self.assertEqual(len(app.threadlocal_manager.popped), 1) |
| | | |
| | | def test_it_withrequest(self): |
| | | app = DummyApp(registry=dummy_registry) |
| | | registry = self._makeRegistry() |
| | | app = DummyApp(registry=registry) |
| | | request = DummyRequest({}) |
| | | root, closer = self._callFUT(app, request) |
| | | self.assertEqual(len(app.threadlocal_manager.pushed), 1) |
| | | pushed = app.threadlocal_manager.pushed[0] |
| | | self.assertEqual(pushed['registry'], dummy_registry) |
| | | self.assertEqual(pushed['registry'], registry) |
| | | self.assertEqual(pushed['request'], request) |
| | | self.assertEqual(len(app.threadlocal_manager.popped), 0) |
| | | closer() |
| | | self.assertEqual(len(app.threadlocal_manager.popped), 1) |
| | | |
| | | def test_it_requestfactory_overridden(self): |
| | | app = DummyApp(registry=dummy_registry) |
| | | registry = self._makeRegistry() |
| | | app = DummyApp(registry=registry) |
| | | root, closer = self._callFUT(app) |
| | | self.assertEqual(len(app.threadlocal_manager.pushed), 1) |
| | | pushed = app.threadlocal_manager.pushed[0] |
| | |
| | | from pyramid.scripting import prepare |
| | | return prepare(request, registry) |
| | | |
| | | def _makeRegistry(self): |
| | | return DummyRegistry(DummyFactory) |
| | | def _makeRegistry(self, L=None): |
| | | if L is None: |
| | | L = [None, DummyFactory] |
| | | return DummyRegistry(L) |
| | | |
| | | def setUp(self): |
| | | from pyramid.threadlocal import manager |
| | |
| | | self.assertRaises(ConfigurationError, self._callFUT) |
| | | |
| | | def test_it_norequest(self): |
| | | registry = self._makeRegistry() |
| | | registry = self._makeRegistry([DummyFactory, None, DummyFactory]) |
| | | info = self._callFUT(registry=registry) |
| | | root, closer = info['root'], info['closer'] |
| | | root, closer, request = info['root'], info['closer'], info['request'] |
| | | pushed = self.manager.get() |
| | | self.assertEqual(pushed['registry'], registry) |
| | | self.assertEqual(pushed['request'].registry, registry) |
| | | self.assertEqual(root.a, (pushed['request'],)) |
| | | closer() |
| | | self.assertEqual(self.default, self.manager.get()) |
| | | self.assertEqual(request.context, root) |
| | | |
| | | def test_it_withrequest(self): |
| | | request = DummyRequest({}) |
| | | registry = request.registry = self._makeRegistry() |
| | | info = self._callFUT(request=request) |
| | | root, closer = info['root'], info['closer'] |
| | | root, closer, request = info['root'], info['closer'], info['request'] |
| | | pushed = self.manager.get() |
| | | self.assertEqual(pushed['request'], request) |
| | | self.assertEqual(pushed['registry'], registry) |
| | |
| | | self.assertEqual(root.a, (request,)) |
| | | closer() |
| | | self.assertEqual(self.default, self.manager.get()) |
| | | self.assertEqual(request.context, root) |
| | | |
| | | def test_it_with_request_and_registry(self): |
| | | request = DummyRequest({}) |
| | | registry = request.registry = self._makeRegistry() |
| | | info = self._callFUT(request=request, registry=registry) |
| | | root, closer = info['root'], info['closer'] |
| | | root, closer, root = info['root'], info['closer'], info['root'] |
| | | pushed = self.manager.get() |
| | | self.assertEqual(pushed['request'], request) |
| | | self.assertEqual(pushed['registry'], registry) |
| | |
| | | self.assertEqual(root.a, (request,)) |
| | | closer() |
| | | self.assertEqual(self.default, self.manager.get()) |
| | | self.assertEqual(request.context, root) |
| | | |
| | | def test_it_with_request_context_already_set(self): |
| | | request = DummyRequest({}) |
| | | context = Dummy() |
| | | request.context = context |
| | | registry = request.registry = self._makeRegistry() |
| | | info = self._callFUT(request=request, registry=registry) |
| | | root, closer, root = info['root'], info['closer'], info['root'] |
| | | closer() |
| | | self.assertEqual(request.context, context) |
| | | |
| | | def test_it_with_extensions(self): |
| | | exts = Dummy() |
| | | request = DummyRequest({}) |
| | | registry = request.registry = self._makeRegistry([exts, DummyFactory]) |
| | | info = self._callFUT(request=request, registry=registry) |
| | | self.assertEqual(request.extensions, exts) |
| | | root, closer = info['root'], info['closer'] |
| | | closer() |
| | | |
| | | class Test__make_request(unittest.TestCase): |
| | | def _callFUT(self, path='/', registry=None): |
| | | from pyramid.scripting import _make_request |
| | | return _make_request(path, registry) |
| | | |
| | | def _makeRegistry(self): |
| | | return DummyRegistry([DummyFactory]) |
| | | |
| | | def test_it_with_registry(self): |
| | | request = self._callFUT('/', dummy_registry) |
| | | registry = self._makeRegistry() |
| | | request = self._callFUT('/', registry) |
| | | self.assertEqual(request.environ['path'], '/') |
| | | self.assertEqual(request.registry, dummy_registry) |
| | | self.assertEqual(request.registry, registry) |
| | | |
| | | def test_it_with_no_registry(self): |
| | | from pyramid.config import global_registries |
| | | # keep registry local so that global_registries is cleared after |
| | | registry = DummyRegistry(DummyFactory) |
| | | registry = self._makeRegistry() |
| | | global_registries.add(registry) |
| | | try: |
| | | request = self._callFUT('/hello') |
| | |
| | | self.kw = kw |
| | | |
| | | class DummyRegistry(object): |
| | | def __init__(self, factory=None): |
| | | self.factory = factory |
| | | def __init__(self, utilities): |
| | | self.utilities = utilities |
| | | |
| | | def queryUtility(self, iface, default=None): |
| | | return self.factory or default |
| | | |
| | | dummy_registry = DummyRegistry(DummyFactory) |
| | | def queryUtility(self, iface, default=None): # pragma: no cover |
| | | if self.utilities: |
| | | return self.utilities.pop(0) |
| | | return default |
| | | |
| | | class DummyApp: |
| | | def __init__(self, registry=None): |
| | |
| | | self.popped.append(True) |
| | | |
| | | class DummyRequest: |
| | | matchdict = None |
| | | matched_route = None |
| | | def __init__(self, environ): |
| | | self.environ = environ |
| | | |
| | | |
| | | def _set_extensions(self, exts): |
| | | self.extensions = exts |
| | |
| | | import unittest |
| | | from pyramid import testing |
| | | |
| | | class TestGetSettings(unittest.TestCase): |
| | | def setUp(self): |
| | | from pyramid.registry import Registry |
| | | registry = Registry('testing') |
| | | self.config = testing.setUp(registry=registry) |
| | | 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 |
| | | return get_settings() |
| | | |
| | | def test_it_nosettings(self): |
| | | self.assertEqual(self._callFUT()['reload_templates'], False) |
| | | |
| | | def test_it_withsettings(self): |
| | | settings = {'a':1} |
| | | self.config.registry.settings = settings |
| | | self.assertEqual(self._callFUT(), settings) |
| | | |
| | | class Test_asbool(unittest.TestCase): |
| | | def _callFUT(self, s): |
| | |
| | | import unittest |
| | | from pyramid.compat import text_ |
| | | |
| | | class TestBase(unittest.TestCase): |
| | | def setUp(self): |
| | | from pyramid.threadlocal import manager |
| | | from pyramid.registry import Registry |
| | | manager.clear() |
| | | registry = Registry('testing') |
| | | self.registry = registry |
| | | manager.push({'registry':registry, 'request':None}) |
| | | from zope.deprecation import __show__ |
| | | __show__.off() |
| | | |
| | | def tearDown(self): |
| | | from pyramid.threadlocal import manager |
| | | manager.clear() |
| | | from zope.deprecation import __show__ |
| | | __show__.on() |
| | | |
| | | class Test_registerDummySecurityPolicy(TestBase): |
| | | def test_registerDummySecurityPolicy(self): |
| | | from pyramid import testing |
| | | testing.registerDummySecurityPolicy('user', ('group1', 'group2'), |
| | | permissive=False) |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | ut = self.registry.getUtility(IAuthenticationPolicy) |
| | | from pyramid.testing import DummySecurityPolicy |
| | | self.assertTrue(isinstance(ut, DummySecurityPolicy)) |
| | | ut = self.registry.getUtility(IAuthorizationPolicy) |
| | | self.assertEqual(ut.userid, 'user') |
| | | self.assertEqual(ut.groupids, ('group1', 'group2')) |
| | | self.assertEqual(ut.permissive, False) |
| | | |
| | | class Test_registerResources(TestBase): |
| | | def test_it(self): |
| | | class Dummy: |
| | | pass |
| | | ob1 = Dummy() |
| | | ob2 = Dummy() |
| | | resources = {'/ob1':ob1, '/ob2':ob2} |
| | | from pyramid import testing |
| | | testing.registerResources(resources) |
| | | from pyramid.interfaces import ITraverser |
| | | adapter = self.registry.getAdapter(None, ITraverser) |
| | | result = adapter(DummyRequest({'PATH_INFO':'/ob1'})) |
| | | self.assertEqual(result['context'], ob1) |
| | | self.assertEqual(result['view_name'], '') |
| | | self.assertEqual(result['subpath'], ()) |
| | | self.assertEqual(result['traversed'], (text_('ob1'),)) |
| | | self.assertEqual(result['virtual_root'], ob1) |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | result = adapter(DummyRequest({'PATH_INFO':'/ob2'})) |
| | | self.assertEqual(result['context'], ob2) |
| | | self.assertEqual(result['view_name'], '') |
| | | self.assertEqual(result['subpath'], ()) |
| | | self.assertEqual(result['traversed'], (text_('ob2'),)) |
| | | self.assertEqual(result['virtual_root'], ob2) |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | self.assertRaises(KeyError, adapter, DummyRequest({'PATH_INFO':'/ob3'})) |
| | | from pyramid.traversal import find_resource |
| | | self.assertEqual(find_resource(None, '/ob1'), ob1) |
| | | |
| | | class Test_registerTemplateRenderer(TestBase): |
| | | def test_registerTemplateRenderer(self): |
| | | from pyramid import testing |
| | | renderer = testing.registerTemplateRenderer('templates/foo') |
| | | from pyramid.testing import DummyTemplateRenderer |
| | | self.assertTrue(isinstance(renderer, DummyTemplateRenderer)) |
| | | from pyramid.renderers import render_to_response |
| | | render_to_response('templates/foo', dict(foo=1, bar=2)) |
| | | renderer.assert_(foo=1) |
| | | renderer.assert_(bar=2) |
| | | |
| | | def test_registerTemplateRenderer_explicitrenderer(self): |
| | | from pyramid import testing |
| | | def renderer(kw, system): |
| | | self.assertEqual(kw, {'foo':1, 'bar':2}) |
| | | renderer = testing.registerTemplateRenderer('templates/foo', renderer) |
| | | from pyramid.renderers import render_to_response |
| | | render_to_response('templates/foo', dict(foo=1, bar=2)) |
| | | |
| | | class Test_registerEventListener(TestBase): |
| | | def test_registerEventListener_single(self): |
| | | from pyramid import testing |
| | | L = testing.registerEventListener(IDummy) |
| | | event = DummyEvent() |
| | | self.registry.notify(event) |
| | | self.assertEqual(len(L), 1) |
| | | self.assertEqual(L[0], event) |
| | | self.registry.notify(object()) |
| | | self.assertEqual(len(L), 1) |
| | | |
| | | def test_registerEventListener_multiple(self): |
| | | from pyramid import testing |
| | | L = testing.registerEventListener((Interface, IDummy)) |
| | | event = DummyEvent() |
| | | event.object = 'foo' |
| | | # the below is the equivalent of z.c.event.objectEventNotify(event) |
| | | self.registry.subscribers((event.object, event), None) |
| | | self.assertEqual(len(L), 2) |
| | | self.assertEqual(L[0], 'foo') |
| | | self.assertEqual(L[1], event) |
| | | |
| | | def test_registerEventListener_defaults(self): |
| | | from pyramid import testing |
| | | L = testing.registerEventListener() |
| | | event = object() |
| | | self.registry.notify(event) |
| | | self.assertEqual(L[-1], event) |
| | | event2 = object() |
| | | self.registry.notify(event2) |
| | | self.assertEqual(L[-1], event2) |
| | | |
| | | class Test_registerView(TestBase): |
| | | def test_registerView_defaults(self): |
| | | from pyramid import testing |
| | | view = testing.registerView('moo.html') |
| | | import types |
| | | self.assertTrue(isinstance(view, types.FunctionType)) |
| | | from pyramid.view import render_view_to_response |
| | | request = DummyRequest() |
| | | request.registry = self.registry |
| | | response = render_view_to_response(None, request, 'moo.html') |
| | | self.assertEqual(view(None, None).body, response.body) |
| | | |
| | | def test_registerView_withresult(self): |
| | | from pyramid import testing |
| | | view = testing.registerView('moo.html', 'yo') |
| | | import types |
| | | self.assertTrue(isinstance(view, types.FunctionType)) |
| | | from pyramid.view import render_view_to_response |
| | | request = DummyRequest() |
| | | request.registry = self.registry |
| | | response = render_view_to_response(None, request, 'moo.html') |
| | | self.assertEqual(response.body, b'yo') |
| | | |
| | | def test_registerView_custom(self): |
| | | from pyramid import testing |
| | | def view(context, request): |
| | | from webob import Response |
| | | return Response('123') |
| | | view = testing.registerView('moo.html', view=view) |
| | | import types |
| | | self.assertTrue(isinstance(view, types.FunctionType)) |
| | | from pyramid.view import render_view_to_response |
| | | request = DummyRequest() |
| | | request.registry = self.registry |
| | | response = render_view_to_response(None, request, 'moo.html') |
| | | self.assertEqual(response.body, b'123') |
| | | |
| | | def test_registerView_with_permission_denying(self): |
| | | from pyramid import testing |
| | | from pyramid.httpexceptions import HTTPForbidden |
| | | def view(context, request): |
| | | """ """ |
| | | view = testing.registerView('moo.html', view=view, permission='bar') |
| | | testing.registerDummySecurityPolicy(permissive=False) |
| | | import types |
| | | self.assertTrue(isinstance(view, types.FunctionType)) |
| | | from pyramid.view import render_view_to_response |
| | | request = DummyRequest() |
| | | request.registry = self.registry |
| | | self.assertRaises(HTTPForbidden, render_view_to_response, |
| | | None, request, 'moo.html') |
| | | |
| | | def test_registerView_with_permission_denying2(self): |
| | | from pyramid import testing |
| | | from pyramid.security import view_execution_permitted |
| | | def view(context, request): |
| | | """ """ |
| | | view = testing.registerView('moo.html', view=view, permission='bar') |
| | | testing.registerDummySecurityPolicy(permissive=False) |
| | | import types |
| | | self.assertTrue(isinstance(view, types.FunctionType)) |
| | | result = view_execution_permitted(None, None, 'moo.html') |
| | | self.assertEqual(result, False) |
| | | |
| | | def test_registerView_with_permission_allowing(self): |
| | | from pyramid import testing |
| | | def view(context, request): |
| | | from webob import Response |
| | | return Response('123') |
| | | view = testing.registerView('moo.html', view=view, permission='bar') |
| | | testing.registerDummySecurityPolicy(permissive=True) |
| | | import types |
| | | self.assertTrue(isinstance(view, types.FunctionType)) |
| | | from pyramid.view import render_view_to_response |
| | | request = DummyRequest() |
| | | request.registry = self.registry |
| | | result = render_view_to_response(None, request, 'moo.html') |
| | | self.assertEqual(result.app_iter, [b'123']) |
| | | |
| | | |
| | | class Test_registerAdapter(TestBase): |
| | | def test_registerAdapter(self): |
| | | from zope.interface import Interface |
| | | class provides(Interface): |
| | | pass |
| | | class Provider: |
| | | pass |
| | | class for_(Interface): |
| | | pass |
| | | from pyramid import testing |
| | | testing.registerAdapter(Provider, (for_, for_), provides, name='foo') |
| | | adapter = self.registry.adapters.lookup( |
| | | (for_, for_), provides, name='foo') |
| | | self.assertEqual(adapter, Provider) |
| | | |
| | | def test_registerAdapter_notlist(self): |
| | | from zope.interface import Interface |
| | | class provides(Interface): |
| | | pass |
| | | class Provider: |
| | | pass |
| | | class for_(Interface): |
| | | pass |
| | | from pyramid import testing |
| | | testing.registerAdapter(Provider, for_, provides, name='foo') |
| | | adapter = self.registry.adapters.lookup( |
| | | (for_,), provides, name='foo') |
| | | self.assertEqual(adapter, Provider) |
| | | |
| | | class Test_registerUtility(TestBase): |
| | | def test_registerUtility(self): |
| | | from zope.interface import implementer |
| | | from zope.interface import Interface |
| | | class iface(Interface): |
| | | pass |
| | | @implementer(iface) |
| | | class impl: |
| | | def __call__(self): |
| | | return 'foo' |
| | | utility = impl() |
| | | from pyramid import testing |
| | | testing.registerUtility(utility, iface, name='mudge') |
| | | self.assertEqual(self.registry.getUtility(iface, name='mudge')(), 'foo') |
| | | |
| | | class Test_registerSubscriber(TestBase): |
| | | def test_it(self): |
| | | from pyramid import testing |
| | | L = [] |
| | | def subscriber(event): |
| | | L.append(event) |
| | | testing.registerSubscriber(subscriber, iface=IDummy) |
| | | event = DummyEvent() |
| | | self.registry.notify(event) |
| | | self.assertEqual(len(L), 1) |
| | | self.assertEqual(L[0], event) |
| | | self.registry.notify(object()) |
| | | self.assertEqual(len(L), 1) |
| | | |
| | | class Test_registerRoute(TestBase): |
| | | def test_registerRoute(self): |
| | | from pyramid.config import Configurator |
| | | from pyramid.request import Request |
| | | from pyramid.interfaces import IRoutesMapper |
| | | from pyramid.testing import registerRoute |
| | | registerRoute(':pagename', 'home', DummyFactory) |
| | | mapper = self.registry.getUtility(IRoutesMapper) |
| | | self.assertEqual(len(mapper.routelist), 1) |
| | | request = Request.blank('/') |
| | | request.registry = self.registry |
| | | config = Configurator(registry=self.registry) |
| | | config.setup_registry() |
| | | self.assertEqual(request.route_url('home', pagename='abc'), |
| | | 'http://localhost/abc') |
| | | |
| | | class Test_registerSettings(TestBase): |
| | | def test_registerSettings(self): |
| | | from pyramid.interfaces import ISettings |
| | | from pyramid.testing import registerSettings |
| | | registerSettings({'a':1, 'b':2}) |
| | | settings = self.registry.getUtility(ISettings) |
| | | self.assertEqual(settings['a'], 1) |
| | | self.assertEqual(settings['b'], 2) |
| | | registerSettings(b=3, c=4) |
| | | settings = self.registry.getUtility(ISettings) |
| | | self.assertEqual(settings['a'], 1) |
| | | self.assertEqual(settings['b'], 3) |
| | | self.assertEqual(settings['c'], 4) |
| | | |
| | | class TestDummyRootFactory(unittest.TestCase): |
| | | def _makeOne(self, environ): |
| | |
| | | class DummyEvent: |
| | | pass |
| | | |
| | | |
| | | class DummyRequest: |
| | | application_url = 'http://example.com' |
| | | def __init__(self, environ=None): |
| | | if environ is None: |
| | | environ = {} |
| | | self.environ = environ |
| | | |
| | | class DummyFactory: |
| | | def __init__(self, environ): |
| | | """ """ |
| | |
| | | context = DummyContext() |
| | | verifyObject(ITraverser, self._makeOne(context)) |
| | | |
| | | def test_call_with_no_pathinfo(self): |
| | | def test_call_with_empty_pathinfo(self): |
| | | policy = self._makeOne(None) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ) |
| | | request = DummyRequest(environ, path_info='') |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], None) |
| | | self.assertEqual(result['view_name'], '') |
| | | self.assertEqual(result['subpath'], ()) |
| | | self.assertEqual(result['traversed'], ()) |
| | | self.assertEqual(result['root'], policy.root) |
| | | self.assertEqual(result['virtual_root'], policy.root) |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_with_pathinfo_KeyError(self): |
| | | policy = self._makeOne(None) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, toraise=KeyError) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], None) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_with_pathinfo_highorder(self): |
| | | foo = DummyContext(None, text_(b'Qu\xc3\xa9bec', 'utf-8')) |
| | | path = text_(b'/Qu\xc3\xa9bec', 'utf-8') |
| | | foo = DummyContext(None, path) |
| | | root = DummyContext(foo, 'root') |
| | | policy = self._makeOne(root) |
| | | if PY3: # pragma: no cover |
| | | path_info = b'/Qu\xc3\xa9bec'.decode('latin-1') |
| | | else: |
| | | path_info = b'/Qu\xc3\xa9bec' |
| | | environ = self._getEnviron(PATH_INFO=path_info) |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, path_info=path) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], foo) |
| | | self.assertEqual(result['view_name'], '') |
| | | self.assertEqual(result['subpath'], ()) |
| | | self.assertEqual( |
| | | result['traversed'], |
| | | (text_(b'Qu\xc3\xa9bec', 'utf-8'),) |
| | | ) |
| | | self.assertEqual(result['traversed'], (path[1:],)) |
| | | self.assertEqual(result['root'], policy.root) |
| | | self.assertEqual(result['virtual_root'], policy.root) |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_pathel_with_no_getitem(self): |
| | | policy = self._makeOne(None) |
| | | environ = self._getEnviron(PATH_INFO='/foo/bar') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, path_info=text_('/foo/bar')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], None) |
| | | self.assertEqual(result['view_name'], 'foo') |
| | |
| | | def test_call_withconn_getitem_emptypath_nosubpath(self): |
| | | root = DummyContext() |
| | | policy = self._makeOne(root) |
| | | environ = self._getEnviron(PATH_INFO='') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, path_info=text_('')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], root) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | foo = DummyContext() |
| | | root = DummyContext(foo) |
| | | policy = self._makeOne(root) |
| | | environ = self._getEnviron(PATH_INFO='/foo/bar') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, path_info=text_('/foo/bar')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], foo) |
| | | self.assertEqual(result['view_name'], 'bar') |
| | |
| | | foo = DummyContext() |
| | | root = DummyContext(foo) |
| | | policy = self._makeOne(root) |
| | | environ = self._getEnviron(PATH_INFO='/foo/bar/baz/buz') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], foo) |
| | | self.assertEqual(result['view_name'], 'bar') |
| | |
| | | foo = DummyContext() |
| | | root = DummyContext(foo) |
| | | policy = self._makeOne(root) |
| | | environ = self._getEnviron(PATH_INFO='/@@foo') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | request = DummyRequest(environ, path_info=text_('/@@foo')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], root) |
| | | self.assertEqual(result['view_name'], 'foo') |
| | |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_with_vh_root(self): |
| | | environ = self._getEnviron(PATH_INFO='/baz', |
| | | HTTP_X_VHM_ROOT='/foo/bar') |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar') |
| | | baz = DummyContext(None, 'baz') |
| | | bar = DummyContext(baz, 'bar') |
| | | foo = DummyContext(bar, 'foo') |
| | | root = DummyContext(foo, 'root') |
| | | policy = self._makeOne(root) |
| | | request = DummyRequest(environ) |
| | | request = DummyRequest(environ, path_info=text_('/baz')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], baz) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | (text_('foo'), text_('bar'))) |
| | | |
| | | def test_call_with_vh_root2(self): |
| | | environ = self._getEnviron(PATH_INFO='/bar/baz', |
| | | HTTP_X_VHM_ROOT='/foo') |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo') |
| | | baz = DummyContext(None, 'baz') |
| | | bar = DummyContext(baz, 'bar') |
| | | foo = DummyContext(bar, 'foo') |
| | | root = DummyContext(foo, 'root') |
| | | policy = self._makeOne(root) |
| | | request = DummyRequest(environ) |
| | | request = DummyRequest(environ, path_info=text_('/bar/baz')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], baz) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | self.assertEqual(result['virtual_root_path'], (text_('foo'),)) |
| | | |
| | | def test_call_with_vh_root3(self): |
| | | environ = self._getEnviron(PATH_INFO='/foo/bar/baz', |
| | | HTTP_X_VHM_ROOT='/') |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT='/') |
| | | baz = DummyContext() |
| | | bar = DummyContext(baz) |
| | | foo = DummyContext(bar) |
| | | root = DummyContext(foo) |
| | | policy = self._makeOne(root) |
| | | request = DummyRequest(environ) |
| | | request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], baz) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_with_vh_root4(self): |
| | | environ = self._getEnviron(PATH_INFO='/', |
| | | HTTP_X_VHM_ROOT='/foo/bar/baz') |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar/baz') |
| | | baz = DummyContext(None, 'baz') |
| | | bar = DummyContext(baz, 'bar') |
| | | foo = DummyContext(bar, 'foo') |
| | | root = DummyContext(foo, 'root') |
| | | policy = self._makeOne(root) |
| | | request = DummyRequest(environ) |
| | | request = DummyRequest(environ, path_info=text_('/')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], baz) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | |
| | | def test_call_with_vh_root_path_root(self): |
| | | policy = self._makeOne(None) |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT='/', |
| | | PATH_INFO='/') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT='/') |
| | | request = DummyRequest(environ, path_info=text_('/')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], None) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_with_vh_root_highorder(self): |
| | | path = text_(b'Qu\xc3\xa9bec', 'utf-8') |
| | | bar = DummyContext(None, 'bar') |
| | | foo = DummyContext(bar, text_(b'Qu\xc3\xa9bec', 'utf-8')) |
| | | foo = DummyContext(bar, path) |
| | | root = DummyContext(foo, 'root') |
| | | policy = self._makeOne(root) |
| | | if PY3: # pragma: no cover |
| | | vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') |
| | | else: |
| | | vhm_root = b'/Qu\xc3\xa9bec' |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root, |
| | | PATH_INFO='/bar') |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) |
| | | request = DummyRequest(environ, path_info=text_('/bar')) |
| | | result = policy(request) |
| | | self.assertEqual(result['context'], bar) |
| | | self.assertEqual(result['view_name'], '') |
| | | self.assertEqual(result['subpath'], ()) |
| | | self.assertEqual( |
| | | result['traversed'], |
| | | (text_(b'Qu\xc3\xa9bec', 'utf-8'), text_('bar')) |
| | | (path, text_('bar')) |
| | | ) |
| | | self.assertEqual(result['root'], policy.root) |
| | | self.assertEqual(result['virtual_root'], foo) |
| | | self.assertEqual( |
| | | result['virtual_root_path'], |
| | | (text_(b'Qu\xc3\xa9bec', 'utf-8'),) |
| | | (path,) |
| | | ) |
| | | |
| | | def test_non_utf8_path_segment_unicode_path_segments_fails(self): |
| | | def test_path_info_raises_unicodedecodeerror(self): |
| | | from pyramid.exceptions import URLDecodeError |
| | | foo = DummyContext() |
| | | root = DummyContext(foo) |
| | | policy = self._makeOne(root) |
| | | segment = native_(text_(b'LaPe\xc3\xb1a', 'utf-8'), 'utf-16') |
| | | environ = self._getEnviron(PATH_INFO='/%s' % segment) |
| | | request = DummyRequest(environ) |
| | | self.assertRaises(URLDecodeError, policy, request) |
| | | |
| | | def test_non_utf8_path_segment_settings_unicode_path_segments_fails(self): |
| | | from pyramid.exceptions import URLDecodeError |
| | | foo = DummyContext() |
| | | root = DummyContext(foo) |
| | | policy = self._makeOne(root) |
| | | segment = native_(text_(b'LaPe\xc3\xb1a', 'utf-8'), 'utf-16') |
| | | environ = self._getEnviron(PATH_INFO='/%s' % segment) |
| | | request = DummyRequest(environ) |
| | | environ = self._getEnviron() |
| | | toraise = UnicodeDecodeError('ascii', b'a', 2, 3, '5') |
| | | request = DummyRequest(environ, toraise=toraise) |
| | | request.matchdict = None |
| | | self.assertRaises(URLDecodeError, policy, request) |
| | | |
| | | def test_withroute_nothingfancy(self): |
| | | resource = DummyContext() |
| | | traverser = self._makeOne(resource) |
| | | environ = {'bfg.routes.matchdict': {}} |
| | | request = DummyRequest(environ) |
| | | request = DummyRequest({}) |
| | | request.matchdict = {} |
| | | result = traverser(request) |
| | | self.assertEqual(result['context'], resource) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | def test_withroute_with_subpath_string(self): |
| | | resource = DummyContext() |
| | | traverser = self._makeOne(resource) |
| | | environ = {'bfg.routes.matchdict': {'subpath':'/a/b/c'}} |
| | | request = DummyRequest(environ) |
| | | matchdict = {'subpath':'/a/b/c'} |
| | | request = DummyRequest({}) |
| | | request.matchdict = matchdict |
| | | result = traverser(request) |
| | | self.assertEqual(result['context'], resource) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | def test_withroute_with_subpath_tuple(self): |
| | | resource = DummyContext() |
| | | traverser = self._makeOne(resource) |
| | | environ = {'bfg.routes.matchdict': {'subpath':('a', 'b', 'c')}} |
| | | request = DummyRequest(environ) |
| | | matchdict = {'subpath':('a', 'b', 'c')} |
| | | request = DummyRequest({}) |
| | | request.matchdict = matchdict |
| | | result = traverser(request) |
| | | self.assertEqual(result['context'], resource) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | def test_withroute_and_traverse_string(self): |
| | | resource = DummyContext() |
| | | traverser = self._makeOne(resource) |
| | | environ = {'bfg.routes.matchdict': {'traverse':'foo/bar'}} |
| | | request = DummyRequest(environ) |
| | | matchdict = {'traverse':text_('foo/bar')} |
| | | request = DummyRequest({}) |
| | | request.matchdict = matchdict |
| | | result = traverser(request) |
| | | self.assertEqual(result['context'], resource) |
| | | self.assertEqual(result['view_name'], 'foo') |
| | |
| | | def test_withroute_and_traverse_tuple(self): |
| | | resource = DummyContext() |
| | | traverser = self._makeOne(resource) |
| | | environ = {'bfg.routes.matchdict': {'traverse':('foo', 'bar')}} |
| | | request = DummyRequest(environ) |
| | | matchdict = {'traverse':('foo', 'bar')} |
| | | request = DummyRequest({}) |
| | | request.matchdict = matchdict |
| | | result = traverser(request) |
| | | self.assertEqual(result['context'], resource) |
| | | self.assertEqual(result['view_name'], 'foo') |
| | |
| | | def test_withroute_and_traverse_empty(self): |
| | | resource = DummyContext() |
| | | traverser = self._makeOne(resource) |
| | | environ = {'bfg.routes.matchdict': {'traverse':''}} |
| | | request = DummyRequest(environ) |
| | | matchdict = {'traverse':''} |
| | | request = DummyRequest({}) |
| | | request.matchdict = matchdict |
| | | result = traverser(request) |
| | | self.assertEqual(result['context'], resource) |
| | | self.assertEqual(result['view_name'], '') |
| | |
| | | self.assertEqual(result['root'], resource) |
| | | self.assertEqual(result['virtual_root'], resource) |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | |
| | | def test_call_with_environ(self): |
| | | with warnings.catch_warnings(record=True) as w: |
| | | warnings.filterwarnings('always') |
| | | policy = self._makeOne(None) |
| | | environ = self._getEnviron() |
| | | result = policy(environ) |
| | | self.assertEqual(result['context'], None) |
| | | self.assertEqual(result['view_name'], '') |
| | | self.assertEqual(result['subpath'], ()) |
| | | self.assertEqual(result['traversed'], ()) |
| | | self.assertEqual(result['root'], policy.root) |
| | | self.assertEqual(result['virtual_root'], policy.root) |
| | | self.assertEqual(result['virtual_root_path'], ()) |
| | | self.assertEqual(len(w), 1) |
| | | |
| | | class FindInterfaceTests(unittest.TestCase): |
| | | def _callFUT(self, context, iface): |
| | |
| | | return '<DummyContext with name %s at id %s>'%(self.__name__, id(self)) |
| | | |
| | | class DummyRequest: |
| | | |
| | | application_url = 'http://example.com:5432' # app_url never ends with slash |
| | | def __init__(self, environ=None): |
| | | matchdict = None |
| | | matched_route = None |
| | | |
| | | def __init__(self, environ=None, path_info=text_('/'), toraise=None): |
| | | if environ is None: |
| | | environ = {} |
| | | self.environ = environ |
| | | self._set_path_info(path_info) |
| | | self.toraise = toraise |
| | | |
| | | def _get_path_info(self): |
| | | if self.toraise: |
| | | raise self.toraise |
| | | return self._path_info |
| | | |
| | | def _set_path_info(self, v): |
| | | self._path_info = v |
| | | |
| | | path_info = property(_get_path_info, _set_path_info) |
| | | |
| | | |
| | | class DummyContextURL: |
| | | def __init__(self, context, request): |
| | |
| | | self.assertEqual(1, foo.x) |
| | | self.assertEqual(2, foo.y) |
| | | |
| | | def test__set_extensions(self): |
| | | inst = self._makeOne() |
| | | def foo(self, result): |
| | | return result |
| | | n, bar = inst._make_property(lambda _: 'bar', name='bar') |
| | | class Extensions(object): |
| | | def __init__(self): |
| | | self.methods = {'foo':foo} |
| | | self.descriptors = {'bar':bar} |
| | | extensions = Extensions() |
| | | inst._set_extensions(extensions) |
| | | self.assertEqual(inst.bar, 'bar') |
| | | self.assertEqual(inst.foo('abc'), 'abc') |
| | | |
| | | class Test_WeakOrderedSet(unittest.TestCase): |
| | | def _makeOne(self): |
| | | from pyramid.config import WeakOrderedSet |
| | |
| | | _segment_cache[(segment, safe)] = result |
| | | return result |
| | | |
| | | slash = text_('/') |
| | | |
| | | @implementer(ITraverser) |
| | | class ResourceTreeTraverser(object): |
| | |
| | | self.root = root |
| | | |
| | | def __call__(self, request): |
| | | try: |
| | | environ = request.environ |
| | | except AttributeError: |
| | | # In BFG 1.0 and before, this API expected an environ |
| | | # rather than a request; some bit of code may still be |
| | | # passing us an environ. If so, deal. |
| | | environ = request |
| | | depwarn = ('Passing an environ dictionary directly to a traverser ' |
| | | 'is deprecated in Pyramid 1.1. Pass a request object ' |
| | | 'instead.') |
| | | warnings.warn(depwarn, DeprecationWarning, 2) |
| | | environ = request.environ |
| | | matchdict = request.matchdict |
| | | |
| | | if 'bfg.routes.matchdict' in environ: |
| | | matchdict = environ['bfg.routes.matchdict'] |
| | | if matchdict is not None: |
| | | |
| | | path = matchdict.get('traverse', '/') or '/' |
| | | path = matchdict.get('traverse', slash) or slash |
| | | if is_nonstr_iter(path): |
| | | # this is a *traverse stararg (not a {traverse}) |
| | | # routing has already decoded these elements, so we just |
| | | # need to join them |
| | | path = '/'.join(path) or '/' |
| | | path = slash.join(path) or slash |
| | | |
| | | subpath = matchdict.get('subpath', ()) |
| | | if not is_nonstr_iter(subpath): |
| | |
| | | subpath = () |
| | | try: |
| | | # empty if mounted under a path in mod_wsgi, for example |
| | | path = decode_path_info(environ['PATH_INFO'] or '/') |
| | | path = request.path_info or slash |
| | | except KeyError: |
| | | path = '/' |
| | | # if environ['PATH_INFO'] is just not there |
| | | path = slash |
| | | except UnicodeDecodeError as e: |
| | | raise URLDecodeError(e.encoding, e.object, e.start, e.end, |
| | | e.reason) |
| | |
| | | root = self.root |
| | | ob = vroot = root |
| | | |
| | | if vpath == '/': # invariant: vpath must not be empty |
| | | if vpath == slash: # invariant: vpath must not be empty |
| | | # prevent a call to traversal_path if we know it's going |
| | | # to return the empty tuple |
| | | vpath_tuple = () |
| | |
| | | import weakref |
| | | |
| | | from pyramid.compat import ( |
| | | iteritems_, |
| | | integer_types, |
| | | string_types, |
| | | text_, |
| | |
| | | cls = type(parent.__name__, (parent, object), attrs) |
| | | self.__class__ = cls |
| | | |
| | | def _set_extensions(self, extensions): |
| | | for name, fn in iteritems_(extensions.methods): |
| | | method = fn.__get__(self, self.__class__) |
| | | setattr(self, name, method) |
| | | self._set_properties(extensions.descriptors) |
| | | |
| | | def set_property(self, callable, name=None, reify=False): |
| | | """ Add a callable or a property descriptor to the instance. |
| | | |
| | |
| | | 'setuptools', |
| | | 'Chameleon >= 1.2.3', |
| | | 'Mako >= 0.3.6', # strict_undefined |
| | | 'WebOb >= 1.2dev', # response.text / py3 compat |
| | | 'WebOb >= 1.2b3', # request.path_info is unicode |
| | | 'repoze.lru >= 0.4', # py3 compat |
| | | 'zope.interface >= 3.8.0', # has zope.interface.registry |
| | | 'zope.deprecation >= 3.5.0', # py3 compat |
| | |
| | | |
| | | [testenv] |
| | | commands = |
| | | python setup.py dev |
| | | python setup.py test -q |
| | | deps = |
| | | zope.component |
| | | Sphinx |
| | | repoze.sphinx.autointerface |
| | | WebTest |
| | | virtualenv |
| | | venusian |
| | | |
| | | [testenv:py32] |
| | | commands = |
| | | python setup.py test -q |
| | | deps = |
| | | WebTest |
| | | virtualenv |
| | | venusian |
| | | |
| | | [testenv:py33] |
| | | commands = |
| | | python setup.py test -q |
| | | deps = |
| | | WebTest |
| | | virtualenv |
| | | venusian |
| | | |
| | | [testenv:cover] |
| | | basepython = |
| | | python2.6 |
| | | commands = |
| | | python setup.py dev |
| | | python setup.py nosetests --with-xunit --with-xcoverage |
| | | deps = |
| | | zope.component |
| | | Sphinx |
| | | WebTest |
| | | repoze.sphinx.autointerface |
| | | virtualenv |
| | | venusian |
| | | nose |
| | | coverage |
| | | nosexcover |
| | | |
| | | # we separate coverage into its own testenv because a) "last run wins" wrt |