- The ``make_app`` function has been removed from the ``pyramid.router``
module. It continues life within the ``pyramid_zcml`` package. This
leaves the ``pyramid.router`` module without any API functions.
- The ``configure_zcml`` setting within the deployment settings (within
``**settings`` passed to a Pyramid ``main`` function) has ceased to have any
meaning.
- The ``starter_zcml`` paster template has been moved to the ``pyramid_zcml``
package.
- The ``bfg2pyramid`` script now converts ZCML include tags that have
``repoze.bfg.includes`` as a package attribute to the value
``pyramid_zcml``. For example, ``<include package="repoze.bfg.includes">``
will be converted to ``<include package="pyramid_zcml">``.
- The ``load_zcml`` method of a Configurator has been removed from the
Pyramid core. Loading ZCML is now a feature of the ``pyramid_zcml``
package, which can be downloaded from PyPI. Documentation for the package
should be available via http://pylonsproject.org, which describes how to
get this method back after depending upon ``pyramid_zcml`` as an
``install_requires`` dependency.
- The ``pyramid.includes`` subpackage has been removed. ZCML files which use
include the package ``pyramid.includes`` (e.g. ``<include
package="pyramid.includes">``) now must include the ``pyramid_zcml``
package instead (e.g. ``<include package="pyramid_zcml"/>).
- The "Declarative Configuration" narrative chapter has been removed (it was
moved to the ``pyramid_zcml`` pakcage).
- The add_directive method now accepts an "action_wrap" flag.
- Fix some orphaned references.
- Remove some docstring references to ZCML directives.
- All integration test fixtures have been changed to use imperative
configuration rather than ZCML configuration.
43 files deleted
27 files modified
| | |
| | | templates were removed. Use ``pyramid_sqla`` (available from PyPI) as a |
| | | generic replacement for Pylons-esque development. |
| | | |
| | | - The ``make_app`` function has been removed from the ``pyramid.router`` |
| | | module. It continues life within the ``pyramid_zcml`` package. This |
| | | leaves the ``pyramid.router`` module without any API functions. |
| | | |
| | | - The ``configure_zcml`` setting within the deployment settings (within |
| | | ``**settings`` passed to a Pyramid ``main`` function) has ceased to have any |
| | | meaning. |
| | | |
| | | - The ``starter_zcml`` paster template has been moved to the ``pyramid_zcml`` |
| | | package. |
| | | |
| | | Features |
| | | -------- |
| | | |
| | |
| | | ``config.include('some.module.somefunc')`` as long as the include function |
| | | within ``some.module`` is named ``includeme``. |
| | | |
| | | - The ``bfg2pyramid`` script now converts ZCML include tags that have |
| | | ``repoze.bfg.includes`` as a package attribute to the value |
| | | ``pyramid_zcml``. For example, ``<include package="repoze.bfg.includes">`` |
| | | will be converted to ``<include package="pyramid_zcml">``. |
| | | |
| | | Paster Templates |
| | | ---------------- |
| | | |
| | |
| | | api/renderers |
| | | api/request |
| | | api/response |
| | | api/router |
| | | api/scripting |
| | | api/security |
| | | api/session |
| | |
| | | |
| | | .. automethod:: derive_view |
| | | |
| | | .. automethod:: load_zcml(spec) |
| | | |
| | | .. automethod:: make_wsgi_app() |
| | | |
| | | .. automethod:: override_asset(to_override, override_with) |
| | |
| | | narr/testing |
| | | narr/hooks |
| | | narr/advconfig |
| | | narr/declarative |
| | | narr/extending |
| | | narr/router |
| | | narr/threadlocals |
| | |
| | | narr/testing |
| | | narr/hooks |
| | | narr/advconfig |
| | | narr/declarative |
| | | narr/extending |
| | | narr/router |
| | | narr/startup |
| | | narr/threadlocals |
| | | narr/zca |
| | |
| | | import re |
| | | import sys |
| | | import types |
| | | import threading |
| | | import traceback |
| | | |
| | | import venusian |
| | | |
| | | from translationstring import ChameleonTranslate |
| | | |
| | | from zope.configuration import xmlconfig |
| | | from zope.configuration.config import GroupingContextDecorator |
| | | from zope.configuration.config import ConfigurationMachine |
| | | from zope.configuration.xmlconfig import registerCommonDirectives |
| | |
| | | config = self.__class__.with_context(context) |
| | | c(config) |
| | | |
| | | def add_directive(self, name, directive): |
| | | def add_directive(self, name, directive, action_wrap=True): |
| | | """ |
| | | Add a directive method to the configurator. |
| | | |
| | |
| | | keyword arguments following. It should use config.action as |
| | | necessary to perform actions. Directive methods can then be invoked |
| | | like 'built-in' directives such as ``add_view``, ``add_route``, etc. |
| | | |
| | | The ``action_wrap`` argument should be ``True`` for directives which |
| | | perform ``config.action`` with potentially conflicting |
| | | discriminators. ``action_wrap`` will cause the directive to be |
| | | wrapped in a decorator which provides more accurate conflict |
| | | cause information. |
| | | |
| | | ``add_directive`` does not participate in conflict detection, and |
| | | later calls to ``add_directive`` will override earlier calls. |
| | |
| | | c = self.maybe_dotted(directive) |
| | | if not hasattr(self.registry, '_directives'): |
| | | self.registry._directives = {} |
| | | self.registry._directives[name] = c |
| | | self.registry._directives[name] = (c, action_wrap) |
| | | |
| | | def __getattr__(self, name): |
| | | # allow directive extension names to work |
| | |
| | | c = directives.get(name) |
| | | if c is None: |
| | | raise AttributeError(name) |
| | | c = action_method(c) |
| | | c, action_wrap = c |
| | | if action_wrap: |
| | | c = action_method(c) |
| | | m = types.MethodType(c, self, self.__class__) |
| | | return m |
| | | |
| | |
| | | finally: |
| | | self.manager.pop() |
| | | return app |
| | | |
| | | def load_zcml(self, spec='configure.zcml', lock=threading.Lock()): |
| | | """ Load configuration from a :term:`ZCML` file into the |
| | | current configuration state. The ``spec`` argument is an |
| | | absolute filename, a relative filename, or a :term:`asset |
| | | specification`, defaulting to ``configure.zcml`` (relative to |
| | | the package of the configurator's caller).""" |
| | | package_name, filename = self._split_spec(spec) |
| | | if package_name is None: # absolute filename |
| | | package = self.package |
| | | else: |
| | | __import__(package_name) |
| | | package = sys.modules[package_name] |
| | | |
| | | registry = self.registry |
| | | self.manager.push({'registry':registry, 'request':None}) |
| | | context = self._ctx |
| | | if context is None: |
| | | context = self._ctx = self._make_context(self.autocommit) |
| | | |
| | | # To avoid breaking people's expectations of how ZCML works, we |
| | | # cannot autocommit ZCML actions incrementally. If we commit actions |
| | | # incrementally, configuration outcome will be controlled purely by |
| | | # ZCML directive execution order, which isn't what anyone who uses |
| | | # ZCML expects. So we don't autocommit each ZCML directive action |
| | | # while parsing is happening, but we do make sure to pass |
| | | # execute=self.autocommit to xmlconfig.file below, which will cause |
| | | # the actions implied by the ZCML that was parsed to be committed |
| | | # right away once parsing is finished if autocommit is True. |
| | | context = GroupingContextDecorator(context) |
| | | context.autocommit = False |
| | | |
| | | lock.acquire() |
| | | try: |
| | | context.package = package |
| | | xmlconfig.file(filename, package, context=context, |
| | | execute=self.autocommit) |
| | | finally: |
| | | lock.release() |
| | | self.manager.pop() |
| | | return registry |
| | | |
| | | @action_method |
| | | def add_view(self, view=None, name="", for_=None, permission=None, |
| | |
| | | |
| | | BFG_NS_RE = r'xmlns\s*?=\s*?[\'\"]http://namespaces\.repoze\.org/bfg[\'\"]' |
| | | BFG_IN_ATTR = r'(repoze\.bfg)(%s)' % MODULE_ALTERNATIVES |
| | | BFG_INCLUDE_IN_ATTR = r'repoze\.bfg\.includes' |
| | | ATTR = re.compile(BFG_IN_ATTR, re.MULTILINE) |
| | | INCLUDE_ATTR = re.compile(BFG_INCLUDE_IN_ATTR, re.MULTILINE) |
| | | NS = re.compile(BFG_NS_RE, re.MULTILINE) |
| | | |
| | | def replace(match): |
| | |
| | | absfile = os.path.join(root, file) |
| | | text = open(absfile, 'rb').read() |
| | | newt = NS.sub('xmlns="http://pylonshq.com/pyramid"', text) |
| | | newt = INCLUDE_ATTR.sub('pyramid_zcml', newt) |
| | | newt = ATTR.sub(replace, newt) |
| | | if text != newt: |
| | | newf = open(absfile, 'wb') |
| | |
| | | summary = 'pyramid starter project' |
| | | template_renderer = staticmethod(paste_script_template_renderer) |
| | | |
| | | class StarterZCMLProjectTemplate(PyramidTemplate): |
| | | _template_dir = 'paster_templates/starter_zcml' |
| | | summary = 'pyramid starter project (ZCML)' |
| | | template_renderer = staticmethod(paste_script_template_renderer) |
| | | |
| | | class ZODBProjectTemplate(PyramidTemplate): |
| | | _template_dir = 'paster_templates/zodb' |
| | | summary = 'pyramid ZODB starter project' |
| | |
| | | Generates a fully qualified URL for a static :term:`asset`. The |
| | | asset must live within a location defined via the |
| | | :meth:`pyramid.config.Configurator.add_static_view` |
| | | :term:`configuration declaration` or the ``<static>`` ZCML directive |
| | | (see :ref:`static_assets_section`). |
| | | :term:`configuration declaration` directive (see |
| | | :ref:`static_assets_section`). |
| | | |
| | | This is a convenience method. The result of calling |
| | | :meth:`pyramid.request.Request.static_url` is the same as calling |
| | |
| | | from zope.interface import implements |
| | | from zope.interface import providedBy |
| | | |
| | | from zope.deprecation import deprecated |
| | | |
| | | from pyramid.interfaces import IDebugLogger |
| | | from pyramid.interfaces import IExceptionViewClassifier |
| | | from pyramid.interfaces import IRequest |
| | |
| | | from pyramid.threadlocal import manager |
| | | from pyramid.traversal import DefaultRootFactory |
| | | from pyramid.traversal import ResourceTreeTraverser |
| | | |
| | | from pyramid.config import Configurator # b/c |
| | | |
| | | class Router(object): |
| | | implements(IRouter) |
| | |
| | | |
| | | finally: |
| | | manager.pop() |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | # note that ``options`` is a b/w compat alias for ``settings`` and |
| | | # ``Configurator`` is a testing dep inj |
| | | def make_app(root_factory, package=None, filename='configure.zcml', |
| | | settings=None, options=None, Configurator=Configurator): |
| | | """ Return a Router object, representing a fully configured |
| | | :app:`Pyramid` WSGI application. |
| | | |
| | | .. warning:: Use of this function is deprecated as of |
| | | :app:`Pyramid` 1.0. You should instead use a |
| | | :class:`pyramid.config.Configurator` instance to |
| | | perform startup configuration as shown in |
| | | :ref:`configuration_narr`. |
| | | |
| | | ``root_factory`` must be a callable that accepts a :term:`request` |
| | | object and which returns a traversal root object. The traversal |
| | | root returned by the root factory is the *default* traversal root; |
| | | it can be overridden on a per-view basis. ``root_factory`` may be |
| | | ``None``, in which case a 'default default' traversal root is |
| | | used. |
| | | |
| | | ``package`` is a Python :term:`package` or module representing the |
| | | application's package. It is optional, defaulting to ``None``. |
| | | ``package`` may be ``None``. If ``package`` is ``None``, the |
| | | ``filename`` passed or the value in the ``options`` dictionary |
| | | named ``configure_zcml`` must be a) absolute pathname to a |
| | | :term:`ZCML` file that represents the application's configuration |
| | | *or* b) a :term:`asset specification` to a :term:`ZCML` file in |
| | | the form ``dotted.package.name:relative/file/path.zcml``. |
| | | |
| | | ``filename`` is the filesystem path to a ZCML file (optionally |
| | | relative to the package path) that should be parsed to create the |
| | | application registry. It defaults to ``configure.zcml``. It can |
| | | also be a ;term:`asset specification` in the form |
| | | ``dotted_package_name:relative/file/path.zcml``. Note that if any |
| | | value for ``configure_zcml`` is passed within the ``settings`` |
| | | dictionary, the value passed as ``filename`` will be ignored, |
| | | replaced with the ``configure_zcml`` value. |
| | | |
| | | ``settings``, if used, should be a dictionary containing runtime |
| | | settings (e.g. the key/value pairs in an app section of a |
| | | PasteDeploy file), with each key representing the option and the |
| | | key's value representing the specific option value, |
| | | e.g. ``{'reload_templates':True}``. Note that the keyword |
| | | parameter ``options`` is a backwards compatibility alias for the |
| | | ``settings`` keyword parameter. |
| | | """ |
| | | settings = settings or options or {} |
| | | zcml_file = settings.get('configure_zcml', filename) |
| | | config = Configurator(package=package, settings=settings, |
| | | root_factory=root_factory, autocommit=True) |
| | | config.hook_zca() |
| | | config.begin() |
| | | config.load_zcml(zcml_file) |
| | | config.end() |
| | | return config.make_wsgi_app() |
| | | |
| | | |
| | | deprecated( |
| | | 'make_app', |
| | | 'pyramid.router.make_app is deprecated as of Pyramid 1.0. Use ' |
| | | 'an instance of ``pyramid.config.Configurator`` to configure your ' |
| | | 'application instead.') |
| | |
| | | config_reload_resources)) |
| | | # reload_resources is an older alias for reload_assets |
| | | eff_reload_assets = reload_assets or reload_resources |
| | | configure_zcml = self.get('configure_zcml', '') |
| | | eff_configure_zcml = eget('PYRAMID_CONFIGURE_ZCML', configure_zcml) |
| | | locale_name = self.get('default_locale_name', 'en') |
| | | eff_locale_name = eget('PYRAMID_DEFAULT_LOCALE_NAME', locale_name) |
| | | |
| | |
| | | 'reload_templates': eff_reload_all or eff_reload_templates, |
| | | 'reload_resources':eff_reload_all or eff_reload_assets, |
| | | 'reload_assets':eff_reload_all or eff_reload_assets, |
| | | 'configure_zcml':eff_configure_zcml, |
| | | 'default_locale_name':eff_locale_name, |
| | | } |
| | | |
| | |
| | | |
| | | .. note:: If the ``root_dir`` is relative to a :term:`package`, or |
| | | is a :term:`asset specification` the :app:`Pyramid` |
| | | ``asset`` ZCML directive or |
| | | :class:`pyramid.config.Configurator` method can be |
| | | used to override assets within the named ``root_dir`` |
| | | package-relative directory. However, if the ``root_dir`` is |
| | |
| | | # fixture application |
| | | def includeme(config): |
| | | config.add_route('rdf', |
| | | 'licenses/:license_code/:license_version/rdf', |
| | | '.views.rdf_view') |
| | | config.add_route('juri', |
| | | 'licenses/:license_code/:license_version/:jurisdiction', |
| | | '.views.juri_view') |
| | |
| | | @view_config(name='z', permission='__no_permission_required__') |
| | | def z_view(request): |
| | | return Response('this is public') |
| | | |
| | | def includeme(config): |
| | | from pyramid.authorization import ACLAuthorizationPolicy |
| | | from pyramid.authentication import AuthTktAuthenticationPolicy |
| | | authn_policy = AuthTktAuthenticationPolicy('seekt1t') |
| | | authz_policy = ACLAuthorizationPolicy() |
| | | config.scan('pyramid.tests.defpermbugapp') |
| | | config._set_authentication_policy(authn_policy) |
| | | config._set_authorization_policy(authz_policy) |
| | | config.set_default_permission('private') |
| | | |
| | |
| | | # a package |
| | | def includeme(config): |
| | | config.add_view('.views.maybe') |
| | | config.add_view('.views.no', context='.models.NotAnException') |
| | | config.add_view('.views.yes', context=".models.AnException") |
| | | config.add_view('.views.raise_exception', name='raise_exception') |
| | | config.add_route('route_raise_exception', 'route_raise_exception', |
| | | view='.views.raise_exception') |
| | | config.add_route('route_raise_exception2', |
| | | 'route_raise_exception2', |
| | | view='.views.raise_exception', |
| | | factory='.models.route_factory') |
| | | config.add_route('route_raise_exception3', |
| | | 'route_raise_exception3', |
| | | view='.views.raise_exception', |
| | | factory='.models.route_factory2') |
| | | config.add_view('.views.whoa', context='.models.AnException', |
| | | route_name='route_raise_exception3') |
| | | config.add_route('route_raise_exception4', 'route_raise_exception4', |
| | | view='.views.raise_exception') |
| | | config.add_view('.views.whoa', context='.models.AnException', |
| | | route_name='route_raise_exception4') |
| | |
| | | # fixture application |
| | | def includeme(config): |
| | | config.add_view('.views.fixture_view') |
| | | config.add_view('.views.exception_view', context=RuntimeError) |
| | | config.add_view('.views.protected_view', name='protected.html') |
| | | config.add_view('.views.erroneous_view', name='error.html') |
| | | config.add_view('.views.fixture_view', name='dummyskin.html', |
| | | request_type='.views.IDummy') |
| | | from models import fixture, IFixture |
| | | config.registry.registerUtility(fixture, IFixture) |
| | | config.add_view('.views.fixture_view', name='another.html') |
| | | |
| | | |
| | |
| | | # package |
| | | def includeme(config): |
| | | # <!-- we want this view to "win" --> |
| | | config.add_route('route', 'abc', view='.views.route_view') |
| | | # <!-- .. even though this one has a more specific context --> |
| | | config.add_view('.views.global_view', |
| | | context='pyramid.traversal.DefaultRootFactory') |
| | | config.add_view('.views.global2_view', |
| | | context='pyramid.traversal.DefaultRootFactory', |
| | | name='global2') |
| | | config.add_route('route2', 'def') |
| | | # <!-- we want this view to win for route2 even though global view with |
| | | # context is more specific --> |
| | | config.add_view('.views.route2_view', route_name='route2') |
| | | |
| | | # <!-- the global view should be found for this route --> |
| | | config.add_route('route3', 'ghi', use_global_views=True) |
| | | # <!-- the global view should not be found for this route --> |
| | | config.add_route('route4', 'jkl') |
| | | # <!-- the global view should not be found for this route (/global2) --> |
| | | config.add_route('route5', 'mno/*traverse') |
| | | # <!-- the global view should be found for this route (/global2) --> |
| | | config.add_route('route6', 'pqr/*traverse', use_global_views=True) |
| | | config.add_route('route7', 'error') |
| | | config.add_view('.views.erroneous_view', route_name='route7') |
| | | config.add_route('route8', 'error2') |
| | | config.add_view('.views.erroneous_view', route_name='route8') |
| | | # <!-- we want this view to "win" for route7 as exception view --> |
| | | config.add_view('.views.exception_view', context=RuntimeError) |
| | | # <!-- we want this view to "win" for route8 as exception view--> |
| | | config.add_view('.views.exception2_view', context=RuntimeError, |
| | | route_name='route8') |
| | | config.add_route('route9', 'error_sub') |
| | | config.add_view('.views.erroneous_sub_view', route_name='route9') |
| | | # <!-- we want this view to "win" for route9 as exception view... --> |
| | | config.add_view('.views.exception2_view', context='.views.SuperException', |
| | | route_name='route9') |
| | | # <!-- ...even if we have more context-specialized view for exception --> |
| | | config.add_view('.views.exception_view', context='.views.SubException') |
| | |
| | | msg = 'Allow ./x? %s' % repr(view_execution_permitted( |
| | | context, request, 'x')) |
| | | return Response(escape(msg)) |
| | | |
| | | def includeme(config): |
| | | from pyramid.authentication import AuthTktAuthenticationPolicy |
| | | from pyramid.authorization import ACLAuthorizationPolicy |
| | | authn_policy = AuthTktAuthenticationPolicy('seekt1t') |
| | | authz_policy = ACLAuthorizationPolicy() |
| | | config._set_authentication_policy(authn_policy) |
| | | config._set_authorization_policy(authz_policy) |
| | | config.add_view(test, name='test') |
| | | config.add_view(x_view, name='x', permission='private') |
| | |
| | | # package |
| | | def includeme(config): |
| | | config.add_route('gameactions_pet_get_pets', '/pet', |
| | | view='.views.PetRESTView', |
| | | view_attr='GET', |
| | | request_method='GET', |
| | | permission='view', |
| | | renderer='json') |
| | | config.add_route('gameactions_pet_care_for_pet', '/pet', |
| | | view='.views.PetRESTView', |
| | | view_attr='POST', |
| | | request_method='POST', |
| | | permission='view', |
| | | renderer='json') |
| | | |
| | |
| | | self.assertEqual(len(subscriber), 1) |
| | | self.failUnless(IApplicationCreated.providedBy(subscriber[0])) |
| | | |
| | | def test_load_zcml_default(self): |
| | | import pyramid.tests.fixtureapp |
| | | config = self._makeOne(package=pyramid.tests.fixtureapp, |
| | | autocommit=True) |
| | | registry = config.load_zcml() |
| | | from pyramid.tests.fixtureapp.models import IFixture |
| | | self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml |
| | | |
| | | def test_load_zcml_routesapp(self): |
| | | from pyramid.interfaces import IRoutesMapper |
| | | config = self._makeOne(autocommit=True) |
| | | config.load_zcml('pyramid.tests.routesapp:configure.zcml') |
| | | self.failUnless(config.registry.getUtility(IRoutesMapper)) |
| | | |
| | | def test_load_zcml_fixtureapp(self): |
| | | from pyramid.tests.fixtureapp.models import IFixture |
| | | config = self._makeOne(autocommit=True) |
| | | config.load_zcml('pyramid.tests.fixtureapp:configure.zcml') |
| | | self.failUnless(config.registry.queryUtility(IFixture)) # only in c.zcml |
| | | |
| | | def test_load_zcml_as_relative_filename(self): |
| | | import pyramid.tests.fixtureapp |
| | | config = self._makeOne(package=pyramid.tests.fixtureapp, |
| | | autocommit=True) |
| | | registry = config.load_zcml('configure.zcml') |
| | | from pyramid.tests.fixtureapp.models import IFixture |
| | | self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml |
| | | |
| | | def test_load_zcml_as_absolute_filename(self): |
| | | import os |
| | | import pyramid.tests.fixtureapp |
| | | config = self._makeOne(package=pyramid.tests.fixtureapp, |
| | | autocommit=True) |
| | | dn = os.path.dirname(pyramid.tests.fixtureapp.__file__) |
| | | c_z = os.path.join(dn, 'configure.zcml') |
| | | registry = config.load_zcml(c_z) |
| | | from pyramid.tests.fixtureapp.models import IFixture |
| | | self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml |
| | | |
| | | def test_load_zcml_lock_and_unlock(self): |
| | | config = self._makeOne(autocommit=True) |
| | | dummylock = DummyLock() |
| | | config.load_zcml( |
| | | 'pyramid.tests.fixtureapp:configure.zcml', |
| | | lock=dummylock) |
| | | self.assertEqual(dummylock.acquired, True) |
| | | self.assertEqual(dummylock.released, True) |
| | | |
| | | def test_include_with_dotted_name(self): |
| | | from pyramid import tests |
| | | config = self._makeOne() |
| | |
| | | def test___getattr__matches(self): |
| | | config = self._makeOne() |
| | | def foo(config): pass |
| | | directives = {'foo':foo} |
| | | directives = {'foo':(foo, True)} |
| | | config.registry._directives = directives |
| | | foo_meth = config.foo |
| | | self.failUnless(foo_meth.im_func.__docobj__ is foo) |
| | |
| | | |
| | | class DummyContext: |
| | | pass |
| | | |
| | | class DummyLock: |
| | | def acquire(self): |
| | | self.acquired = True |
| | | |
| | | def release(self): |
| | | self.released = True |
| | | |
| | | class DummyPackage: |
| | | def __init__(self, name): |
| | |
| | | |
| | | class IntegrationBase(unittest.TestCase): |
| | | root_factory = None |
| | | package = None |
| | | def setUp(self): |
| | | from pyramid.config import Configurator |
| | | config = Configurator(root_factory=self.root_factory) |
| | | config = Configurator(root_factory=self.root_factory, |
| | | package=self.package) |
| | | config.begin() |
| | | config.load_zcml(self.config) |
| | | config.include(self.package) |
| | | config.commit() |
| | | app = config.make_wsgi_app() |
| | | from webtest import TestApp |
| | |
| | | self.config.end() |
| | | |
| | | class TestFixtureApp(IntegrationBase): |
| | | config = 'pyramid.tests.fixtureapp:configure.zcml' |
| | | package = 'pyramid.tests.fixtureapp' |
| | | def test_another(self): |
| | | res = self.testapp.get('/another.html', status=200) |
| | | self.assertEqual(res.body, 'fixture') |
| | |
| | | class TestCCBug(IntegrationBase): |
| | | # "unordered" as reported in IRC by author of |
| | | # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ |
| | | config = 'pyramid.tests.ccbugapp:configure.zcml' |
| | | package = 'pyramid.tests.ccbugapp' |
| | | def test_rdf(self): |
| | | res = self.testapp.get('/licenses/1/v1/rdf', status=200) |
| | | self.assertEqual(res.body, 'rdf') |
| | |
| | | # make sure views registered for a route "win" over views registered |
| | | # without one, even though the context of the non-route view may |
| | | # be more specific than the route view. |
| | | config = 'pyramid.tests.hybridapp:configure.zcml' |
| | | package = 'pyramid.tests.hybridapp' |
| | | def test_root(self): |
| | | res = self.testapp.get('/', status=200) |
| | | self.assertEqual(res.body, 'global') |
| | |
| | | |
| | | class TestRestBugApp(IntegrationBase): |
| | | # test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515) |
| | | config = 'pyramid.tests.restbugapp:configure.zcml' |
| | | package = 'pyramid.tests.restbugapp' |
| | | def test_it(self): |
| | | res = self.testapp.get('/pet', status=200) |
| | | self.assertEqual(res.body, 'gotten') |
| | | |
| | | class TestViewDecoratorApp(IntegrationBase): |
| | | config = 'pyramid.tests.viewdecoratorapp:configure.zcml' |
| | | package = 'pyramid.tests.viewdecoratorapp' |
| | | def _configure_mako(self): |
| | | tmpldir = os.path.join(os.path.dirname(__file__), 'viewdecoratorapp', |
| | | 'views') |
| | |
| | | |
| | | class TestViewPermissionBug(IntegrationBase): |
| | | # view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html |
| | | config = 'pyramid.tests.permbugapp:configure.zcml' |
| | | package = 'pyramid.tests.permbugapp' |
| | | def test_test(self): |
| | | res = self.testapp.get('/test', status=200) |
| | | self.failUnless('ACLDenied' in res.body) |
| | |
| | | |
| | | class TestDefaultViewPermissionBug(IntegrationBase): |
| | | # default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html |
| | | config = 'pyramid.tests.defpermbugapp:configure.zcml' |
| | | package = 'pyramid.tests.defpermbugapp' |
| | | def test_x(self): |
| | | res = self.testapp.get('/x', status=401) |
| | | self.failUnless('failed permission check' in res.body) |
| | |
| | | 'notanexception':NotAnException()} |
| | | |
| | | class TestExceptionViewsApp(IntegrationBase): |
| | | config = 'pyramid.tests.exceptionviewapp:configure.zcml' |
| | | package = 'pyramid.tests.exceptionviewapp' |
| | | root_factory = lambda *arg: excroot |
| | | def test_root(self): |
| | | res = self.testapp.get('/', status=200) |
| | |
| | | start_response = DummyStartResponse() |
| | | self.assertRaises(RuntimeError, router, environ, start_response) |
| | | |
| | | class TestMakeApp(unittest.TestCase): |
| | | def setUp(self): |
| | | from zope.deprecation import __show__ |
| | | __show__.off() |
| | | testing.setUp() |
| | | |
| | | def tearDown(self): |
| | | from zope.deprecation import __show__ |
| | | __show__.on() |
| | | testing.tearDown() |
| | | |
| | | def _callFUT(self, *arg, **kw): |
| | | from pyramid.router import make_app |
| | | return make_app(*arg, **kw) |
| | | |
| | | def test_it(self): |
| | | settings = {'a':1} |
| | | rootfactory = object() |
| | | app = self._callFUT(rootfactory, settings=settings, |
| | | Configurator=DummyConfigurator) |
| | | self.assertEqual(app.root_factory, rootfactory) |
| | | self.assertEqual(app.settings, settings) |
| | | self.assertEqual(app.zcml_file, 'configure.zcml') |
| | | self.assertEqual(app.zca_hooked, True) |
| | | |
| | | def test_it_options_means_settings(self): |
| | | settings = {'a':1} |
| | | rootfactory = object() |
| | | app = self._callFUT(rootfactory, options=settings, |
| | | Configurator=DummyConfigurator) |
| | | self.assertEqual(app.root_factory, rootfactory) |
| | | self.assertEqual(app.settings, settings) |
| | | self.assertEqual(app.zcml_file, 'configure.zcml') |
| | | |
| | | def test_it_with_package(self): |
| | | package = object() |
| | | rootfactory = object() |
| | | app = self._callFUT(rootfactory, package=package, |
| | | Configurator=DummyConfigurator) |
| | | self.assertEqual(app.package, package) |
| | | |
| | | def test_it_with_custom_configure_zcml(self): |
| | | rootfactory = object() |
| | | settings = {'configure_zcml':'2.zcml'} |
| | | app = self._callFUT(rootfactory, filename='1.zcml', settings=settings, |
| | | Configurator=DummyConfigurator) |
| | | self.assertEqual(app.zcml_file, '2.zcml') |
| | | |
| | | class DummyConfigurator(object): |
| | | def __init__(self, registry=None, package=None, root_factory=None, |
| | | settings=None, autocommit=True): |
| | | self.root_factory = root_factory |
| | | self.package = package |
| | | self.settings = settings |
| | | self.autocommit = autocommit |
| | | |
| | | def begin(self, request=None): |
| | | self.begun = True |
| | | self.request = request |
| | | |
| | | def end(self): |
| | | self.ended = True |
| | | |
| | | def load_zcml(self, filename): |
| | | self.zcml_file = filename |
| | | |
| | | def make_wsgi_app(self): |
| | | return self |
| | | |
| | | def hook_zca(self): |
| | | self.zca_hooked = True |
| | | |
| | | |
| | | class DummyContext: |
| | | pass |
| | | |
| | |
| | | self.assertEqual(settings['debug_routematch'], False) |
| | | self.assertEqual(settings['reload_templates'], False) |
| | | self.assertEqual(settings['reload_resources'], False) |
| | | self.assertEqual(settings['configure_zcml'], '') |
| | | |
| | | def test_reload_templates(self): |
| | | settings = self._makeOne({}) |
| | |
| | | self.assertEqual(result['debug_routematch'], True) |
| | | self.assertEqual(result['debug_authorization'], True) |
| | | self.assertEqual(result['debug_templates'], True) |
| | | |
| | | def test_configure_zcml(self): |
| | | result = self._makeOne({}) |
| | | self.assertEqual(result['configure_zcml'], '') |
| | | result = self._makeOne({'configure_zcml':'abc'}) |
| | | self.assertEqual(result['configure_zcml'], 'abc') |
| | | result = self._makeOne({}, {'PYRAMID_CONFIGURE_ZCML':'abc'}) |
| | | self.assertEqual(result['configure_zcml'], 'abc') |
| | | result = self._makeOne({'configure_zcml':'def'}, |
| | | {'PYRAMID_CONFIGURE_ZCML':'abc'}) |
| | | self.assertEqual(result['configure_zcml'], 'abc') |
| | | |
| | | def test_default_locale_name(self): |
| | | result = self._makeOne({}) |
| | |
| | | # package |
| | | def includeme(config): |
| | | config.scan('pyramid.tests.viewdecoratorapp') |
| | | |
| | |
| | | Generates a fully qualified URL for a static :term:`asset`. |
| | | The asset must live within a location defined via the |
| | | :meth:`pyramid.config.Configurator.add_static_view` |
| | | :term:`configuration declaration` or the ``<static>`` ZCML |
| | | directive (see :ref:`static_assets_section`). |
| | | :term:`configuration declaration` (see :ref:`static_assets_section`). |
| | | |
| | | .. note:: Calling :meth:`pyramid.Request.static_url` can be used to |
| | | achieve the same result as :func:`pyramid.url.static_url`. |
| | |
| | | class view_config(object): |
| | | """ A function, class or method :term:`decorator` which allows a |
| | | developer to create view registrations nearer to a :term:`view |
| | | callable` definition than use of :term:`ZCML` or :term:`imperative |
| | | callable` definition than use :term:`imperative |
| | | configuration` to do the same. |
| | | |
| | | For example, this code in a module ``views.py``:: |
| | |
| | | from resources import MyResource |
| | | config.add_view(views.my_view, context=MyResource, name='my_view', |
| | | permission='read', 'route_name='site1') |
| | | |
| | | Or might replace the following ZCML ``view`` declaration:: |
| | | |
| | | <view |
| | | for='.resources.MyResource' |
| | | view='.views.my_view' |
| | | name='my_view' |
| | | permission='read' |
| | | route_name='site1' |
| | | /> |
| | | |
| | | .. note: :class:`pyramid.view.view_config` is also importable, for |
| | | backwards compatibility purposes, as the name |
| | |
| | | return Response('hello from %s!' % self.context) |
| | | |
| | | To make use of any ``view_config`` declaration, you must perform a |
| | | :term:`scan`. To do so, either insert the following boilerplate |
| | | into your application registry's ZCML:: |
| | | :term:`scan`. To do so, insert the following into your Pyramid |
| | | application's ``main`` stanza:: |
| | | |
| | | <scan package="."/> |
| | | |
| | | See :ref:`scan_directive` for more information about the ZCML |
| | | ``scan`` directive. |
| | | |
| | | Or, if you don't use ZCML, use the |
| | | :meth:`pyramid.config.Configurator.scan` method:: |
| | | |
| | | config.scan() |
| | | """ |
| | | venusian = venusian # for testing injection |
| | |
| | | ``POST`` data information (turning it into a GET), so you shouldn't |
| | | rely on this to redirect POST requests. |
| | | |
| | | If you use :term:`ZCML`, add the following to your application's |
| | | ``configure.zcml`` to use this view as the Not Found view:: |
| | | |
| | | <view |
| | | context="pyramid.exceptions.NotFound" |
| | | view="pyramid.view.append_slash_notfound_view"/> |
| | | |
| | | Or use the |
| | | :meth:`pyramid.config.Configurator.add_view` |
| | | method if you don't use ZCML:: |
| | | Use the :meth:`pyramid.config.Configurator.add_view` method to configure this |
| | | view as the Not Found view:: |
| | | |
| | | from pyramid.exceptions import NotFound |
| | | from pyramid.view import append_slash_notfound_view |
| | |
| | | ('Content-Length', len(body)) ] ) |
| | | return [body] |
| | | |
| | | Allows the following ZCML view declaration to be made:: |
| | | |
| | | <view |
| | | view=".views.hello_world" |
| | | name="hello_world.txt" |
| | | /> |
| | | |
| | | Or the following call to |
| | | Allows the following call to |
| | | :meth:`pyramid.config.Configurator.add_view`:: |
| | | |
| | | from views import hello_world |
| | |
| | | ('Content-Length', len(body)) ] ) |
| | | return [body] |
| | | |
| | | Allows the following ZCML view declaration to be made:: |
| | | |
| | | <view |
| | | view=".views.hello_world" |
| | | name="hello_world.txt" |
| | | /> |
| | | |
| | | Or the following call to |
| | | Allows the following call to |
| | | :meth:`pyramid.config.Configurator.add_view`:: |
| | | |
| | | from views import hello_world |