diff options
64 files changed, 254 insertions, 2570 deletions
diff --git a/.travis.yml b/.travis.yml index 00c293046..9d4324ff8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ python: - pypy - 3.2 -script: python setup.py test +script: python setup.py test -q notifications: email: diff --git a/CHANGES.txt b/CHANGES.txt index d8d606530..9d34786e2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,8 +1,14 @@ Next Release ============ -Major Backward Incompatibilities --------------------------------- +Bug Fixes +--------- + +- Fix an exception in ``pyramid.path.package_name`` when resolving the package + name for namespace packages that had no ``__file__`` attribute. + +Backwards Incompatibilities +--------------------------- - Pyramid has dropped native support for the Mako and Chameleon renderers. To re-add support for these renderers into existing projects there are 3 steps: @@ -37,6 +43,28 @@ Major Backward Incompatibilities result = pyramid.renderers.render('mypkg:templates/home.mako', {}) +- Removed the ``request.response_*`` varying attributes. These attributes + have been deprecated since Pyramid 1.1, and as per the deprecation policy, + have now been removed. + +- ``request.response`` will no longer be mutated when using the + ``pyramid.renderers.render()`` API. Almost all renderers mutate the + ``request.response`` response object (for example, the JSON renderer sets + ``request.response.content_type`` to ``application/json``), but this is + only necessary when the renderer is generating a response; it was a bug + when it was done as a side effect of calling ``pyramid.renderers.render()``. + +- The Mako and Chameleon renderers have been removed from Pyramid. Their + functionality has been moved to the ``pyramid_mako`` and + ``pyramid_chameleon`` distributions respectively. + +- Removed the ``bfg2pyramid`` fixer script. + +- The ``pyramid.events.NewResponse`` event is now sent **after** response + callbacks are executed. It previously executed before response callbacks + were executed. Rationale: it's more useful to be able to inspect the response + after response callbacks have done their jobs instead of before. + 1.5a1 (2013-08-30) ================== diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 0ddaebf15..1a5b975d7 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -220,3 +220,5 @@ Contributors - Matthew Wilkes, 2013/08/23 - Takahiro Fujiwara, 2013/08/28 + +- Doug Hellmann, 2013/09/06 diff --git a/HACKING.txt b/HACKING.txt index abfed6dab..684a42ee6 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -78,7 +78,7 @@ In order to add a feature to Pyramid: documentation (in ``docs/``). - The feature must work fully on the following CPython versions: 2.6, - 2.7, and 3.2 on both UNIX and Windows. + 2.7, 3.2, and 3.3 on both UNIX and Windows. - The feature must work on the latest version of PyPy. @@ -104,7 +104,9 @@ Coding Style - PEP8 compliance. Whitespace rules are relaxed: not necessary to put 2 newlines between classes. But 80-column lines, in particular, are - mandatory. + mandatory. See + http://docs.pylonsproject.org/en/latest/community/codestyle.html for more + information. - Please do not remove trailing whitespace. Configure your editor to reduce diff noise. See https://github.com/Pylons/pyramid/issues/788 for more. @@ -112,13 +114,15 @@ Coding Style Running Tests -------------- -- To run all tests for Pyramid on a single Python version, run ``nosetests`` from - your development virtualenv (See *Using a Development Checkout* above). +- To run all tests for Pyramid on a single Python version, run ``nosetests`` + from your development virtualenv (See *Using a Development Checkout* above). - To run individual tests (i.e. during development) you can use a regular expression with the ``-t`` parameter courtesy of the `nose-selecttests - <https://pypi.python.org/pypi/nose-selecttests/>`_ plugin that's been installed (along with nose itself) via ``python setup.py dev``. The easiest usage is to - simply provide the verbatim name of the test you're working on. + <https://pypi.python.org/pypi/nose-selecttests/>`_ plugin that's been + installed (along with nose itself) via ``python setup.py dev``. The + easiest usage is to simply provide the verbatim name of the test you're + working on. - To run the full set of Pyramid tests on all platforms, install ``tox`` (http://codespeak.net/~hpk/tox/) into a system Python. The ``tox`` console diff --git a/docs/api/request.rst b/docs/api/request.rst index 02290eaf3..72abddb68 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -199,13 +199,13 @@ - Ensures that the user implied by the request passed has the necessary authorization to invoke view callable before calling it. - - causes a :class:`~pyramid.events.NewResponse` event to be sent when - the Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the request's lifetime if a response is obtained from the Pyramid application. + - causes a :class:`~pyramid.events.NewResponse` event to be sent if a + response is obtained. + - Calls any :term:`finished callback` functions defined within the request's lifetime. @@ -235,24 +235,6 @@ .. automethod:: resource_path - .. attribute:: response_* - - In Pyramid 1.0, you could set attributes on a - :class:`pyramid.request.Request` which influenced the behavior of - *rendered* responses (views which use a :term:`renderer` and which - don't directly return a response). These attributes began with - ``response_``, such as ``response_headerlist``. If you needed to - influence response values from a view that uses a renderer (such as the - status code, a header, the content type, etc) you would set these - attributes. See :ref:`response_prefixed_attrs` for further discussion. - As of Pyramid 1.1, assignment to ``response_*`` attrs is deprecated. - Assigning to one is still supported but will cause a deprecation - warning to be emitted, and eventually the feature will be removed. For - new code, instead of assigning ``response_*`` attributes to the - request, use API of the :attr:`pyramid.request.Request.response` - object (exposed to view code as ``request.response``) to influence - rendered response behavior. - .. attribute:: json_body This property will return the JSON-decoded variant of the request diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 3a2568775..8ffda1a5f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -514,7 +514,7 @@ callback will be an exception object instead of its default value of ``None``. Response callbacks are called in the order they're added -(first-to-most-recently-added). All response callbacks are called *after* +(first-to-most-recently-added). All response callbacks are called *before* the :class:`~pyramid.events.NewResponse` event is sent. Errors raised by response callbacks are not handled specially. They will be propagated to the caller of the :app:`Pyramid` router application. diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 8afc9c4ab..e13e09af3 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -430,40 +430,6 @@ For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of ``request.response``, see :attr:`pyramid.request.Request.response`. -.. _response_prefixed_attrs: - -Deprecated Mechanism to Vary Attributes of Rendered Responses -------------------------------------------------------------- - -In previous releases of Pyramid (1.0 and before), the ``request.response`` -attribute did not exist. Instead, Pyramid required users to set special -``response_`` -prefixed attributes of the request to influence response -behavior. As of Pyramid 1.1, those request attributes are deprecated and -their use will cause a deprecation warning to be issued when used. Until -their existence is removed completely, we document them below, for benefit of -people with older code bases. - -``response_content_type`` - Defines the content-type of the resulting response, - e.g. ``text/xml``. - -``response_headerlist`` - A sequence of tuples describing header values that should be set in the - response, e.g. ``[('Set-Cookie', 'abc=123'), ('X-My-Header', 'foo')]``. - -``response_status`` - A WSGI-style status code (e.g. ``200 OK``) describing the status of the - response. - -``response_charset`` - The character set (e.g. ``UTF-8``) of the response. - -``response_cache_for`` - A value in seconds which will influence ``Cache-Control`` and ``Expires`` - headers in the returned response. The same can also be achieved by - returning various values in the ``response_headerlist``, this is purely a - convenience. - .. _adding_and_overriding_renderers: Adding and Changing Renderers diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 6437bd0fa..4b4e99d41 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -232,12 +232,12 @@ unconditionally: - Ensures that the user implied by the request passed has the necessary authorization to invoke view callable before calling it. -- causes a :class:`~pyramid.events.NewResponse` event to be sent when the - Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the subrequest's lifetime if a response is obtained from the Pyramid application. +- causes a :class:`~pyramid.events.NewResponse` event to be sent if a response + is obtained. + - Calls any :term:`finished callback` functions defined within the subrequest's lifetime. diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e09fd83ab..76cf1daac 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -465,6 +465,36 @@ configured view. .. versionadded:: 1.4a1 +Inverting Predicate Values +++++++++++++++++++++++++++ + +You can invert the meaning of any predicate value by wrapping it in a call to +:class:`pyramid.config.not_`. + +.. code-block:: python + :linenos: + + from pyramid.config import not_ + + config.add_view( + 'mypackage.views.my_view', + route_name='ok', + request_method=not_('POST') + ) + +The above example will ensure that the view is called if the request method +is *not* ``POST``, at least if no other view is more specific. + +This technique of wrapping a predicate value in ``not_`` can be used anywhere +predicate values are accepted: + +- :meth:`pyramid.config.Configurator.add_view` + +- :meth:`pyramid.view.view_config` + +.. versionadded:: 1.5 + + .. index:: single: view_config decorator @@ -557,35 +587,6 @@ form of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. -Inverting Predicate Values -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can invert the meaning of any predicate value by wrapping it in a call to -:class:`pyramid.config.not_`. - -.. code-block:: python - :linenos: - - from pyramid.config import not_ - - config.add_view( - 'mypackage.views.my_view', - route_name='ok', - request_method=not_('POST') - ) - -The above example will ensure that the view is called if the request method -is *not* ``POST``, at least if no other view is more specific. - -This technique of wrapping a predicate value in ``not_`` can be used anywhere -predicate values are accepted: - -- :meth:`pyramid.config.Configurator.add_view` - -- :meth:`pyramid.view.view_config` - -.. versionadded:: 1.5 - .. index:: single: view_config placement diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index df2e9e149..cf20db6d7 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -83,7 +83,7 @@ statement at the head: Add the following class definition: .. literalinclude:: src/authorization/tutorial/models.py - :lines: 36-40 + :lines: 33-37 :linenos: :language: python @@ -339,7 +339,7 @@ when we're done: .. literalinclude:: src/authorization/tutorial/models.py :linenos: - :emphasize-lines: 1-4,36-40 + :emphasize-lines: 1-4,33-37 :language: python (Only the highlighted lines need to be added.) diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index c8e6723b3..05781c044 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -232,10 +232,17 @@ To give a simple example of a model class, we define one named ``MyModel``: :linenos: :language: py -Our example model has an ``__init__`` method that takes two arguments -(``name``, and ``value``). It stores these values as ``self.name`` and -``self.value`` on the instance created by the ``__init__`` function itself. -The ``MyModel`` class also has a ``__tablename__`` attribute. This informs +Our example model does not require an ``__init__`` method because SQLAlchemy +supplies for us a default constructor if one is not already present, +which accepts keyword arguments of the same name as that of the mapped attributes. + +.. note:: Example usage of MyModel: + + .. code-block:: python + + johnny = MyModel(name="John Doe", value=10) + +The ``MyModel`` class has a ``__tablename__`` attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 60427a911..e30af12b2 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -24,7 +24,7 @@ following: .. literalinclude:: src/models/tutorial/models.py :linenos: :language: py - :emphasize-lines: 20-22,25,27,29 + :emphasize-lines: 20-22,25 (The highlighted lines are the ones that need to be changed.) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py index 91e5a0019..4f7e1e024 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py @@ -29,9 +29,6 @@ class Page(Base): name = Column(Text, unique=True) data = Column(Text) - def __init__(self, name, data): - self.name = name - self.data = data class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py index aeeb9df64..0cdd4bbc3 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py @@ -22,7 +22,3 @@ class MyModel(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value diff --git a/docs/tutorials/wiki2/src/models/tutorial/models.py b/docs/tutorials/wiki2/src/models/tutorial/models.py index 9a078d757..f028c917a 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models.py @@ -23,7 +23,3 @@ class Page(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) data = Column(Text) - - def __init__(self, name, data): - self.name = name - self.data = data diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models.py b/docs/tutorials/wiki2/src/tests/tutorial/models.py index 91e5a0019..4f7e1e024 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models.py @@ -29,9 +29,6 @@ class Page(Base): name = Column(Text, unique=True) data = Column(Text) - def __init__(self, name, data): - self.name = name - self.data = data class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), diff --git a/docs/tutorials/wiki2/src/views/tutorial/models.py b/docs/tutorials/wiki2/src/views/tutorial/models.py index 9a078d757..f028c917a 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models.py @@ -23,7 +23,3 @@ class Page(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) data = Column(Text) - - def __init__(self, name, data): - self.name = name - self.data = data diff --git a/pyramid/chameleon_text.py b/pyramid/chameleon_text.py deleted file mode 100644 index d2a943a28..000000000 --- a/pyramid/chameleon_text.py +++ /dev/null @@ -1,37 +0,0 @@ -from zope.interface import implementer - -from pyramid.interfaces import ITemplateRenderer - -from pyramid.decorator import reify -from pyramid import renderers - -def renderer_factory(info): - return renderers.template_renderer_factory(info, TextTemplateRenderer) - -@implementer(ITemplateRenderer) -class TextTemplateRenderer(object): - 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): - from chameleon.zpt.template import PageTextTemplateFile - return PageTextTemplateFile(self.path, - auto_reload=self.lookup.auto_reload, - debug=self.lookup.debug, - translate=self.lookup.translate) - - def implementation(self): - return self.template - - def __call__(self, value, system): - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - result = self.template(**system) - return result - diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py deleted file mode 100644 index 4ea5d506d..000000000 --- a/pyramid/chameleon_zpt.py +++ /dev/null @@ -1,49 +0,0 @@ -from zope.interface import implementer - -from pyramid.interfaces import ITemplateRenderer -from pyramid.decorator import reify -from pyramid import renderers - -from chameleon.zpt.template import PageTemplateFile - -def renderer_factory(info): - return renderers.template_renderer_factory(info, ZPTTemplateRenderer) - -class PyramidPageTemplateFile(PageTemplateFile): - def cook(self, body): - PageTemplateFile.cook(self, body) - if self.macro: - # render only the portion of the template included in a - # define-macro named the value of self.macro - macro_renderer = self.macros[self.macro].include - self._render = macro_renderer - -@implementer(ITemplateRenderer) -class ZPTTemplateRenderer(object): - def __init__(self, path, lookup, macro=None): - self.path = path - self.lookup = lookup - self.macro = macro - - @reify # avoid looking up reload_templates before manager pushed - def template(self): - tf = PyramidPageTemplateFile( - self.path, - auto_reload=self.lookup.auto_reload, - debug=self.lookup.debug, - translate=self.lookup.translate, - macro=self.macro, - ) - return tf - - def implementation(self): - return self.template - - def __call__(self, value, system): - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - result = self.template(**system) - return result - diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 9eb59e1c7..f08cfb9a8 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -1,10 +1,7 @@ import os import sys -from translationstring import ChameleonTranslate - from pyramid.interfaces import ( - IChameleonTranslate, ILocaleNegotiator, ITranslationDirectories, ) @@ -12,7 +9,6 @@ from pyramid.interfaces import ( from pyramid.exceptions import ConfigurationError from pyramid.i18n import get_localizer from pyramid.path import package_path -from pyramid.threadlocal import get_current_request from pyramid.util import action_method class I18NConfiguratorMixin(object): @@ -108,18 +104,5 @@ class I18NConfiguratorMixin(object): tdirs.insert(0, directory) - if directories: - # We actually only need an IChameleonTranslate function - # utility to be registered zero or one times. We register the - # same function once for each added translation directory, - # which does too much work, but has the same effect. - ctranslate = ChameleonTranslate(translator) - self.registry.registerUtility(ctranslate, IChameleonTranslate) - self.action(None, register, introspectables=introspectables) -def translator(msg): - request = get_current_request() - localizer = get_localizer(request) - return localizer.translate(msg) - diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index 356bf033e..a301b9c43 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -7,20 +7,9 @@ from pyramid.interfaces import ( ) from pyramid.util import action_method - -from pyramid import ( - renderers, - chameleon_text, - chameleon_zpt, - ) - -from pyramid.mako_templating import renderer_factory as mako_renderer_factory +from pyramid import renderers DEFAULT_RENDERERS = ( - ('.txt', chameleon_text.renderer_factory), - ('.pt', chameleon_zpt.renderer_factory), - ('.mak', mako_renderer_factory), - ('.mako', mako_renderer_factory), ('json', renderers.json_renderer_factory), ('string', renderers.string_renderer_factory), ) diff --git a/pyramid/fixers/__init__.py b/pyramid/fixers/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/pyramid/fixers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/pyramid/fixers/fix_bfg_imports.py b/pyramid/fixers/fix_bfg_imports.py deleted file mode 100644 index 0046aad30..000000000 --- a/pyramid/fixers/fix_bfg_imports.py +++ /dev/null @@ -1,220 +0,0 @@ -import os -import re -import sys - -from lib2to3.refactor import get_fixers_from_package -from lib2to3.refactor import RefactoringTool -from lib2to3.fixer_util import Name -from lib2to3.fixer_util import attr_chain -from lib2to3 import fixer_base - -MAPPING = {'repoze.bfg':'pyramid'} - -MODULE_NAMES = ( - 'compat', - 'configuration', - 'authentication', - 'authorization', - 'chameleon_text', - 'chameleon_zpt', - 'decorator', - 'encode', - 'events', - 'exceptions', - 'i18n', - 'includes', - 'interfaces', - 'location', - 'log', - 'paster', - 'path', - 'registry', - 'renderers', - 'request', - 'resource', - 'router', - 'scripting', - 'security', - 'settings', - 'static', - 'testing', - 'tests', - 'tests.test_configuration', - 'tests.ccbugapp', - 'tests.exceptionviewapp', - 'tests.exceptionviewapp.models', - 'tests.fixtureapp', - 'tests.fixtureapp.models', - 'tests.grokkedapp', - 'tests.hybridapp', - 'tests.localeapp', - 'tests.restbugapp', - 'tests.routesapp', - 'threadlocal', - 'traversal', - 'urldispatch', - 'url', - 'view', - 'wsgi', - 'zcml', - ) - -for name in MODULE_NAMES: - frm = 'repoze.bfg.' + name - to = 'pyramid.' + name - MAPPING[frm] = to - -def alternates(members): - return "(" + "|".join(map(str, members)) + ")" - -def build_pattern(mapping=MAPPING): - mod_list = [] - - for key in mapping: - splitted = key.split('.') - joined = " '.' ".join(["'%s'" %s for s in splitted]) - mod_list.append(joined) - - mod_list = ' | '.join( - ['module_name=dotted_name< %s >' %s for s in mod_list]) - - yield """name_import=import_name< 'import' ((%s) | - multiple_imports=dotted_as_names< any* (%s) any* >) > - """ % (mod_list, mod_list) - yield """import_from< 'from' (%s) 'import' ['('] - ( any | import_as_name< any 'as' any > | - import_as_names< any* >) [')'] > - """ % mod_list - yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | - multiple_imports=dotted_as_names< - any* dotted_as_name< (%s) 'as' any > any* >) > - """ % (mod_list, mod_list) - - # Find usages of module members in code e.g. ``repoze.bfg`` or - # ``repoze.bfg.configuration`` - # 'repoze' trailer< '.' 'bfg' > trailer< '.' 'configuration' > - bare_names = [] - for key in mapping: - splitted = key.split('.') - tmp = ["'%s'" % splitted[0]] - for thing in splitted[1:]: - tmp.append(" trailer< '.' '%s' > " % thing) - bare_name = ''.join(tmp) - bare_names.append(bare_name) - - names = alternates(bare_names) - yield "power< bare_with_attr=%s >" % names - -class FixBfgImports(fixer_base.BaseFix): - - mapping = MAPPING - run_order = 8 - - def build_pattern(self): - pattern = "|".join(build_pattern(self.mapping)) - return pattern - - def compile_pattern(self): - # We override this, so MAPPING can be pragmatically altered and the - # changes will be reflected in PATTERN. - self.PATTERN = self.build_pattern() - super(FixBfgImports, self).compile_pattern() - - # Don't match the node if it's within another match. - def match(self, node): - match = super(FixBfgImports, self).match - results = match(node) - if results: - # Module usage could be in the trailer of an attribute lookup, so we - # might have nested matches when "bare_with_attr" is present. - if "bare_with_attr" not in results and \ - any(match(obj) for obj in attr_chain(node, "parent")): - return False - return results - return False - - def start_tree(self, tree, filename): - super(FixBfgImports, self).start_tree(tree, filename) - self.replace = {} - - def transform(self, node, results): - # Mostly copied from fix_imports.py - import_mod = results.get("module_name") - if import_mod: - try: - mod_name = import_mod.value - except AttributeError: - # XXX: A hack to remove whitespace prefixes and suffixes - mod_name = str(import_mod).strip() - new_name = self.mapping[mod_name] - import_mod.replace(Name(new_name, prefix=import_mod.prefix)) - if "name_import" in results: - # If it's not a "from x import x, y" or "import x as y" import, - # marked its usage to be replaced. - self.replace[mod_name] = new_name - if "multiple_imports" in results: - # This is a nasty hack to fix multiple imports on a line (e.g., - # "import StringIO, urlparse"). The problem is that I can't - # figure out an easy way to make a pattern recognize the keys of - # MAPPING randomly sprinkled in an import statement. - results = self.match(node) - if results: - self.transform(node, results) - else: - # Replace usage of the module. - bare_name_text = ''.join(map(str,results['bare_with_attr'])).strip() - new_name = self.replace.get(bare_name_text) - bare_name = results["bare_with_attr"][0] - - if new_name: - node.replace(Name(new_name, prefix=bare_name.prefix)) - -MODULE_ALTERNATIVES = [] -for name in MODULE_NAMES: - MODULE_ALTERNATIVES.append(r'\.' + re.escape(name)+r'[\w\.]*?') - -MODULE_ALTERNATIVES = '|'.join(MODULE_ALTERNATIVES) - -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): - return 'pyramid%s' % match.group(2) - -def fix_zcml(path): - for root, dirs, files in os.walk(path): - for file in files: - if file.endswith('.zcml'): - absfile = os.path.join(root, file) - f = open(absfile, 'rb') - text = f.read() - f.close() - 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') - newf.write(newt) - newf.flush() - newf.close() - - for dir in dirs: - if dir.startswith('.'): - dirs.remove(dir) - -def main(argv=None): - if argv is None: - argv = sys.argv - path = argv[1] - fixer_names = get_fixers_from_package('pyramid.fixers') - tool = RefactoringTool(fixer_names) - tool.refactor([path], write=True) - fix_zcml(path) - -if __name__ == '__main__': - main() - diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 3f43494a8..1d5688195 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -853,19 +853,6 @@ class IPackageOverrides(IPEP302Loader): # traversalwrapper) VH_ROOT_KEY = 'HTTP_X_VHM_ROOT' -class IChameleonLookup(Interface): - translate = Attribute('IChameleonTranslate object') - debug = Attribute('The ``debug_templates`` setting for this application') - auto_reload = Attribute('The ``reload_templates`` setting for this app') - def __call__(self, info): - """ Return an ITemplateRenderer based on IRendererInfo ``info`` """ - -class IChameleonTranslate(Interface): - """ Internal interface representing a chameleon translate function """ - def __call__(msgid, domain=None, mapping=None, context=None, - target_language=None, default=None): - """ Translate a mess of arguments to a Unicode object """ - class ILocalizer(Interface): """ Localizer for a specific language """ diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py deleted file mode 100644 index 01456c3d4..000000000 --- a/pyramid/mako_templating.py +++ /dev/null @@ -1,252 +0,0 @@ -import os -import posixpath -import sys -import threading -import warnings - -from zope.interface import ( - implementer, - Interface, - ) - -from pyramid.asset import ( - resolve_asset_spec, - abspath_from_asset_spec, - ) - -from pyramid.compat import ( - is_nonstr_iter, - reraise, - ) - -from pyramid.interfaces import ITemplateRenderer -from pyramid.settings import asbool -from pyramid.util import DottedNameResolver - -def _no_mako(*arg, **kw): # pragma: no cover - raise NotImplementedError( - "'mako' package is not importable (maybe downgrade MarkupSafe to " - "0.16 or below if you're using Python 3.2)" - ) - -try: - from mako.lookup import TemplateLookup -except (ImportError, SyntaxError, AttributeError): #pragma NO COVER - class TemplateLookup(object): - def __init__(self, **kw): - for name in ('adjust_uri', 'get_template', 'filename_to_uri', - 'put_string', 'put_template'): - setattr(self, name, _no_mako) - self.filesystem_checks = False - -try: - from mako.exceptions import TopLevelLookupException -except (ImportError, SyntaxError, AttributeError): #pragma NO COVER - class TopLevelLookupException(Exception): - pass - -try: - from mako.exceptions import text_error_template -except (ImportError, SyntaxError, AttributeError): #pragma NO COVER - def text_error_template(lookup=None): - _no_mako() - - -class IMakoLookup(Interface): - pass - -class PkgResourceTemplateLookup(TemplateLookup): - """TemplateLookup subclass that handles asset specification URIs""" - def adjust_uri(self, uri, relativeto): - """Called from within a Mako template, avoids adjusting the - uri if it looks like an asset specification""" - # Don't adjust asset spec names - isabs = os.path.isabs(uri) - if (not isabs) and (':' in uri): - return uri - if not(isabs) and ('$' in uri): - return uri.replace('$', ':') - if relativeto is not None: - relativeto = relativeto.replace('$', ':') - if not(':' in uri) and (':' in relativeto): - if uri.startswith('/'): - return uri - pkg, relto = relativeto.split(':') - _uri = posixpath.join(posixpath.dirname(relto), uri) - return '{0}:{1}'.format(pkg, _uri) - if not(':' in uri) and not(':' in relativeto): - return posixpath.join(posixpath.dirname(relativeto), uri) - return TemplateLookup.adjust_uri(self, uri, relativeto) - - def get_template(self, uri): - """Fetch a template from the cache, or check the filesystem - for it - - In addition to the basic filesystem lookup, this subclass will - use pkg_resource to load a file using the asset - specification syntax. - - """ - isabs = os.path.isabs(uri) - if (not isabs) and (':' in uri): - # Windows can't cope with colons in filenames, so we replace the - # colon with a dollar sign in the filename mako uses to actually - # store the generated python code in the mako module_directory or - # in the temporary location of mako's modules - adjusted = uri.replace(':', '$') - try: - if self.filesystem_checks: - return self._check(adjusted, self._collection[adjusted]) - else: - return self._collection[adjusted] - except KeyError: - pname, path = resolve_asset_spec(uri) - srcfile = abspath_from_asset_spec(path, pname) - if os.path.isfile(srcfile): - return self._load(srcfile, adjusted) - raise TopLevelLookupException( - "Can not locate template for uri %r" % uri) - return TemplateLookup.get_template(self, uri) - -registry_lock = threading.Lock() - -class MakoRendererFactoryHelper(object): - def __init__(self, settings_prefix=None): - self.settings_prefix = settings_prefix - - def __call__(self, info): - defname = None - asset, ext = info.name.rsplit('.', 1) - if '#' in asset: - asset, defname = asset.rsplit('#', 1) - - path = '%s.%s' % (asset, ext) - registry = info.registry - settings = info.settings - settings_prefix = self.settings_prefix - - if settings_prefix is None: - settings_prefix = info.type +'.' - - lookup = registry.queryUtility(IMakoLookup, name=settings_prefix) - - def sget(name, default=None): - return settings.get(settings_prefix + name, default) - - if lookup is None: - reload_templates = settings.get('pyramid.reload_templates', None) - if reload_templates is None: - reload_templates = settings.get('reload_templates', False) - reload_templates = asbool(reload_templates) - directories = sget('directories', []) - module_directory = sget('module_directory', None) - input_encoding = sget('input_encoding', 'utf-8') - error_handler = sget('error_handler', None) - default_filters = sget('default_filters', 'h') - imports = sget('imports', None) - strict_undefined = asbool(sget('strict_undefined', False)) - preprocessor = sget('preprocessor', None) - if not is_nonstr_iter(directories): - directories = list(filter(None, directories.splitlines())) - directories = [ abspath_from_asset_spec(d) for d in directories ] - if module_directory is not None: - module_directory = abspath_from_asset_spec(module_directory) - if error_handler is not None: - dotted = DottedNameResolver(info.package) - error_handler = dotted.maybe_resolve(error_handler) - if default_filters is not None: - if not is_nonstr_iter(default_filters): - default_filters = list(filter( - None, default_filters.splitlines())) - if imports is not None: - if not is_nonstr_iter(imports): - imports = list(filter(None, imports.splitlines())) - if preprocessor is not None: - dotted = DottedNameResolver(info.package) - preprocessor = dotted.maybe_resolve(preprocessor) - - - lookup = PkgResourceTemplateLookup( - directories=directories, - module_directory=module_directory, - input_encoding=input_encoding, - error_handler=error_handler, - default_filters=default_filters, - imports=imports, - filesystem_checks=reload_templates, - strict_undefined=strict_undefined, - preprocessor=preprocessor - ) - - with registry_lock: - registry.registerUtility(lookup, IMakoLookup, - name=settings_prefix) - - return MakoLookupTemplateRenderer(path, defname, lookup) - -renderer_factory = MakoRendererFactoryHelper('mako.') - -class MakoRenderingException(Exception): - def __init__(self, text): - self.text = text - - def __repr__(self): - return self.text - - __str__ = __repr__ - -@implementer(ITemplateRenderer) -class MakoLookupTemplateRenderer(object): - """ Render a :term:`Mako` 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`. If a defname is defined, in the form of - package:path/to/template#defname.mako, a function named ``defname`` - inside the template will then be rendered. - """ - warnings = warnings # for testing - - def __init__(self, path, defname, lookup): - self.path = path - self.defname = defname - self.lookup = lookup - - def implementation(self): - return self.lookup.get_template(self.path) - - def __call__(self, value, system): - context = system.pop('context', None) - if context is not None: - system['_context'] = context - # tuple returned to be deprecated - if isinstance(value, tuple): - self.warnings.warn( - 'Using a tuple in the form (\'defname\', {}) to render a ' - 'Mako partial will be deprecated in the future. Use a ' - 'Mako template renderer as documented in the "Using A ' - 'Mako def name Within a Renderer Name" chapter of the ' - 'Pyramid narrative documentation instead', - DeprecationWarning, - 3) - self.defname, value = value - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - template = self.implementation() - if self.defname is not None: - template = template.get_def(self.defname) - try: - result = template.render_unicode(**system) - except: - try: - exc_info = sys.exc_info() - errtext = text_error_template().render( - error=exc_info[1], - traceback=exc_info[2] - ) - reraise(MakoRenderingException(errtext), None, exc_info[2]) - finally: - del exc_info - - return result diff --git a/pyramid/path.py b/pyramid/path.py index eb92ea62b..470e766f8 100644 --- a/pyramid/path.py +++ b/pyramid/path.py @@ -33,8 +33,12 @@ def package_name(pkg_or_module): name of the package itself.""" if pkg_or_module is None or pkg_or_module.__name__ == '__main__': return '__main__' - pkg_filename = pkg_or_module.__file__ pkg_name = pkg_or_module.__name__ + pkg_filename = getattr(pkg_or_module, '__file__', None) + if pkg_filename is None: + # Namespace packages do not have __init__.py* files, + # and so have no __file__ attribute + return pkg_name splitted = os.path.split(pkg_filename) if splitted[-1] in init_names: # it's a package diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 602655be8..6f088a54f 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -1,8 +1,5 @@ import json import os -import re -import pkg_resources -import threading from zope.interface import ( implementer, @@ -11,18 +8,13 @@ from zope.interface import ( from zope.interface.registry import Components from pyramid.interfaces import ( - IChameleonLookup, - IChameleonTranslate, IJSONAdapter, IRendererGlobalsFactory, IRendererFactory, IResponseFactory, - ITemplateRenderer, IRendererInfo, ) -from pyramid.asset import asset_spec_from_abspath - from pyramid.compat import ( string_types, text_type, @@ -32,10 +24,7 @@ from pyramid.decorator import reify from pyramid.events import BeforeRender -from pyramid.path import ( - caller_package, - package_path, - ) +from pyramid.path import caller_package from pyramid.response import Response from pyramid.threadlocal import get_current_registry @@ -85,7 +74,23 @@ def render(renderer_name, value, request=None, package=None): package = caller_package() helper = RendererHelper(name=renderer_name, package=package, registry=registry) - return helper.render(value, None, request=request) + + saved_response = None + # save the current response, preventing the renderer from affecting it + attrs = request.__dict__ if request is not None else {} + if 'response' in attrs: + saved_response = attrs['response'] + del attrs['response'] + + result = helper.render(value, None, request=request) + + # restore the original response, overwriting any changes + if saved_response is not None: + attrs['response'] = saved_response + elif 'response' in attrs: + del attrs['response'] + + return result def render_to_response(renderer_name, value, request=None, package=None): """ Using the renderer ``renderer_name`` (a template @@ -360,128 +365,6 @@ class JSONP(JSON): return body return _render -# utility functions, not API - -@implementer(IChameleonLookup) -class ChameleonRendererLookup(object): - spec_re = re.compile( - r'(?P<asset>[\w_.:/-]+)' - r'(?:\#(?P<defname>[\w_]+))?' - r'(\.(?P<ext>.*))' - ) - - def __init__(self, impl, registry): - self.impl = impl - self.registry = registry - self.lock = threading.Lock() - - def get_spec(self, name, package): - if not package: - # if there's no package, we can't do any conversion - return name - - spec = name - isabspath = os.path.isabs(name) - colon_in_name = ':' in name - isabsspec = colon_in_name and (not isabspath) - isrelspec = (not isabsspec) and (not isabspath) - - # if it's already an absolute spec, we don't need to do anything, - # but if it's a relative spec or an absolute path, we need to try - # to convert it to an absolute spec - - if isrelspec: - # convert relative asset spec to absolute asset spec - pp = package_path(package) - spec = os.path.join(pp, spec) - spec = asset_spec_from_abspath(spec, package) - - elif isabspath: - # convert absolute path to absolute asset spec - spec = asset_spec_from_abspath(spec, package) - - return spec - - @property # wait until completely necessary to look up translator - def translate(self): - return self.registry.queryUtility(IChameleonTranslate) - - @property # wait until completely necessary to look up debug_templates - def debug(self): - settings = self.registry.settings - if settings is None: - return False - return settings.get('debug_templates', False) - - @property # wait until completely necessary to look up reload_templates - def auto_reload(self): - settings = self.registry.settings - if settings is None: - return False - return settings.get('reload_templates', False) - - def _crack_spec(self, spec): - asset, macro, ext = self.spec_re.match(spec).group( - 'asset', 'defname', 'ext' - ) - return asset, macro, ext - - def __call__(self, info): - spec = self.get_spec(info.name, info.package) - registry = info.registry - - if os.path.isabs(spec): - # 'spec' is an absolute filename - if not os.path.exists(spec): - raise ValueError('Missing template file: %s' % spec) - renderer = registry.queryUtility(ITemplateRenderer, name=spec) - if renderer is None: - renderer = self.impl(spec, self, macro=None) - # cache the template - with self.lock: - registry.registerUtility(renderer, - ITemplateRenderer, name=spec) - else: - # spec is a package:relpath asset spec - renderer = registry.queryUtility(ITemplateRenderer, name=spec) - if renderer is None: - asset, macro, ext = self._crack_spec(spec) - spec_without_macro = '%s.%s' % (asset, ext) - try: - package_name, filename = spec_without_macro.split(':', 1) - except ValueError: # pragma: no cover - # somehow we were passed a relative pathname; this - # should die - package_name = caller_package(4).__name__ - filename = spec_without_macro - abspath = pkg_resources.resource_filename(package_name, - filename) - if not pkg_resources.resource_exists(package_name, filename): - raise ValueError( - 'Missing template asset: %s (%s)' % ( - spec_without_macro, abspath) - ) - renderer = self.impl(abspath, self, macro=macro) - settings = info.settings - if not settings.get('reload_assets'): - # cache the template - with self.lock: - registry.registerUtility(renderer, ITemplateRenderer, - name=spec) - - return renderer - -registry_lock = threading.Lock() - -def template_renderer_factory(info, impl, lock=registry_lock): - registry = info.registry - lookup = registry.queryUtility(IChameleonLookup, name=info.type) - if lookup is None: - lookup = ChameleonRendererLookup(impl, registry) - with lock: - registry.registerUtility(lookup, IChameleonLookup, name=info.type) - return lookup(info) - @implementer(IRendererInfo) class RendererHelper(object): def __init__(self, name=None, package=None, registry=None): @@ -576,26 +459,6 @@ class RendererHelper(object): else: response.body = result - if request is not None: - # deprecated mechanism to set up request.response_* attrs, see - # pyramid.request.Request - attrs = request.__dict__ - content_type = attrs.get('_response_content_type', None) - if content_type is not None: - response.content_type = content_type - headerlist = attrs.get('_response_headerlist', None) - if headerlist is not None: - for k, v in headerlist: - response.headers.add(k, v) - status = attrs.get('_response_status', None) - if status is not None: - response.status = status - charset = attrs.get('_response_charset', None) - if charset is not None: - response.charset = charset - cache_for = attrs.get('_response_cache_for', None) - if cache_for is not None: - response.cache_expires = cache_for return response def clone(self, name=None, package=None, registry=None): diff --git a/pyramid/request.py b/pyramid/request.py index 9b62bee00..5c064d3ef 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -111,88 +111,6 @@ class DeprecatedRequestMethodsMixin(object): def values(self): return self.environ.values() - # 1.0 deprecated bw compat code for using response_* values - - rr_dep = ('Accessing and setting "request.response_%s" is ' - 'deprecated as of Pyramid 1.1; access or set ' - '"request.response.%s" instead.') - - # response_content_type - def _response_content_type_get(self): - return self._response_content_type - def _response_content_type_set(self, value): - self._response_content_type = value - def _response_content_type_del(self): - del self._response_content_type - response_content_type = property(_response_content_type_get, - _response_content_type_set, - _response_content_type_del) - response_content_type = deprecated( - response_content_type, - rr_dep % ('content_type', 'content_type')) - - # response_headerlist - def _response_headerlist_get(self): - return self._response_headerlist - def _response_headerlist_set(self, value): - self._response_headerlist = value - def _response_headerlist_del(self): - del self._response_headerlist - response_headerlist = property(_response_headerlist_get, - _response_headerlist_set, - _response_headerlist_del) - - hl_dep = ('Accessing and setting "request.response_headerlist" is ' - 'deprecated as of Pyramid 1.1; access the headerlist via ' - '"request.response.headerlist" and extend headers via ' - '"request.response.headerlist.extend(alist)" instead of ' - '"request.response_headerlist = alist"') - - response_headerlist = deprecated(response_headerlist, hl_dep) - - # response_status - def _response_status_get(self): - return self._response_status - def _response_status_set(self, value): - self._response_status = value - def _response_status_del(self): - del self._response_status - response_status = property(_response_status_get, - _response_status_set, - _response_status_del) - - response_status = deprecated( - response_status, - rr_dep % ('status', 'status')) - - # response_charset - def _response_charset_get(self): - return self._response_charset - def _response_charset_set(self, value): - self._response_charset = value - def _response_charset_del(self): - del self._response_charset - response_charset = property(_response_charset_get, - _response_charset_set, - _response_charset_del) - response_charset = deprecated( - response_charset, - rr_dep % ('charset', 'charset')) - - # response_cache_for - def _response_cache_for_get(self): - return self._response_cache_for - def _response_cache_for_set(self, value): - self._response_cache_for = value - def _response_cache_for_del(self): - del self._response_cache_for - response_cache_for = property(_response_cache_for_get, - _response_cache_for_set, - _response_cache_for_del) - response_cache_for = deprecated( - response_cache_for, - rr_dep % ('cache_for', 'cache_expires')) - class CallbackMethodsMixin(object): response_callbacks = () finished_callbacks = () diff --git a/pyramid/router.py b/pyramid/router.py index 1a991648b..6239f3980 100644 --- a/pyramid/router.py +++ b/pyramid/router.py @@ -212,13 +212,13 @@ class Router(object): - causes a :class:`~pyramid.event.ContextFound` event to be sent when a context resource is found. - - causes a :class:`~pyramid.event.NewResponse` event to be sent when - the Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the request's lifetime if a response is obtained from the Pyramid application. + - causes a :class:`~pyramid.event.NewResponse` event to be sent if a + response is obtained. + - Calls any :term:`finished callback` functions defined within the request's lifetime. @@ -245,11 +245,12 @@ class Router(object): if extensions is not None: request._set_extensions(extensions) response = handle_request(request) - has_listeners and notify(NewResponse(request, response)) if request.response_callbacks: request._process_response_callbacks(response) + has_listeners and notify(NewResponse(request, response)) + return response finally: diff --git a/pyramid/scaffolds/alchemy/+package+/models.py b/pyramid/scaffolds/alchemy/+package+/models.py index db1fee832..a0d3e7b71 100644 --- a/pyramid/scaffolds/alchemy/+package+/models.py +++ b/pyramid/scaffolds/alchemy/+package+/models.py @@ -24,8 +24,4 @@ class MyModel(Base): name = Column(Text) value = Column(Integer) - def __init__(self, name, value): - self.name = name - self.value = value - Index('my_index', MyModel.name, unique=True, mysql_length=255) diff --git a/pyramid/tests/fixtures/components.mak b/pyramid/tests/fixtures/components.mak deleted file mode 100644 index cc886805c..000000000 --- a/pyramid/tests/fixtures/components.mak +++ /dev/null @@ -1,3 +0,0 @@ -<%def name="comp()"> -World! -</%def>
\ No newline at end of file diff --git a/pyramid/tests/fixtures/hello .world.mako b/pyramid/tests/fixtures/hello .world.mako deleted file mode 100644 index 7a06eed97..000000000 --- a/pyramid/tests/fixtures/hello .world.mako +++ /dev/null @@ -1,3 +0,0 @@ -## -*- coding: utf-8 -*- -<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %> -Hello ${text_('föö', 'utf-8')}
\ No newline at end of file diff --git a/pyramid/tests/fixtures/hello_inherit_pkg.mak b/pyramid/tests/fixtures/hello_inherit_pkg.mak deleted file mode 100644 index 87d18d0f7..000000000 --- a/pyramid/tests/fixtures/hello_inherit_pkg.mak +++ /dev/null @@ -1,2 +0,0 @@ -Hello World! -<%inherit file="pyramid.tests:fixtures/layout.mak"/>
\ No newline at end of file diff --git a/pyramid/tests/fixtures/hellocompo.mak b/pyramid/tests/fixtures/hellocompo.mak deleted file mode 100644 index 142676a11..000000000 --- a/pyramid/tests/fixtures/hellocompo.mak +++ /dev/null @@ -1,3 +0,0 @@ -<%namespace name="comp" file="pyramid.tests:fixtures/components.mak"/> -Namespace -Hello ${comp.comp()}
\ No newline at end of file diff --git a/pyramid/tests/fixtures/helloinherit.mak b/pyramid/tests/fixtures/helloinherit.mak deleted file mode 100644 index 53edd71ed..000000000 --- a/pyramid/tests/fixtures/helloinherit.mak +++ /dev/null @@ -1,2 +0,0 @@ -Hello World! -<%inherit file="layout.mak"/>
\ No newline at end of file diff --git a/pyramid/tests/fixtures/helloworld.mak b/pyramid/tests/fixtures/helloworld.mak deleted file mode 100644 index 25283a50d..000000000 --- a/pyramid/tests/fixtures/helloworld.mak +++ /dev/null @@ -1,3 +0,0 @@ -## -*- coding: utf-8 -*- -<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %> -Hello ${text_('föö', 'utf-8')} diff --git a/pyramid/tests/fixtures/helloworld.mako b/pyramid/tests/fixtures/helloworld.mako deleted file mode 100644 index 25283a50d..000000000 --- a/pyramid/tests/fixtures/helloworld.mako +++ /dev/null @@ -1,3 +0,0 @@ -## -*- coding: utf-8 -*- -<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %> -Hello ${text_('föö', 'utf-8')} diff --git a/pyramid/tests/fixtures/layout.mak b/pyramid/tests/fixtures/layout.mak deleted file mode 100644 index 3bef88bf8..000000000 --- a/pyramid/tests/fixtures/layout.mak +++ /dev/null @@ -1,2 +0,0 @@ -Layout -${next.body()}
\ No newline at end of file diff --git a/pyramid/tests/fixtures/minimal.pt b/pyramid/tests/fixtures/minimal.pt deleted file mode 100644 index 693d155ef..000000000 --- a/pyramid/tests/fixtures/minimal.pt +++ /dev/null @@ -1,3 +0,0 @@ -<div xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -</div> diff --git a/pyramid/tests/fixtures/nonminimal.mak b/pyramid/tests/fixtures/nonminimal.mak deleted file mode 100644 index 9de95ec92..000000000 --- a/pyramid/tests/fixtures/nonminimal.mak +++ /dev/null @@ -1 +0,0 @@ -Hello, ${name}! diff --git a/pyramid/tests/fixtures/pp.pt b/pyramid/tests/fixtures/pp.pt deleted file mode 100644 index 9df7d22da..000000000 --- a/pyramid/tests/fixtures/pp.pt +++ /dev/null @@ -1,3 +0,0 @@ -<p xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal" - tal:content="wrapped">WRAPPED</p> diff --git a/pyramid/tests/fixtures/withmacro.pt b/pyramid/tests/fixtures/withmacro.pt deleted file mode 100644 index 6fa654645..000000000 --- a/pyramid/tests/fixtures/withmacro.pt +++ /dev/null @@ -1,7 +0,0 @@ -<html> -Outside macro -<metal:m define-macro="foo"> - Hello! -</metal:m> -</html> - diff --git a/pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt b/pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt deleted file mode 100644 index 90531a4b3..000000000 --- a/pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt +++ /dev/null @@ -1,2 +0,0 @@ -<html> -</html> diff --git a/pyramid/tests/pkgs/fixtureapp/templates/fixture.pt b/pyramid/tests/pkgs/fixtureapp/templates/fixture.pt deleted file mode 100644 index 06dd4e2b1..000000000 --- a/pyramid/tests/pkgs/fixtureapp/templates/fixture.pt +++ /dev/null @@ -1,6 +0,0 @@ -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head></head> -<body> -</body> -</html> diff --git a/pyramid/tests/pkgs/rendererscanapp/__init__.py b/pyramid/tests/pkgs/rendererscanapp/__init__.py index 1baec0940..f3276a063 100644 --- a/pyramid/tests/pkgs/rendererscanapp/__init__.py +++ b/pyramid/tests/pkgs/rendererscanapp/__init__.py @@ -1,6 +1,6 @@ from pyramid.view import view_config -@view_config(name='one', renderer='one.pt') +@view_config(name='one', renderer='json') def one(request): return {'name':'One!'} diff --git a/pyramid/tests/pkgs/rendererscanapp/one.pt b/pyramid/tests/pkgs/rendererscanapp/one.pt deleted file mode 100644 index 42114d94f..000000000 --- a/pyramid/tests/pkgs/rendererscanapp/one.pt +++ /dev/null @@ -1,4 +0,0 @@ -<div xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - ${name} -</div> diff --git a/pyramid/tests/pkgs/rendererscanapp/two/__init__.py b/pyramid/tests/pkgs/rendererscanapp/two/__init__.py index be0077fcb..6f575dd83 100644 --- a/pyramid/tests/pkgs/rendererscanapp/two/__init__.py +++ b/pyramid/tests/pkgs/rendererscanapp/two/__init__.py @@ -1,6 +1,6 @@ from pyramid.view import view_config -@view_config(name='two', renderer='two.pt') +@view_config(name='two', renderer='json') def two(request): return {'nameagain':'Two!'} diff --git a/pyramid/tests/pkgs/rendererscanapp/two/two.pt b/pyramid/tests/pkgs/rendererscanapp/two/two.pt deleted file mode 100644 index 7eff97c22..000000000 --- a/pyramid/tests/pkgs/rendererscanapp/two/two.pt +++ /dev/null @@ -1,4 +0,0 @@ -<div xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> - ${nameagain} -</div> diff --git a/pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt b/pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt deleted file mode 100644 index 6a2f701b6..000000000 --- a/pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt +++ /dev/null @@ -1,3 +0,0 @@ -<html> -${result} -</html> diff --git a/pyramid/tests/pkgs/viewdecoratorapp/views/views.py b/pyramid/tests/pkgs/viewdecoratorapp/views/views.py index 2b7d7e928..18ec78847 100644 --- a/pyramid/tests/pkgs/viewdecoratorapp/views/views.py +++ b/pyramid/tests/pkgs/viewdecoratorapp/views/views.py @@ -1,11 +1,11 @@ from pyramid.view import view_config -@view_config(renderer='templates/foo.pt', name='first') +@view_config(renderer='json', name='first') def first(request): return {'result':'OK1'} @view_config( - renderer='pyramid.tests.pkgs.viewdecoratorapp.views:templates/foo.pt', + renderer='json', name='second') def second(request): return {'result':'OK2'} diff --git a/pyramid/tests/test_chameleon_text.py b/pyramid/tests/test_chameleon_text.py deleted file mode 100644 index d9f20f241..000000000 --- a/pyramid/tests/test_chameleon_text.py +++ /dev/null @@ -1,145 +0,0 @@ -import sys -import unittest - -from pyramid.compat import binary_type -from pyramid import testing - -class Base(object): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', 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): - from pyramid.chameleon_text import TextTemplateRenderer - return TextTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITemplateRenderer - path = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - verifyObject(ITemplateRenderer, self._makeOne(path, lookup)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_template_reified(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template, instance.__dict__['template']) - - def test_template_with_ichameleon_translate(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.translate, lookup.translate) - - def test_template_with_debug_templates(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - lookup.debug = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, True) - - def test_template_with_reload_templates(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - lookup.auto_reload = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, True) - - def test_template_without_reload_templates(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - lookup.auto_reload = False - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, False) - - def test_call(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance({}, {}) - self.assertTrue(isinstance(result, binary_type)) - self.assertEqual(result, b'Hello.\n') - - def test_call_with_nondict_value(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertRaises(ValueError, instance, None, {}) - - def test_call_nonminimal(self): - nonminimal = self._getTemplatePath('nonminimal.txt') - lookup = DummyLookup() - instance = self._makeOne(nonminimal, lookup) - result = instance({'name':'Chris'}, {}) - self.assertTrue(isinstance(result, binary_type)) - self.assertEqual(result, b'Hello, Chris!\n') - - def test_implementation(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance.implementation()() - self.assertTrue(isinstance(result, binary_type)) - self.assertEqual(result, b'Hello.\n') - -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 = {} - diff --git a/pyramid/tests/test_chameleon_zpt.py b/pyramid/tests/test_chameleon_zpt.py deleted file mode 100644 index d7ca94298..000000000 --- a/pyramid/tests/test_chameleon_zpt.py +++ /dev/null @@ -1,175 +0,0 @@ -import sys -import unittest - -from pyramid import testing -from pyramid.compat import text_type - -class Base(object): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', name) - -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 - return ZPTTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITemplateRenderer - path = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - verifyObject(ITemplateRenderer, self._makeOne(path, lookup)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_call(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance({}, {}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result.rstrip('\n'), - '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') - - def test_template_reified(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template, instance.__dict__['template']) - - def test_template_with_ichameleon_translate(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.translate, lookup.translate) - - def test_template_with_debug_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.debug = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, True) - - def test_template_without_debug_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.debug = False - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, False) - - def test_template_with_reload_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.auto_reload = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, True) - - def test_template_without_reload_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.auto_reload = False - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, False) - - def test_call_with_nondict_value(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertRaises(ValueError, instance, None, {}) - - def test_implementation(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance.implementation()() - 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') - - def test_macro_notsupplied(self): - minimal = self._getTemplatePath('withmacro.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance.implementation()() - self.assertEqual(result, - '<html>\nOutside macro\n\n Hello!\n\n</html>\n\n') - - def test_macro_template_reload(self): - minimal = self._getTemplatePath('withmacro.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup, macro='foo') - result = instance.implementation()() - self.assertEqual(result, '\n Hello!\n') - instance.template.cook( - '<html>\nOutside macro\n\n Hello!\n\n</html>\n\n' - ) - result = instance.implementation()() - self.assertEqual(result, '\n Hello!\n') - -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 = {} - diff --git a/pyramid/tests/test_config/files/minimal.pt b/pyramid/tests/test_config/files/minimal.pt deleted file mode 100644 index 693d155ef..000000000 --- a/pyramid/tests/test_config/files/minimal.pt +++ /dev/null @@ -1,3 +0,0 @@ -<div xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -</div> diff --git a/pyramid/tests/test_config/files/minimal.txt b/pyramid/tests/test_config/files/minimal.txt new file mode 100644 index 000000000..19fe66dfa --- /dev/null +++ b/pyramid/tests/test_config/files/minimal.txt @@ -0,0 +1 @@ +<div clas="header"></div> diff --git a/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt b/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt deleted file mode 100644 index 90531a4b3..000000000 --- a/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt +++ /dev/null @@ -1,2 +0,0 @@ -<html> -</html> diff --git a/pyramid/tests/test_config/pkgs/asset/templates/fixture.pt b/pyramid/tests/test_config/pkgs/asset/templates/fixture.pt deleted file mode 100644 index 06dd4e2b1..000000000 --- a/pyramid/tests/test_config/pkgs/asset/templates/fixture.pt +++ /dev/null @@ -1,6 +0,0 @@ -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head></head> -<body> -</body> -</html> diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py index fdee0416f..71c68af8a 100644 --- a/pyramid/tests/test_config/test_i18n.py +++ b/pyramid/tests/test_config/test_i18n.py @@ -42,13 +42,10 @@ class TestI18NConfiguratorMixin(unittest.TestCase): def test_add_translation_dirs_no_specs(self): from pyramid.interfaces import ITranslationDirectories - from pyramid.interfaces import IChameleonTranslate config = self._makeOne() config.add_translation_dirs() self.assertEqual(config.registry.queryUtility(ITranslationDirectories), None) - self.assertEqual(config.registry.queryUtility(IChameleonTranslate), - None) def test_add_translation_dirs_asset_spec(self): from pyramid.interfaces import ITranslationDirectories @@ -83,21 +80,6 @@ class TestI18NConfiguratorMixin(unittest.TestCase): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale3, locale, locale2]) - def test_add_translation_dirs_registers_chameleon_translate(self): - from pyramid.interfaces import IChameleonTranslate - from pyramid.threadlocal import manager - from pyramid.request import Request - config = self._makeOne(autocommit=True) - request = Request.blank('/') - request.registry = config.registry - manager.push({'request':request, 'registry':config.registry}) - try: - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - translate = config.registry.getUtility(IChameleonTranslate) - self.assertEqual(translate('Approve'), 'Approve') - finally: - manager.pop() - def test_add_translation_dirs_abspath(self): from pyramid.interfaces import ITranslationDirectories config = self._makeOne(autocommit=True) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index b8cbbd676..4c6fd3ab9 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -69,11 +69,6 @@ class ConfiguratorTests(unittest.TestCase): config.commit() self.assertTrue(config.registry.getUtility(IRendererFactory, 'json')) self.assertTrue(config.registry.getUtility(IRendererFactory, 'string')) - if not PYPY: - self.assertTrue(config.registry.getUtility(IRendererFactory, '.pt')) - self.assertTrue(config.registry.getUtility(IRendererFactory,'.txt')) - self.assertTrue(config.registry.getUtility(IRendererFactory, '.mak')) - self.assertTrue(config.registry.getUtility(IRendererFactory, '.mako')) def test_begin(self): from pyramid.config import Configurator @@ -1225,19 +1220,6 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): (classifier, request_iface, ctx_iface), IView, name=name, default=None) - def _registerRenderer(self, config, name='.txt'): - from pyramid.interfaces import IRendererFactory - from pyramid.interfaces import ITemplateRenderer - from zope.interface import implementer - @implementer(ITemplateRenderer) - class Renderer: - def __init__(self, info): - self.__class__.info = info - def __call__(self, *arg): - return 'Hello!' - config.registry.registerUtility(Renderer, IRendererFactory, name=name) - return Renderer - def _assertRoute(self, config, name, path, num_predicates=0): from pyramid.interfaces import IRoutesMapper mapper = config.registry.getUtility(IRoutesMapper) @@ -1323,19 +1305,17 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): def test_add_route_with_view_renderer(self): config = self._makeOne(autocommit=True) - self._registerRenderer(config) view = lambda *arg: 'OK' config.add_route('name', 'path', view=view, - view_renderer='files/minimal.txt') + view_renderer='json') request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, b'Hello!') + self.assertEqual(wrapper(None, None).body, b'"OK"') def test_add_route_with_view_attr(self): from pyramid.renderers import null_renderer config = self._makeOne(autocommit=True) - self._registerRenderer(config) class View(object): def __init__(self, context, request): pass @@ -1351,14 +1331,13 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): def test_add_route_with_view_renderer_alias(self): config = self._makeOne(autocommit=True) - self._registerRenderer(config) view = lambda *arg: 'OK' config.add_route('name', 'path', view=view, - renderer='files/minimal.txt') + renderer='json') request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, b'Hello!') + self.assertEqual(wrapper(None, None).body, b'"OK"') def test_add_route_with_view_permission(self): from pyramid.interfaces import IAuthenticationPolicy diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 94bc497ba..618ac2bf4 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -47,7 +47,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): def __init__(self, info): self.__class__.info = info def __call__(self, *arg): - return 'Hello!' + return b'Hello!' config.registry.registerUtility(Renderer, IRendererFactory, name=name) return Renderer @@ -264,7 +264,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') - + def test_add_view_as_instance_requestonly(self): from pyramid.renderers import null_renderer class AView: @@ -994,7 +994,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): pass foo = Foo() bar = Bar() - + from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier @@ -1029,6 +1029,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config = self._makeOne(autocommit=True) renderer = self._registerRenderer(config) fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.introspection = False config.add_view(view=view, renderer=fixture) wrapper = self._getViewCallable(config) request = self._makeRequest(config) @@ -1055,7 +1056,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): def __init__(self, *arg, **kw): pass def __call__(self, *arg, **kw): - return 'moo' + return b'moo' config.add_renderer(None, moo) config.add_view(view=view) wrapper = self._getViewCallable(config) @@ -1069,6 +1070,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config = self._makeOne(autocommit=True) renderer = self._registerRenderer(config) fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.introspection = False config.add_view(view=None, renderer=fixture) wrapper = self._getViewCallable(config) request = self._makeRequest(config) @@ -1198,7 +1200,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): request = self._makeRequest(config) request.method = 'HEAD' self.assertEqual(wrapper(None, request), 'OK') - + def test_add_view_with_request_param_noval_true(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' @@ -1585,7 +1587,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): context = DummyContext() request = self._makeRequest(config) self.assertRaises(PredicateMismatch, wrapper, context, request) - + def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self): from pyramid.renderers import null_renderer class view(object): @@ -1663,7 +1665,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): def __init__(self, view): pass def __call__(self, *arg, **kw): - return 'foo' + return b'foo' def view(request): return 'OK' config = self._makeOne() @@ -1687,8 +1689,8 @@ class TestViewsConfigurationMixin(unittest.TestCase): wrapped = config.registry.adapters.lookup( (IViewClassifier, request_type, Interface), IView, name='') from pyramid.request import Request - request = Request.blank('/static/minimal.pt') - request.subpath = ('minimal.pt', ) + request = Request.blank('/static/minimal.txt') + request.subpath = ('minimal.txt', ) result = wrapped(None, request) self.assertEqual(result.status, '200 OK') self.assertTrue(result.body.startswith(b'<div')) @@ -1725,7 +1727,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config.add_static_view('static', static_path) self.assertEqual(info.added, [(config, 'static', static_path, {})]) - + def test_add_forbidden_view(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy @@ -1819,7 +1821,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config = self._makeOne(autocommit=True) self.assertRaises(ConfigurationError, config.add_notfound_view, http_cache='foo') - + def test_add_notfound_view_append_slash(self): from pyramid.response import Response from pyramid.renderers import null_renderer @@ -1839,26 +1841,31 @@ class TestViewsConfigurationMixin(unittest.TestCase): request_iface=IRequest) result = view(None, request) self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2') - + + # Since Python 3 has to be all cool and fancy and different... + def _assertBody(self, response, value): + from pyramid.compat import text_type + if isinstance(value, text_type): # pragma: nocover + self.assertEqual(response.text, value) + else: # pragma: nocover + self.assertEqual(response.body, value) + def test_add_notfound_view_with_renderer(self): from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.httpexceptions import HTTPNotFound config = self._makeOne(autocommit=True) view = lambda *arg: {} + config.introspection = False config.add_notfound_view( view, - renderer='pyramid.tests.test_config:files/minimal.pt') - config.begin() - try: # chameleon depends on being able to find a threadlocal registry - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPNotFound), - request_iface=IRequest) - result = view(None, request) - finally: - config.end() - self.assertTrue(b'div' in result.body) + renderer='json') + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPNotFound), + request_iface=IRequest) + result = view(None, request) + self._assertBody(result, '{}') def test_add_forbidden_view_with_renderer(self): from zope.interface import implementedBy @@ -1866,19 +1873,16 @@ class TestViewsConfigurationMixin(unittest.TestCase): from pyramid.httpexceptions import HTTPForbidden config = self._makeOne(autocommit=True) view = lambda *arg: {} + config.introspection = False config.add_forbidden_view( view, - renderer='pyramid.tests.test_config:files/minimal.pt') - config.begin() - try: # chameleon requires a threadlocal registry - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPForbidden), - request_iface=IRequest) - result = view(None, request) - finally: - config.end() - self.assertTrue(b'div' in result.body) + renderer='json') + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPForbidden), + request_iface=IRequest) + result = view(None, request) + self._assertBody(result, '{}') def test_set_view_mapper(self): from pyramid.interfaces import IViewMapperFactory @@ -2228,12 +2232,12 @@ class TestViewDeriver(unittest.TestCase): def tearDown(self): self.config = None - + def _makeOne(self, **kw): kw['registry'] = self.config.registry from pyramid.config.views import ViewDeriver return ViewDeriver(**kw) - + def _makeRequest(self): request = DummyRequest() request.registry = self.config.registry @@ -2262,7 +2266,7 @@ class TestViewDeriver(unittest.TestCase): result(None, None) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], 'Could not convert return value of the view callable function ' 'pyramid.tests.test_config.test_views.view into a response ' 'object. The value returned was None. You may have forgotten ' @@ -2281,7 +2285,7 @@ class TestViewDeriver(unittest.TestCase): result(None, None) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], "Could not convert return value of the view callable function " "pyramid.tests.test_config.test_views.view into a response " "object. The value returned was {'a': 1}. You may have " @@ -2289,7 +2293,7 @@ class TestViewDeriver(unittest.TestCase): ) else: # pragma: no cover raise AssertionError - + def test_instance_returns_non_adaptable(self): class AView(object): def __call__(self, request): @@ -2348,7 +2352,7 @@ class TestViewDeriver(unittest.TestCase): result(None, request) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], 'Could not convert return value of the view callable ' 'method __call__ of ' 'class pyramid.tests.test_config.test_views.AView into a ' @@ -2372,7 +2376,7 @@ class TestViewDeriver(unittest.TestCase): result(None, request) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], 'Could not convert return value of the view callable ' 'method theviewmethod of ' 'class pyramid.tests.test_config.test_views.AView into a ' @@ -2381,7 +2385,7 @@ class TestViewDeriver(unittest.TestCase): ) else: # pragma: no cover raise AssertionError - + def test_requestonly_function(self): response = DummyResponse() def view(request): @@ -2415,7 +2419,7 @@ class TestViewDeriver(unittest.TestCase): self.assertEqual(value, 'OK') self.assertEqual(system['request'], request) self.assertEqual(system['context'], context) - return 'moo' + return b'moo' return inner def view(request): return 'OK' @@ -2932,7 +2936,7 @@ class TestViewDeriver(unittest.TestCase): 'predicate mismatch for view myview (pred2)') else: # pragma: no cover raise AssertionError - + def test_with_predicates_all(self): response = DummyResponse() view = lambda *arg: response @@ -3243,7 +3247,7 @@ class TestViewDeriver(unittest.TestCase): expires = parse_httpdate(headers['Expires']) assert_similar_datetime(expires, when) self.assertEqual(headers['Cache-Control'], 'max-age=3600') - + def test_http_cached_view_timedelta(self): import datetime from pyramid.response import Response @@ -3339,7 +3343,7 @@ class TestViewDeriver(unittest.TestCase): class TestDefaultViewMapper(unittest.TestCase): def setUp(self): self.config = testing.setUp() - self.registry = self.config.registry + self.registry = self.config.registry def tearDown(self): del self.registry @@ -3601,7 +3605,7 @@ class TestStaticURLInfo(unittest.TestCase): def _getTargetClass(self): from pyramid.config.views import StaticURLInfo return StaticURLInfo - + def _makeOne(self): return self._getTargetClass()() @@ -3828,42 +3832,46 @@ class Test_view_description(unittest.TestCase): def _callFUT(self, view): from pyramid.config.views import view_description return view_description(view) - + def test_with_text(self): def view(): pass view.__text__ = 'some text' result = self._callFUT(view) self.assertEqual(result, 'some text') - + def test_without_text(self): def view(): pass result = self._callFUT(view) - self.assertEqual(result, + self.assertEqual(result, 'function pyramid.tests.test_config.test_views.view') - + class DummyRegistry: pass +from zope.interface import implementer +from pyramid.interfaces import IResponse +@implementer(IResponse) +class DummyResponse(object): + content_type = None + default_content_type = None + body = None + class DummyRequest: subpath = () matchdict = None + def __init__(self, environ=None): if environ is None: environ = {} self.environ = environ self.params = {} self.cookies = {} + self.response = DummyResponse() class DummyContext: pass -from zope.interface import implementer -from pyramid.interfaces import IResponse -@implementer(IResponse) -class DummyResponse(object): - pass - class DummyAccept(object): def __init__(self, *matches): self.matches = list(matches) diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index 391310432..9d3a9e004 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -74,8 +74,8 @@ here = os.path.dirname(__file__) class StaticAppBase(IntegrationBase): def test_basic(self): - res = self.testapp.get('/minimal.pt', status=200) - _assertBody(res.body, os.path.join(here, 'fixtures/minimal.pt')) + res = self.testapp.get('/minimal.txt', status=200) + _assertBody(res.body, os.path.join(here, 'fixtures/minimal.txt')) def test_hidden(self): res = self.testapp.get('/static/.hiddenfile', status=200) @@ -119,7 +119,7 @@ class StaticAppBase(IntegrationBase): def test_not_modified(self): self.testapp.extra_environ = { 'HTTP_IF_MODIFIED_SINCE':httpdate(fiveyrsfuture)} - res = self.testapp.get('/minimal.pt', status=304) + res = self.testapp.get('/minimal.txt', status=304) self.assertEqual(res.body, b'') def test_file_in_subdir(self): @@ -222,19 +222,19 @@ class TestStaticAppNoSubpath(unittest.TestCase): return request def test_basic(self): - request = self._makeRequest({'PATH_INFO':'/minimal.pt'}) + request = self._makeRequest({'PATH_INFO':'/minimal.txt'}) context = DummyContext() result = self.staticapp(context, request) self.assertEqual(result.status, '200 OK') - _assertBody(result.body, os.path.join(here, 'fixtures/minimal.pt')) + _assertBody(result.body, os.path.join(here, 'fixtures/minimal.txt')) class TestStaticAppWithRoutePrefix(IntegrationBase, unittest.TestCase): package = 'pyramid.tests.pkgs.static_routeprefix' def test_includelevel1(self): - res = self.testapp.get('/static/minimal.pt', status=200) + res = self.testapp.get('/static/minimal.txt', status=200) _assertBody(res.body, - os.path.join(here, 'fixtures/minimal.pt')) + os.path.join(here, 'fixtures/minimal.txt')) def test_includelevel2(self): res = self.testapp.get('/prefix/static/index.html', status=200) diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py deleted file mode 100644 index 69485ca19..000000000 --- a/pyramid/tests/test_mako_templating.py +++ /dev/null @@ -1,655 +0,0 @@ -## come on python gimme some of that sweet, sweet -*- coding: utf-8 -*- - -import shutil -import tempfile -import unittest - -from pyramid import testing - -from pyramid.compat import ( - text_, - text_type, - ) - -class Base(object): - def setUp(self): - self.config = testing.setUp() - self.config.begin() - import os - here = os.path.abspath(os.path.dirname(__file__)) - self.templates_dir = os.path.join(here, 'fixtures') - - def tearDown(self): - self.config.end() - -def maybe_unittest(): - # The latest release of MarkupSafe (0.17) which is used by Mako is - # incompatible with Python 3.2, so we skip these tests if we cannot - # import a Mako module which ends up importing MarkupSafe. Note that - # this version of MarkupSafe *is* compatible with Python 2.6, 2.7, and 3.3, - # so these tests should not be skipped on those platforms. - try: - import mako.lookup - except (ImportError, SyntaxError, AttributeError): # pragma: no cover - return object - else: - return unittest.TestCase - -class Test_renderer_factory(Base, maybe_unittest()): - def _callFUT(self, info): - from pyramid.mako_templating import renderer_factory - return renderer_factory(info) - - def _getLookup(self, name='mako.'): - from pyramid.mako_templating import IMakoLookup - return self.config.registry.getUtility(IMakoLookup, name=name) - - def test_hyphen_filenames(self): - from pyramid.mako_templating import renderer_factory - - info = DummyRendererInfo({ - 'name':'app:moon-and-world.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type': '' - }) - - result = renderer_factory(info) - self.assertEqual(result.path, 'app:moon-and-world.mak') - - def test_no_directories(self): - info = DummyRendererInfo({ - 'name':'pyramid.tests:fixtures/helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - renderer = self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.directories, []) - self.assertEqual(lookup.filesystem_checks, False) - self.assertEqual(renderer.path, - 'pyramid.tests:fixtures/helloworld.mak') - self.assertEqual(renderer.lookup, lookup) - - def test_no_lookup(self): - settings = {'mako.directories':self.templates_dir} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - renderer = self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.directories, [self.templates_dir]) - self.assertEqual(lookup.filesystem_checks, False) - self.assertEqual(renderer.path, 'helloworld.mak') - self.assertEqual(renderer.lookup, lookup) - - def test_composite_directories_path(self): - twice = '\n' + self.templates_dir + '\n' + self.templates_dir + '\n' - settings = {'mako.directories':twice} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.directories, [self.templates_dir]*2) - - def test_directories_list(self): - import sys - import os.path - settings = {'mako.directories':['a', 'b']} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - module_path = os.path.dirname( - sys.modules['__main__'].__file__).rstrip('.') # ./setup.py - self.assertEqual(lookup.directories, [ - os.path.join(module_path, 'a'), - os.path.join(module_path, 'b')]) - - def test_with_module_directory_asset_spec(self): - import os - module_directory = 'pyramid.tests:fixtures' - settings = {'mako.directories':self.templates_dir, - 'mako.module_directory':module_directory} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') - self.assertEqual(lookup.module_directory, fixtures) - - def test_with_module_directory_asset_abspath(self): - import os - fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') - settings = {'mako.directories':self.templates_dir, - 'mako.module_directory':fixtures} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.module_directory, fixtures) - - def test_with_input_encoding(self): - settings = {'mako.directories':self.templates_dir, - 'mako.input_encoding':'utf-16'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['input_encoding'], 'utf-16') - - def test_with_error_handler(self): - settings = {'mako.directories':self.templates_dir, - 'mako.error_handler':'pyramid.tests'} - import pyramid.tests - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['error_handler'], pyramid.tests) - - def test_with_preprocessor(self): - settings = {'mako.directories':self.templates_dir, - 'mako.preprocessor':'pyramid.tests'} - import pyramid.tests - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['preprocessor'], pyramid.tests) - - def test_with_default_filters(self): - settings = {'mako.directories':self.templates_dir, - 'mako.default_filters':'\nh\ng\n\n'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) - - def test_with_default_filters_list(self): - settings = {'mako.directories':self.templates_dir, - 'mako.default_filters':['h', 'g']} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) - - def test_with_imports(self): - settings = {'mako.directories':self.templates_dir, - 'mako.imports':'\none\ntwo\n\n'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['imports'], ['one', 'two']) - - def test_with_imports_list(self): - settings = {'mako.directories':self.templates_dir, - 'mako.imports':['one', 'two']} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['imports'], ['one', 'two']) - - def test_with_strict_undefined_true(self): - settings = {'mako.directories':self.templates_dir, - 'mako.strict_undefined':'true'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['strict_undefined'], True) - - def test_with_strict_undefined_false(self): - settings = {'mako.directories':self.templates_dir, - 'mako.strict_undefined':'false'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['strict_undefined'], False) - - def test_with_lookup(self): - from pyramid.mako_templating import IMakoLookup - lookup = dict() - self.config.registry.registerUtility(lookup, IMakoLookup, name='mako.') - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - renderer = self._callFUT(info) - self.assertEqual(renderer.lookup, lookup) - self.assertEqual(renderer.path, 'helloworld.mak') - - def test_space_dot_name(self): - from pyramid.mako_templating import renderer_factory - - info = DummyRendererInfo({ - 'name':'hello .world.mako', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - - result = renderer_factory(info) - self.assertEqual(result.path, 'hello .world.mako') - self.assertTrue(result.defname is None) - - def test_space_dot_name_def(self): - from pyramid.mako_templating import renderer_factory - - info = DummyRendererInfo({ - 'name':'hello .world#comp.mako', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - - result = renderer_factory(info) - self.assertEqual(result.path, 'hello .world.mako') - self.assertEqual(result.defname, 'comp') - -class MakoRendererFactoryHelperTests(Base, maybe_unittest()): - def _getTargetClass(self): - from pyramid.mako_templating import MakoRendererFactoryHelper - return MakoRendererFactoryHelper - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def _getLookup(self, name='mako.'): - from pyramid.mako_templating import IMakoLookup - return self.config.registry.getUtility(IMakoLookup, name=name) - - def test_no_settings_prefix(self): - settings = {'foo.directories':self.templates_dir} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - 'type':'foo', - }) - helper = self._makeOne() - renderer = helper(info) - lookup = self._getLookup('foo.') - self.assertEqual(lookup.directories, [self.templates_dir]) - self.assertEqual(lookup.filesystem_checks, False) - self.assertEqual(renderer.path, 'helloworld.mak') - self.assertEqual(renderer.lookup, lookup) - - def test_custom_settings_prefix(self): - settings = {'bar.directories':self.templates_dir} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - 'type':'foo', - }) - helper = self._makeOne('bar.') - renderer = helper(info) - lookup = self._getLookup('bar.') - self.assertEqual(lookup.directories, [self.templates_dir]) - self.assertEqual(lookup.filesystem_checks, False) - self.assertEqual(renderer.path, 'helloworld.mak') - self.assertEqual(renderer.lookup, lookup) - -class MakoLookupTemplateRendererTests(Base, maybe_unittest()): - def _getTargetClass(self): - from pyramid.mako_templating import MakoLookupTemplateRenderer - return MakoLookupTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITemplateRenderer - verifyObject(ITemplateRenderer, self._makeOne(None, None, None)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_call(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - result = instance({}, {'system':1}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - - def test_call_with_system_context(self): - # lame - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - result = instance({}, {'context':1}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - - def test_call_with_tuple_value(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - warnings = DummyWarnings() - instance.warnings = warnings - result = instance(('fub', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'fub') - self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - self.assertEqual(len(warnings.msgs), 1) - - def test_call_with_defname(self): - lookup = DummyLookup() - instance = self._makeOne('path', 'defname', lookup) - result = instance({}, {'system':1}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - - def test_call_with_defname_with_tuple_value(self): - lookup = DummyLookup() - instance = self._makeOne('path', 'defname', lookup) - warnings = DummyWarnings() - instance.warnings = warnings - result = instance(('defname', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'defname') - self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - self.assertEqual(len(warnings.msgs), 1) - - def test_call_with_defname_with_tuple_value_twice(self): - lookup = DummyLookup() - instance1 = self._makeOne('path', 'defname', lookup) - warnings = DummyWarnings() - instance1.warnings = warnings - result1 = instance1(('defname1', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'defname1') - self.assertEqual(result1, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - instance2 = self._makeOne('path', 'defname', lookup) - warnings = DummyWarnings() - instance2.warnings = warnings - result2 = instance2(('defname2', {}), {'context':2}) - self.assertNotEqual(lookup.deffed, 'defname1') - self.assertEqual(lookup.deffed, 'defname2') - self.assertEqual(result2, text_('result')) - self.assertEqual(lookup.values, {'_context':2}) - - def test_call_with_nondict_value(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - self.assertRaises(ValueError, instance, None, {}) - - def test_call_render_raises(self): - from pyramid.mako_templating import MakoRenderingException - lookup = DummyLookup(exc=NotImplementedError) - instance = self._makeOne('path', None, lookup) - try: - instance({}, {}) - except MakoRenderingException as e: - self.assertTrue('NotImplementedError' in e.text) - else: # pragma: no cover - raise AssertionError - - def test_implementation(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - result = instance.implementation().render_unicode() - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - -class TestIntegration(maybe_unittest()): - def setUp(self): - import pyramid.mako_templating - self.config = testing.setUp() - self.config.add_settings({'mako.directories': - 'pyramid.tests:fixtures'}) - self.config.add_renderer('.mak', - pyramid.mako_templating.renderer_factory) - - def tearDown(self): - self.config.end() - - def test_render(self): - from pyramid.renderers import render - result = render('helloworld.mak', {'a':1}).replace('\r','') - self.assertEqual(result, text_('\nHello föö\n', 'utf-8')) - - def test_render_from_fs(self): - from pyramid.renderers import render - self.config.add_settings({'reload_templates': True}) - result = render('helloworld.mak', {'a':1}).replace('\r','') - self.assertEqual(result, text_('\nHello föö\n', 'utf-8')) - - def test_render_inheritance(self): - from pyramid.renderers import render - result = render('helloinherit.mak', {}).replace('\r','') - self.assertEqual(result, text_('Layout\nHello World!\n')) - - def test_render_inheritance_pkg_spec(self): - from pyramid.renderers import render - result = render('hello_inherit_pkg.mak', {}).replace('\r','') - self.assertEqual(result, text_('Layout\nHello World!\n')) - - def test_render_namespace(self): - from pyramid.renderers import render - result = render('hellocompo.mak', {}).replace('\r','') - self.assertEqual(result, text_('\nNamespace\nHello \nWorld!\n')) - - def test_render_to_response(self): - from pyramid.renderers import render_to_response - result = render_to_response('helloworld.mak', {'a':1}) - self.assertEqual(result.ubody.replace('\r',''), - text_('\nHello föö\n', 'utf-8')) - - def test_render_to_response_pkg_spec(self): - from pyramid.renderers import render_to_response - result = render_to_response('pyramid.tests:fixtures/helloworld.mak', - {'a':1}) - self.assertEqual(result.ubody.replace('\r', ''), - text_('\nHello föö\n', 'utf-8')) - - def test_render_with_abs_path(self): - from pyramid.renderers import render - result = render('/helloworld.mak', {'a':1}).replace('\r','') - self.assertEqual(result, text_('\nHello föö\n', 'utf-8')) - - def test_get_renderer(self): - from pyramid.renderers import get_renderer - result = get_renderer('helloworld.mak') - self.assertEqual( - result.implementation().render_unicode().replace('\r',''), - text_('\nHello föö\n', 'utf-8')) - - def test_template_not_found(self): - from pyramid.renderers import render - from mako.exceptions import TemplateLookupException - self.assertRaises(TemplateLookupException, render, - 'helloworld_not_here.mak', {}) - - def test_template_default_escaping(self): - from pyramid.renderers import render - result = render('nonminimal.mak', - {'name':'<b>fred</b>'}).replace('\r','') - self.assertEqual(result, text_('Hello, <b>fred</b>!\n')) - -class TestPkgResourceTemplateLookup(maybe_unittest()): - def _makeOne(self, **kw): - from pyramid.mako_templating import PkgResourceTemplateLookup - return PkgResourceTemplateLookup(**kw) - - def get_fixturedir(self): - import os - import pyramid.tests - return os.path.join(os.path.dirname(pyramid.tests.__file__), 'fixtures') - - def test_adjust_uri_not_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('a', None) - self.assertEqual(result, '/a') - - def test_adjust_uri_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('a:b', None) - self.assertEqual(result, 'a:b') - - def test_adjust_uri_asset_spec_with_modified_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('a$b', None) - self.assertEqual(result, 'a:b') - - def test_adjust_uri_not_asset_spec_with_relativeto_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('c', 'a:b') - self.assertEqual(result, 'a:c') - - def test_adjust_uri_not_asset_spec_with_relativeto_modified_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('c', 'a$b') - self.assertEqual(result, 'a:c') - - def test_adjust_uri_not_asset_spec_with_relativeto_not_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('b', '../a') - self.assertEqual(result, '../b') - - def test_adjust_uri_not_asset_spec_abs_with_relativeto_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('/c', 'a:b') - self.assertEqual(result, '/c') - - def test_adjust_uri_asset_spec_with_relativeto_not_asset_spec_abs(self): - inst = self._makeOne() - result = inst.adjust_uri('a:b', '/c') - self.assertEqual(result, 'a:b') - - def test_get_template_not_asset_spec(self): - fixturedir = self.get_fixturedir() - inst = self._makeOne(directories=[fixturedir]) - result = inst.get_template('helloworld.mak') - self.assertFalse(result is None) - - def test_get_template_asset_spec_with_filesystem_checks(self): - inst = self._makeOne(filesystem_checks=True) - result = inst.get_template('pyramid.tests:fixtures/helloworld.mak') - self.assertFalse(result is None) - - def test_get_template_asset_spec_with_module_dir(self): - tmpdir = tempfile.mkdtemp() - try: - inst = self._makeOne(module_directory=tmpdir) - result = inst.get_template('pyramid.tests:fixtures/helloworld.mak') - self.assertFalse(result is None) - finally: - shutil.rmtree(tmpdir, ignore_errors=True) - - def test_get_template_asset_spec_missing(self): - from mako.exceptions import TopLevelLookupException - fixturedir = self.get_fixturedir() - inst = self._makeOne(filesystem_checks=True, directories=[fixturedir]) - self.assertRaises(TopLevelLookupException, inst.get_template, - 'pyramid.tests:fixtures/notthere.mak') - -class TestMakoRenderingException(unittest.TestCase): - def _makeOne(self, text): - from pyramid.mako_templating import MakoRenderingException - return MakoRenderingException(text) - - def test_repr_and_str(self): - exc = self._makeOne('text') - self.assertEqual(str(exc), 'text') - self.assertEqual(repr(exc), 'text') - -class DummyLookup(object): - def __init__(self, exc=None): - self.exc = exc - - def get_template(self, path): - self.path = path - return self - - def get_def(self, path): - self.deffed = path - return self - - def render_unicode(self, **values): - if self.exc: - raise self.exc - self.values = values - return text_('result') - -class DummyRendererInfo(object): - def __init__(self, kw): - self.__dict__.update(kw) - - -class DummyWarnings(object): - def __init__(self): - self.msgs = [] - def warn(self, msg, typ, level): - self.msgs.append(msg) diff --git a/pyramid/tests/test_path.py b/pyramid/tests/test_path.py index a07ebeffa..fd927996a 100644 --- a/pyramid/tests/test_path.py +++ b/pyramid/tests/test_path.py @@ -154,6 +154,12 @@ class TestPackageName(unittest.TestCase): package = DummyPackageOrModule(tests) result = self._callFUT(package) self.assertEqual(result, 'pyramid.tests') + + def test_it_namespace_package(self): + from pyramid import tests + package = DummyNamespacePackage(tests) + result = self._callFUT(package) + self.assertEqual(result, 'pyramid.tests') def test_it_module(self): from pyramid.tests import test_path @@ -558,3 +564,13 @@ class DummyPackageOrModule: if self.raise_exc is not None: raise self.raise_exc self.__dict__[key] = val + +class DummyNamespacePackage: + """Has no __file__ attribute. + """ + + def __init__(self, real_package_or_module): + self.__name__ = real_package_or_module.__name__ + import os + self.package_path = os.path.dirname( + os.path.abspath(real_package_or_module.__file__)) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index befb714bd..0b67462bb 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -4,372 +4,6 @@ from pyramid.testing import cleanUp from pyramid import testing from pyramid.compat import text_ -class TestTemplateRendererFactory(unittest.TestCase): - def setUp(self): - self.config = cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, info, impl): - from pyramid.renderers import template_renderer_factory - return template_renderer_factory(info, impl) - - def test_lookup_found(self): - from pyramid.interfaces import IChameleonLookup - L = [] - def dummy(info): - L.append(info) - return True - self.config.registry.registerUtility(dummy, IChameleonLookup, - name='abc') - class DummyInfo(object): - pass - info = DummyInfo() - info.registry = self.config.registry - info.type = 'abc' - result = self._callFUT(info, None) - self.assertEqual(result, True) - self.assertEqual(L, [info]) - - def test_lookup_miss(self): - from pyramid.interfaces import ITemplateRenderer - import os - abspath = os.path.abspath(__file__) - renderer = {} - self.config.registry.registerUtility( - renderer, ITemplateRenderer, name=abspath) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - result = self._callFUT(info, None) - self.assertTrue(result is renderer) - -class TestChameleonRendererLookup(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, impl): - from pyramid.renderers import ChameleonRendererLookup - return ChameleonRendererLookup(impl, self.config.registry) - - def _registerTemplateRenderer(self, renderer, name): - from pyramid.interfaces import ITemplateRenderer - self.config.registry.registerUtility( - renderer, ITemplateRenderer, name=name) - - def test_get_spec_not_abspath_no_colon_no_package(self): - lookup = self._makeOne(None) - result = lookup.get_spec('foo', None) - self.assertEqual(result, 'foo') - - def test_get_spec_not_abspath_no_colon_with_package(self): - from pyramid import tests - lookup = self._makeOne(None) - result = lookup.get_spec('foo', tests) - self.assertEqual(result, 'pyramid.tests:foo') - - def test_get_spec_not_abspath_with_colon_no_package(self): - lookup = self._makeOne(None) - result = lookup.get_spec('fudge:foo', None) - self.assertEqual(result, 'fudge:foo') - - def test_get_spec_not_abspath_with_colon_with_package(self): - from pyramid import tests - lookup = self._makeOne(None) - result = lookup.get_spec('fudge:foo', tests) - self.assertEqual(result, 'fudge:foo') - - def test_get_spec_is_abspath_no_colon_no_package(self): - import os - lookup = self._makeOne(None) - spec = os.path.abspath(__file__) - result = lookup.get_spec(spec, None) - self.assertEqual(result, spec) - - def test_get_spec_is_abspath_no_colon_with_path_in_package(self): - from pyramid import tests - import os - lookup = self._makeOne(None) - f = __file__ - spec = os.path.abspath(f) - result = lookup.get_spec(spec, tests) - self.assertEqual(result, 'pyramid.tests:%s' % os.path.split(f)[-1]) - - def test_get_spec_is_abspath_no_colon_with_path_outside_package(self): - import venusian # used only because it's outside of pyramid.tests - import os - lookup = self._makeOne(None) - f = __file__ - spec = os.path.abspath(f) - result = lookup.get_spec(spec, venusian) - self.assertEqual(result, spec) - - def test_get_spec_is_abspath_with_colon_no_package(self): - import os - lookup = self._makeOne(None) - spec = os.path.join(os.path.abspath(__file__), ':foo') - result = lookup.get_spec(spec, None) - self.assertEqual(result, spec) - - def test_get_spec_is_abspath_with_colon_with_path_in_package(self): - from pyramid import tests - import os - lookup = self._makeOne(None) - f = os.path.abspath(__file__) - spec = os.path.join(f, ':foo') - result = lookup.get_spec(spec, tests) - tail = spec.split(os.sep)[-2:] - self.assertEqual(result, 'pyramid.tests:%s/%s' % tuple(tail)) - - def test_get_spec_is_abspath_with_colon_with_path_outside_package(self): - import venusian # used only because it's outside of pyramid.tests - import os - lookup = self._makeOne(None) - spec = os.path.join(os.path.abspath(__file__), ':foo') - result = lookup.get_spec(spec, venusian) - self.assertEqual(result, spec) - - def test_translate(self): - from pyramid.interfaces import IChameleonTranslate - def t(): pass - self.config.registry.registerUtility(t, IChameleonTranslate) - lookup = self._makeOne(None) - self.assertEqual(lookup.translate, t) - - def test_debug_settings_None(self): - self.config.registry.settings = None - lookup = self._makeOne(None) - self.assertEqual(lookup.debug, False) - - def test_debug_settings_not_None(self): - self.config.registry.settings = {'debug_templates':True} - lookup = self._makeOne(None) - self.assertEqual(lookup.debug, True) - - def test_auto_reload_settings_None(self): - self.config.registry.settings = None - lookup = self._makeOne(None) - self.assertEqual(lookup.auto_reload, False) - - def test_auto_reload_settings_not_None(self): - self.config.registry.settings = {'reload_templates':True} - lookup = self._makeOne(None) - self.assertEqual(lookup.auto_reload, True) - - def test___call__abspath_path_notexists(self): - abspath = '/wont/exist' - self._registerTemplateRenderer({}, abspath) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - self.assertRaises(ValueError, lookup.__call__, info) - - def test___call__abspath_alreadyregistered(self): - import os - abspath = os.path.abspath(__file__) - renderer = {} - self._registerTemplateRenderer(renderer, abspath) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(result is renderer) - - def test___call__abspath_notyetregistered(self): - import os - abspath = os.path.abspath(__file__) - renderer = {} - factory = DummyFactory(renderer) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertEqual(result, renderer) - - def test___call__relpath_path_registered(self): - renderer = {} - spec = 'foo/bar' - self._registerTemplateRenderer(renderer, spec) - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(renderer is result) - - def test___call__relpath_has_package_registered(self): - renderer = {} - import pyramid.tests - spec = 'bar/baz' - self._registerTemplateRenderer(renderer, 'pyramid.tests:bar/baz') - info = DummyRendererInfo({ - 'name':spec, - 'package':pyramid.tests, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(renderer is result) - - def test___call__spec_notfound(self): - spec = 'pyramid.tests:wont/exist' - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - self.assertRaises(ValueError, lookup.__call__, info) - - def test___call__spec_alreadyregistered(self): - from pyramid import tests - module_name = tests.__name__ - relpath = 'test_renderers.py' - spec = '%s:%s' % (module_name, relpath) - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - renderer = {} - self._registerTemplateRenderer(renderer, spec) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(result is renderer) - - def test___call__spec_notyetregistered(self): - import os - from pyramid import tests - module_name = tests.__name__ - relpath = 'test_renderers.py' - renderer = {} - factory = DummyFactory(renderer) - spec = '%s:%s' % (module_name, relpath) - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - path = os.path.abspath(__file__).split('$')[0] # jython - if path.endswith('.pyc'): # pragma: no cover - path = path[:-1] - self.assertTrue(factory.path.startswith(path)) - self.assertEqual(factory.kw, {'macro':None}) - - def test___call__spec_withmacro(self): - from pyramid.interfaces import ITemplateRenderer - import os - from pyramid import tests - module_name = tests.__name__ - relpath = 'fixtures/withmacro#foo.pt' - renderer = {} - factory = DummyFactory(renderer) - spec = '%s:%s' % (module_name, relpath) - reg = self.config.registry - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':reg, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - 'fixtures', - 'withmacro.pt') - self.assertTrue(factory.path.startswith(path)) - self.assertEqual(factory.kw, {'macro':'foo'}) - self.assertTrue( - reg.getUtility(ITemplateRenderer, name=spec) is renderer - ) - - def test___call__reload_assets_true(self): - import pyramid.tests - from pyramid.interfaces import ISettings - from pyramid.interfaces import ITemplateRenderer - settings = {'reload_assets':True} - self.config.registry.registerUtility(settings, ISettings) - renderer = {} - factory = DummyFactory(renderer) - spec = 'test_renderers.py' - reg = self.config.registry - info = DummyRendererInfo({ - 'name':spec, - 'package':pyramid.tests, - 'registry':reg, - 'settings':settings, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - spec = '%s:%s' % ('pyramid.tests', 'test_renderers.py') - self.assertEqual(reg.queryUtility(ITemplateRenderer, name=spec), - None) - - def test___call__reload_assets_false(self): - import pyramid.tests - from pyramid.interfaces import ITemplateRenderer - settings = {'reload_assets':False} - renderer = {} - factory = DummyFactory(renderer) - spec = 'test_renderers.py' - reg = self.config.registry - info = DummyRendererInfo({ - 'name':spec, - 'package':pyramid.tests, - 'registry':reg, - 'settings':settings, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - spec = '%s:%s' % ('pyramid.tests', 'test_renderers.py') - self.assertNotEqual(reg.queryUtility(ITemplateRenderer, name=spec), - None) - class TestJSON(unittest.TestCase): def setUp(self): self.config = testing.setUp() @@ -470,7 +104,7 @@ class Test_string_renderer_factory(unittest.TestCase): value = text_('La Pe\xc3\xb1a', 'utf-8') result = renderer(value, {}) self.assertEqual(result, value) - + def test_it_str(self): renderer = self._callFUT(None) value = 'La Pe\xc3\xb1a' @@ -680,63 +314,6 @@ class TestRendererHelper(unittest.TestCase): helper = self._makeOne('loo.foo') response = helper._make_response(None, request) self.assertEqual(response.body, b'abc') - - def test__make_response_with_content_type(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_content_type':'text/nonsense'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.content_type, 'text/nonsense') - self.assertEqual(response.body, b'abc') - - def test__make_response_with_headerlist(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_headerlist':[('a', '1'), ('b', '2')]} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.headerlist, - [('Content-Type', 'text/html; charset=UTF-8'), - ('Content-Length', '3'), - ('a', '1'), - ('b', '2')]) - self.assertEqual(response.body, b'abc') - - def test__make_response_with_status(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_status':'406 You Lose'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.status, '406 You Lose') - self.assertEqual(response.body, b'abc') - - def test__make_response_with_charset(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_charset':'UTF-16'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.charset, 'UTF-16') - - def test__make_response_with_cache_for(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_cache_for':100} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.cache_control.max_age, 100) def test_with_alternate_response_factory(self): from pyramid.interfaces import IResponseFactory @@ -865,19 +442,21 @@ class Test_render(unittest.TestCase): from pyramid.renderers import render return render(renderer_name, value, request=request, package=package) - def test_it_no_request(self): + def _registerRenderer(self): renderer = self.config.testing_add_renderer( 'pyramid.tests:abc/def.pt') renderer.string_response = 'abc' + return renderer + + def test_it_no_request(self): + renderer = self._registerRenderer() result = self._callFUT('abc/def.pt', dict(a=1)) self.assertEqual(result, 'abc') renderer.assert_(a=1) renderer.assert_(request=None) - + def test_it_with_request(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' + renderer = self._registerRenderer() request = testing.DummyRequest() result = self._callFUT('abc/def.pt', dict(a=1), request=request) @@ -887,9 +466,7 @@ class Test_render(unittest.TestCase): def test_it_with_package(self): import pyramid.tests - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' + renderer = self._registerRenderer() request = testing.DummyRequest() result = self._callFUT('abc/def.pt', dict(a=1), request=request, package=pyramid.tests) @@ -897,6 +474,30 @@ class Test_render(unittest.TestCase): renderer.assert_(a=1) renderer.assert_(request=request) + def test_response_preserved(self): + request = testing.DummyRequest() + response = object() # should error if mutated + request.response = response + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertEqual(request.response, response) + + def test_no_response_to_preserve(self): + from pyramid.decorator import reify + class DummyRequestWithClassResponse(object): + _response = DummyResponse() + _response.content_type = None + _response.default_content_type = None + @reify + def response(self): + return self._response + request = DummyRequestWithClassResponse() + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertFalse('response' in request.__dict__) + class Test_render_to_response(unittest.TestCase): def setUp(self): self.config = testing.setUp() @@ -917,7 +518,7 @@ class Test_render_to_response(unittest.TestCase): self.assertEqual(response.body, b'abc') renderer.assert_(a=1) renderer.assert_(request=None) - + def test_it_with_request(self): renderer = self.config.testing_add_renderer( 'pyramid.tests:abc/def.pt') @@ -999,17 +600,3 @@ class DummyResponse: app_iter = () body = '' -class DummyFactory: - def __init__(self, renderer): - self.renderer = renderer - - def __call__(self, path, lookup, **kw): - self.path = path - self.kw = kw - return self.renderer - - -class DummyRendererInfo(object): - def __init__(self, kw): - self.__dict__.update(kw) - @@ -39,8 +39,6 @@ except IOError: install_requires=[ 'setuptools', - 'Chameleon >= 1.2.3', - 'Mako >= 0.3.6', # strict_undefined 'WebOb >= 1.2b3', # request.path_info is unicode 'repoze.lru >= 0.4', # py3 compat 'zope.interface >= 3.8.0', # has zope.interface.registry @@ -111,7 +109,6 @@ setup(name='pyramid', zodb=pyramid.scaffolds:ZODBProjectTemplate alchemy=pyramid.scaffolds:AlchemyProjectTemplate [console_scripts] - bfg2pyramid = pyramid.fixers.fix_bfg_imports:main pcreate = pyramid.scripts.pcreate:main pserve = pyramid.scripts.pserve:main pshell = pyramid.scripts.pshell:main |
