summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/narr/vhosting.rst14
-rw-r--r--pyramid/interfaces.py52
-rw-r--r--pyramid/tests/test_traversal.py226
-rw-r--r--pyramid/tests/test_url.py22
-rw-r--r--pyramid/traversal.py111
-rw-r--r--pyramid/url.py148
6 files changed, 132 insertions, 441 deletions
diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst
index 0edf03353..e4cee9882 100644
--- a/docs/narr/vhosting.rst
+++ b/docs/narr/vhosting.rst
@@ -26,20 +26,20 @@ Hosting an Application Under a URL Prefix
``http://example.com/``).
If you use a "pure Python" environment, this functionality can be provided by
-Paste's `urlmap <http://pythonpaste.org/modules/urlmap.html>`_ "composite" WSGI
-application. Alternatively, you can use :term:`mod_wsgi` to serve your
+`rutter <http://rutter.readthedocs.io/en/latest/>`_, forming a "composite"
+WSGI application. Alternatively, you can use :term:`mod_wsgi` to serve your
application, which handles this virtual hosting translation for you "under the
hood".
-If you use the ``urlmap`` composite application "in front" of a :app:`Pyramid`
+If you use the ``rutter`` composite application "in front" of a :app:`Pyramid`
application or if you use :term:`mod_wsgi` to serve up a :app:`Pyramid`
application, nothing special needs to be done within the application for URLs
-to be generated that contain a prefix. :mod:`paste.urlmap` and :term:`mod_wsgi`
+to be generated that contain a prefix. Rutter and :term:`mod_wsgi`
manipulate the :term:`WSGI` environment in such a way that the ``PATH_INFO``
and ``SCRIPT_NAME`` variables are correct for some given prefix.
Here's an example of a PasteDeploy configuration snippet that includes a
-``urlmap`` composite.
+``rutter`` composite.
.. code-block:: ini
:linenos:
@@ -48,13 +48,13 @@ Here's an example of a PasteDeploy configuration snippet that includes a
use = egg:mypyramidapp
[composite:main]
- use = egg:Paste#urlmap
+ use = egg:rutter#urlmap
/pyramidapp = mypyramidapp
This "roots" the :app:`Pyramid` application at the prefix ``/pyramidapp`` and
serves up the composite as the "main" application in the file.
-.. note:: If you're using an Apache server to proxy to a Paste ``urlmap``
+.. note:: If you're using an Apache server to proxy to a ``urlmap``
composite, you may have to use the `ProxyPreserveHost
<http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypreservehost>`_
directive to pass the original ``HTTP_HOST`` header along to the
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index c1ddea63f..450cd9c24 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -799,58 +799,6 @@ class IResourceURL(Interface):
'The physical url path of the resource as a tuple. (New in 1.5)'
)
-class IContextURL(IResourceURL):
- """
- .. deprecated:: 1.3
- An adapter which deals with URLs related to a context. Use
- :class:`pyramid.interfaces.IResourceURL` instead.
- """
- # this class subclasses IResourceURL because request.resource_url looks
- # for IResourceURL via queryAdapter. queryAdapter will find a deprecated
- # IContextURL registration if no registration for IResourceURL exists.
- # In reality, however, IContextURL objects were never required to have
- # the virtual_path or physical_path attributes spelled in IResourceURL.
- # The inheritance relationship is purely to benefit adapter lookup,
- # not to imply an inheritance relationship of interface attributes
- # and methods.
- #
- # Mechanics:
- #
- # class Fudge(object):
- # def __init__(self, one, two):
- # print(one, two)
- # class Another(object):
- # def __init__(self, one, two):
- # print(one, two)
- # ob = object()
- # r.registerAdapter(Fudge, (Interface, Interface), IContextURL)
- # print(r.queryMultiAdapter((ob, ob), IResourceURL))
- # r.registerAdapter(Another, (Interface, Interface), IResourceURL)
- # print(r.queryMultiAdapter((ob, ob), IResourceURL))
- #
- # prints
- #
- # <object object at 0x7fa678f3e2a0> <object object at 0x7fa678f3e2a0>
- # <__main__.Fudge object at 0x1cda890>
- # <object object at 0x7fa678f3e2a0> <object object at 0x7fa678f3e2a0>
- # <__main__.Another object at 0x1cda850>
-
- def virtual_root():
- """ Return the virtual root related to a request and the
- current context"""
-
- def __call__():
- """ Return a URL that points to the context. """
-
-deprecated(
- 'IContextURL',
- 'As of Pyramid 1.3 the, "pyramid.interfaces.IContextURL" interface is '
- 'scheduled to be removed. Use the '
- '"pyramid.config.Configurator.add_resource_url_adapter" method to register '
- 'a class that implements "pyramid.interfaces.IResourceURL" instead. '
- 'See the "What\'s new In Pyramid 1.3" document for more details.'
- )
-
class IPEP302Loader(Interface):
""" See http://www.python.org/dev/peps/pep-0302/#id30.
"""
diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py
index 5fc878a32..437fe46df 100644
--- a/pyramid/tests/test_traversal.py
+++ b/pyramid/tests/test_traversal.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import unittest
-import warnings
from pyramid.testing import cleanUp
@@ -12,11 +11,6 @@ from pyramid.compat import (
PY2,
)
-with warnings.catch_warnings(record=True) as w:
- warnings.filterwarnings('always')
- from pyramid.interfaces import IContextURL
- assert(len(w) == 1)
-
class TraversalPathTests(unittest.TestCase):
def _callFUT(self, path):
from pyramid.traversal import traversal_path
@@ -871,182 +865,12 @@ class ResourceURLTests(unittest.TestCase):
from pyramid.traversal import ResourceURL
return ResourceURL
- def _registerTraverser(self, traverser):
- from pyramid.threadlocal import get_current_registry
- reg = get_current_registry()
- from pyramid.interfaces import ITraverser
- from zope.interface import Interface
- reg.registerAdapter(traverser, (Interface,), ITraverser)
-
- def test_class_conforms_to_IContextURL(self):
- # bw compat
- from zope.interface.verify import verifyClass
- verifyClass(IContextURL, self._getTargetClass())
-
- def test_instance_conforms_to_IContextURL(self):
- from zope.interface.verify import verifyObject
- context = DummyContext()
- request = DummyRequest()
- verifyObject(IContextURL, self._makeOne(context, request))
-
def test_instance_conforms_to_IResourceURL(self):
from pyramid.interfaces import IResourceURL
from zope.interface.verify import verifyObject
context = DummyContext()
request = DummyRequest()
verifyObject(IResourceURL, self._makeOne(context, request))
-
- def test_call_withlineage(self):
- baz = DummyContext()
- bar = DummyContext(baz)
- foo = DummyContext(bar)
- root = DummyContext(foo)
- root.__parent__ = None
- root.__name__ = None
- foo.__parent__ = root
- foo.__name__ = 'foo '
- bar.__parent__ = foo
- bar.__name__ = 'bar'
- baz.__parent__ = bar
- baz.__name__ = 'baz'
- request = DummyRequest()
- context_url = self._makeOne(baz, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432/foo%20/bar/baz/')
-
- def test_call_nolineage(self):
- context = DummyContext()
- context.__name__ = ''
- context.__parent__ = None
- request = DummyRequest()
- context_url = self._makeOne(context, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432/')
-
- def test_call_unicode_mixed_with_bytes_in_resource_names(self):
- root = DummyContext()
- root.__parent__ = None
- root.__name__ = None
- one = DummyContext()
- one.__parent__ = root
- one.__name__ = text_(b'La Pe\xc3\xb1a', 'utf-8')
- two = DummyContext()
- two.__parent__ = one
- two.__name__ = b'La Pe\xc3\xb1a'
- request = DummyRequest()
- context_url = self._makeOne(two, request)
- result = context_url()
- self.assertEqual(
- result,
- 'http://example.com:5432/La%20Pe%C3%B1a/La%20Pe%C3%B1a/')
-
- def test_call_with_virtual_root_path(self):
- from pyramid.interfaces import VH_ROOT_KEY
- root = DummyContext()
- root.__parent__ = None
- root.__name__ = None
- one = DummyContext()
- one.__parent__ = root
- one.__name__ = 'one'
- two = DummyContext()
- two.__parent__ = one
- two.__name__ = 'two'
- request = DummyRequest({VH_ROOT_KEY:'/one'})
- context_url = self._makeOne(two, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432/two/')
-
- request = DummyRequest({VH_ROOT_KEY:'/one/two'})
- context_url = self._makeOne(two, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432/')
-
- def test_call_with_virtual_root_path_physical_not_startwith_vroot(self):
- from pyramid.interfaces import VH_ROOT_KEY
- root = DummyContext()
- root.__parent__ = None
- root.__name__ = None
- one = DummyContext()
- one.__parent__ = root
- one.__name__ = 'one'
- two = DummyContext()
- two.__parent__ = one
- two.__name__ = 'two'
- request = DummyRequest({VH_ROOT_KEY:'/wrong'})
- context_url = self._makeOne(two, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432/one/two/')
-
- def test_call_empty_names_not_ignored(self):
- bar = DummyContext()
- empty = DummyContext(bar)
- root = DummyContext(empty)
- root.__parent__ = None
- root.__name__ = None
- empty.__parent__ = root
- empty.__name__ = ''
- bar.__parent__ = empty
- bar.__name__ = 'bar'
- request = DummyRequest()
- context_url = self._makeOne(bar, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432//bar/')
-
- def test_call_local_url_returns_None(self):
- resource = DummyContext()
- def resource_url(request, info):
- self.assertEqual(info['virtual_path'], '/')
- self.assertEqual(info['physical_path'], '/')
- return None
- resource.__resource_url__ = resource_url
- request = DummyRequest()
- context_url = self._makeOne(resource, request)
- result = context_url()
- self.assertEqual(result, 'http://example.com:5432/')
-
- def test_call_local_url_returns_url(self):
- resource = DummyContext()
- def resource_url(request, info):
- self.assertEqual(info['virtual_path'], '/')
- self.assertEqual(info['physical_path'], '/')
- return 'abc'
- resource.__resource_url__ = resource_url
- request = DummyRequest()
- context_url = self._makeOne(resource, request)
- result = context_url()
- self.assertEqual(result, 'abc')
-
- def test_virtual_root_no_virtual_root_path(self):
- root = DummyContext()
- root.__name__ = None
- root.__parent__ = None
- one = DummyContext()
- one.__name__ = 'one'
- one.__parent__ = root
- request = DummyRequest()
- context_url = self._makeOne(one, request)
- self.assertEqual(context_url.virtual_root(), root)
-
- def test_virtual_root_no_virtual_root_path_with_root_on_request(self):
- context = DummyContext()
- context.__parent__ = None
- request = DummyRequest()
- request.root = DummyContext()
- context_url = self._makeOne(context, request)
- self.assertEqual(context_url.virtual_root(), request.root)
-
- def test_virtual_root_with_virtual_root_path(self):
- from pyramid.interfaces import VH_ROOT_KEY
- context = DummyContext()
- context.__parent__ = None
- traversed_to = DummyContext()
- environ = {VH_ROOT_KEY:'/one'}
- request = DummyRequest(environ)
- traverser = make_traverser({'context':traversed_to, 'view_name':''})
- self._registerTraverser(traverser)
- context_url = self._makeOne(context, request)
- self.assertEqual(context_url.virtual_root(), traversed_to)
- self.assertEqual(context.request.environ['PATH_INFO'], '/one')
def test_IResourceURL_attributes_with_vroot(self):
from pyramid.interfaces import VH_ROOT_KEY
@@ -1115,14 +939,47 @@ class TestVirtualRoot(unittest.TestCase):
from pyramid.traversal import virtual_root
return virtual_root(resource, request)
- def test_registered(self):
+ def _registerTraverser(self, traverser):
+ from pyramid.threadlocal import get_current_registry
+ reg = get_current_registry()
+ from pyramid.interfaces import ITraverser
from zope.interface import Interface
- request = _makeRequest()
- request.registry.registerAdapter(DummyContextURL, (Interface,Interface),
- IContextURL)
+ reg.registerAdapter(traverser, (Interface,), ITraverser)
+
+ def test_virtual_root_no_virtual_root_path(self):
+ root = DummyContext()
+ root.__name__ = None
+ root.__parent__ = None
+ one = DummyContext()
+ one.__name__ = 'one'
+ one.__parent__ = root
+ request = DummyRequest()
+ result = self._callFUT(one, request)
+ self.assertEqual(result, root)
+
+ def test_virtual_root_no_virtual_root_path_with_root_on_request(self):
context = DummyContext()
+ context.__parent__ = None
+ request = DummyRequest()
+ request.root = DummyContext()
result = self._callFUT(context, request)
- self.assertEqual(result, '123')
+ self.assertEqual(result, request.root)
+
+ def test_virtual_root_with_virtual_root_path(self):
+ from pyramid.interfaces import VH_ROOT_KEY
+ root = DummyContext()
+ root.__parent__ = None
+ context = DummyContext()
+ context.__name__ = 'one'
+ context.__parent__ = root
+ traversed_to = DummyContext()
+ environ = {VH_ROOT_KEY:'/one'}
+ request = DummyRequest(environ)
+ traverser = make_traverser({'context':traversed_to, 'view_name':''})
+ self._registerTraverser(traverser)
+ result = self._callFUT(context, request)
+ self.assertEqual(result, traversed_to)
+ self.assertEqual(root.request.environ['PATH_INFO'], '/one')
def test_default(self):
context = DummyContext()
@@ -1357,13 +1214,6 @@ class DummyRequest:
path_info = property(_get_path_info, _set_path_info)
-class DummyContextURL:
- def __init__(self, context, request):
- pass
-
- def virtual_root(self):
- return '123'
-
def _makeRequest(environ=None):
from pyramid.registry import Registry
request = DummyRequest()
diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py
index 0a788ba97..ddf28e0b0 100644
--- a/pyramid/tests/test_url.py
+++ b/pyramid/tests/test_url.py
@@ -29,18 +29,6 @@ class TestURLMethodsMixin(unittest.TestCase):
request.registry = self.config.registry
return request
- def _registerContextURL(self, reg):
- with warnings.catch_warnings(record=True):
- from pyramid.interfaces import IContextURL
- from zope.interface import Interface
- class DummyContextURL(object):
- def __init__(self, context, request):
- pass
- def __call__(self):
- return 'http://example.com/context/'
- reg.registerAdapter(DummyContextURL, (Interface, Interface),
- IContextURL)
-
def _registerResourceURL(self, reg):
from pyramid.interfaces import IResourceURL
from zope.interface import Interface
@@ -186,16 +174,6 @@ class TestURLMethodsMixin(unittest.TestCase):
root = DummyContext()
result = request.resource_url(root)
self.assertEqual(result, 'http://example.com:5432/context/')
-
- def test_resource_url_finds_IContextURL(self):
- request = self._makeOne()
- self._registerContextURL(request.registry)
- root = DummyContext()
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter('always')
- result = request.resource_url(root)
- self.assertEqual(len(w), 1)
- self.assertEqual(result, 'http://example.com/context/')
def test_resource_url_with_app_url(self):
request = self._makeOne()
diff --git a/pyramid/traversal.py b/pyramid/traversal.py
index 1ca52692a..641445067 100644
--- a/pyramid/traversal.py
+++ b/pyramid/traversal.py
@@ -1,7 +1,3 @@
-import warnings
-
-from zope.deprecation import deprecated
-
from zope.interface import implementer
from zope.interface.interfaces import IInterface
@@ -31,10 +27,6 @@ from pyramid.exceptions import URLDecodeError
from pyramid.location import lineage
from pyramid.threadlocal import get_current_registry
-with warnings.catch_warnings():
- warnings.filterwarnings('ignore')
- from pyramid.interfaces import IContextURL
-
PATH_SEGMENT_SAFE = "~!$&'()*+,;=:@" # from webob
PATH_SAFE = PATH_SEGMENT_SAFE + "/"
@@ -100,10 +92,6 @@ def find_resource(resource, path):
object representing a resource name). Resource path tuples generated by
:func:`pyramid.traversal.resource_path_tuple` can always be
resolved by ``find_resource``.
-
- .. note:: For backwards compatibility purposes, this function can also
- be imported as :func:`pyramid.traversal.find_model`, although doing so
- will emit a deprecation warning.
"""
if isinstance(path, text_type):
path = ascii_native_(path)
@@ -174,12 +162,6 @@ def resource_path(resource, *elements):
properly. If the root resource has a non-null ``__name__`` attribute,
its name will be prepended to the generated path rather than a single
leading '/' character.
-
- .. note::
-
- For backwards compatibility purposes, this function can also
- be imported as ``model_path``, although doing so will cause
- a deprecation warning to be emitted.
"""
# joining strings is a bit expensive so we delegate to a function
# which caches the joined result for us
@@ -381,12 +363,6 @@ def resource_path_tuple(resource, *elements):
generated properly. If the root resource has a non-null ``__name__``
attribute, its name will be the first element in the generated path tuple
rather than the empty string.
-
- .. note::
-
- For backwards compatibility purposes, this function can also be imported
- as ``model_path_tuple``, although doing so will cause a deprecation
- warning to be emitted.
"""
return tuple(_resource_path_list(resource, *elements))
@@ -407,8 +383,8 @@ def virtual_root(resource, request):
the resource object representing the :term:`virtual root` of the
current :term:`request`. Using a virtual root in a
:term:`traversal` -based :app:`Pyramid` application permits
- rooting, for example, the resource at the traversal path ``/cms`` at
- ``http://example.com/`` instead of rooting it at
+ rooting. For example, the resource at the traversal path ``/cms`` will
+ be found at ``http://example.com/`` instead of rooting it at
``http://example.com/cms/``.
If the ``resource`` passed in is a context obtained via
@@ -430,11 +406,20 @@ def virtual_root(resource, request):
try:
reg = request.registry
except AttributeError:
- reg = get_current_registry() # b/c
- urlgenerator = reg.queryMultiAdapter((resource, request), IContextURL)
- if urlgenerator is None:
- urlgenerator = TraversalContextURL(resource, request)
- return urlgenerator.virtual_root()
+ reg = get_current_registry()
+ url_adapter = reg.queryMultiAdapter((resource, request), IResourceURL)
+ if url_adapter is None:
+ url_adapter = ResourceURL(resource, request)
+
+ vpath, rpath = url_adapter.virtual_path, url_adapter.physical_path
+ if rpath != vpath and rpath.endswith(vpath):
+ vroot_path = rpath[:-len(vpath)]
+ return find_resource(resource, vroot_path)
+
+ try:
+ return request.root
+ except AttributeError:
+ return find_root(resource)
def traversal_path(path):
""" Variant of :func:`pyramid.traversal.traversal_path_info` suitable for
@@ -627,6 +612,7 @@ class ResourceTreeTraverser(object):
:term:`location` aware) ."""
+ VH_ROOT_KEY = VH_ROOT_KEY
VIEW_SELECTOR = '@@'
def __init__(self, root):
@@ -665,9 +651,9 @@ class ResourceTreeTraverser(object):
raise URLDecodeError(e.encoding, e.object, e.start, e.end,
e.reason)
- if VH_ROOT_KEY in environ:
+ if self.VH_ROOT_KEY in environ:
# HTTP_X_VHM_ROOT
- vroot_path = decode_path_info(environ[VH_ROOT_KEY])
+ vroot_path = decode_path_info(environ[self.VH_ROOT_KEY])
vroot_tuple = split_path_info(vroot_path)
vpath = vroot_path + path # both will (must) be unicode or asciistr
vroot_idx = len(vroot_tuple) - 1
@@ -731,9 +717,9 @@ class ResourceTreeTraverser(object):
ModelGraphTraverser = ResourceTreeTraverser # b/w compat, not API, used in wild
-@implementer(IResourceURL, IContextURL)
+@implementer(IResourceURL)
class ResourceURL(object):
- vroot_varname = VH_ROOT_KEY
+ VH_ROOT_KEY = VH_ROOT_KEY
def __init__(self, resource, request):
physical_path_tuple = resource_path_tuple(resource)
@@ -747,7 +733,7 @@ class ResourceURL(object):
virtual_path_tuple = physical_path_tuple
environ = request.environ
- vroot_path = environ.get(self.vroot_varname)
+ vroot_path = environ.get(self.VH_ROOT_KEY)
# if the physical path starts with the virtual root path, trim it out
# of the virtual path
@@ -764,59 +750,6 @@ class ResourceURL(object):
self.virtual_path_tuple = virtual_path_tuple # IResourceURL attr (1.5)
self.physical_path_tuple = physical_path_tuple # IResourceURL attr (1.5)
- # bw compat for IContextURL methods
- self.resource = resource
- self.context = resource
- self.request = request
-
- # IContextURL method (deprecated in 1.3)
- def virtual_root(self):
- environ = self.request.environ
- vroot_varname = self.vroot_varname
- if vroot_varname in environ:
- return find_resource(self.context, environ[vroot_varname])
- # shortcut instead of using find_root; we probably already
- # have it on the request
- try:
- return self.request.root
- except AttributeError:
- return find_root(self.context)
-
- # IContextURL method (deprecated in 1.3)
- def __call__(self):
- """ Generate a URL based on the :term:`lineage` of a :term:`resource`
- object that is ``self.context``. If any resource in the context
- lineage has a Unicode name, it will be converted to a UTF-8 string
- before being attached to the URL. If a ``HTTP_X_VHM_ROOT`` key is
- present in the WSGI environment, its value will be treated as a
- 'virtual root path': the path of the URL generated by this will be
- left-stripped of this virtual root path value.
- """
- local_url = getattr(self.context, '__resource_url__', None)
- if local_url is not None:
- result = local_url(
- self.request,
- {'virtual_path':self.virtual_path,
- 'physical_path':self.physical_path},
- )
- if result is not None:
- # allow it to punt by returning ``None``
- return result
-
- app_url = self.request.application_url # never ends in a slash
- return app_url + self.virtual_path
-
-TraversalContextURL = ResourceURL # deprecated as of 1.3
-
-deprecated(
- 'TraversalContextURL',
- 'As of Pyramid 1.3 the, "pyramid.traversal.TraversalContextURL" class is '
- 'scheduled to be removed. Use the '
- '"pyramid.config.Configurator.add_resource_url_adapter" method to register '
- 'a class that implements "pyramid.interfaces.IResourceURL" instead. '
- 'See the "What\'s new In Pyramid 1.3" document for a further description.'
- )
-
@lru_cache(1000)
def _join_path_tuple(tuple):
return tuple and '/'.join([quote_path_segment(x) for x in tuple]) or '/'
diff --git a/pyramid/url.py b/pyramid/url.py
index d6587e783..9634f61da 100644
--- a/pyramid/url.py
+++ b/pyramid/url.py
@@ -1,7 +1,6 @@
""" Utility functions for dealing with URLs in pyramid """
import os
-import warnings
from repoze.lru import lru_cache
@@ -534,89 +533,72 @@ class URLMethodsMixin(object):
virtual_path = getattr(url_adapter, 'virtual_path', None)
- if virtual_path is None:
- # old-style IContextURL adapter (Pyramid 1.2 and previous)
- warnings.warn(
- 'Pyramid is using an IContextURL adapter to generate a '
- 'resource URL; any "app_url", "host", "port", or "scheme" '
- 'arguments passed to resource_url are being ignored. To '
- 'avoid this behavior, as of Pyramid 1.3, register an '
- 'IResourceURL adapter instead of an IContextURL '
- 'adapter for the resource type(s). IContextURL adapters '
- 'will be ignored in a later major release of Pyramid.',
- DeprecationWarning,
- 2)
-
- resource_url = url_adapter()
+ app_url = None
+ scheme = None
+ host = None
+ port = None
+
+ if 'route_name' in kw:
+ newkw = {}
+ route_name = kw['route_name']
+ remainder = getattr(url_adapter, 'virtual_path_tuple', None)
+ if remainder is None:
+ # older user-supplied IResourceURL adapter without 1.5
+ # virtual_path_tuple
+ remainder = tuple(url_adapter.virtual_path.split('/'))
+ remainder_name = kw.get('route_remainder_name', 'traverse')
+ newkw[remainder_name] = remainder
+
+ for name in (
+ 'app_url', 'scheme', 'host', 'port', 'query', 'anchor'
+ ):
+ val = kw.get(name, None)
+ if val is not None:
+ newkw['_' + name] = val
+
+ if 'route_kw' in kw:
+ route_kw = kw.get('route_kw')
+ if route_kw is not None:
+ newkw.update(route_kw)
+
+ return self.route_url(route_name, *elements, **newkw)
+
+ if 'app_url' in kw:
+ app_url = kw['app_url']
+
+ if 'scheme' in kw:
+ scheme = kw['scheme']
+
+ if 'host' in kw:
+ host = kw['host']
+
+ if 'port' in kw:
+ port = kw['port']
- else:
- # IResourceURL adapter (Pyramid 1.3 and after)
- app_url = None
- scheme = None
- host = None
- port = None
-
- if 'route_name' in kw:
- newkw = {}
- route_name = kw['route_name']
- remainder = getattr(url_adapter, 'virtual_path_tuple', None)
- if remainder is None:
- # older user-supplied IResourceURL adapter without 1.5
- # virtual_path_tuple
- remainder = tuple(url_adapter.virtual_path.split('/'))
- remainder_name = kw.get('route_remainder_name', 'traverse')
- newkw[remainder_name] = remainder
-
- for name in (
- 'app_url', 'scheme', 'host', 'port', 'query', 'anchor'
- ):
- val = kw.get(name, None)
- if val is not None:
- newkw['_' + name] = val
-
- if 'route_kw' in kw:
- route_kw = kw.get('route_kw')
- if route_kw is not None:
- newkw.update(route_kw)
-
- return self.route_url(route_name, *elements, **newkw)
-
- if 'app_url' in kw:
- app_url = kw['app_url']
-
- if 'scheme' in kw:
- scheme = kw['scheme']
-
- if 'host' in kw:
- host = kw['host']
-
- if 'port' in kw:
- port = kw['port']
-
- if app_url is None:
- if scheme or host or port:
- app_url = self._partial_application_url(scheme, host, port)
- else:
- app_url = self.application_url
-
- resource_url = None
- local_url = getattr(resource, '__resource_url__', None)
-
- if local_url is not None:
- # the resource handles its own url generation
- d = dict(
- virtual_path=virtual_path,
- physical_path=url_adapter.physical_path,
- app_url=app_url,
- )
-
- # allow __resource_url__ to punt by returning None
- resource_url = local_url(self, d)
-
- if resource_url is None:
- # the resource did not handle its own url generation or the
- # __resource_url__ function returned None
- resource_url = app_url + virtual_path
+ if app_url is None:
+ if scheme or host or port:
+ app_url = self._partial_application_url(scheme, host, port)
+ else:
+ app_url = self.application_url
+
+ resource_url = None
+ local_url = getattr(resource, '__resource_url__', None)
+
+ if local_url is not None:
+ # the resource handles its own url generation
+ d = dict(
+ virtual_path=virtual_path,
+ physical_path=url_adapter.physical_path,
+ app_url=app_url,
+ )
+
+ # allow __resource_url__ to punt by returning None
+ resource_url = local_url(self, d)
+
+ if resource_url is None:
+ # the resource did not handle its own url generation or the
+ # __resource_url__ function returned None
+ resource_url = app_url + virtual_path
qs = ''
anchor = ''