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