Skip to content

Commit

Permalink
document changes and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mmerickel committed Jun 18, 2017
1 parent 75c30df commit effe0e6
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 26 deletions.
32 changes: 32 additions & 0 deletions pyramid/tests/test_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ def test_resource_url_with_query_empty(self):
self.assertEqual(result,
'http://example.com:5432/context/a')

def test_resource_url_with_query_None(self):
request = self._makeOne()
self._registerResourceURL(request.registry)
context = DummyContext()
result = request.resource_url(context, 'a', query=None)
self.assertEqual(result,
'http://example.com:5432/context/a')

def test_resource_url_anchor_is_after_root_when_no_elements(self):
request = self._makeOne()
self._registerResourceURL(request.registry)
Expand Down Expand Up @@ -157,6 +165,13 @@ def test_resource_url_anchor_is_urlencoded_safe(self):
self.assertEqual(result,
'http://example.com:5432/context/#%20/%23?&+')

def test_resource_url_anchor_is_None(self):
request = self._makeOne()
self._registerResourceURL(request.registry)
context = DummyContext()
result = request.resource_url(context, anchor=None)
self.assertEqual(result, 'http://example.com:5432/context/')

def test_resource_url_no_IResourceURL_registered(self):
# falls back to ResourceURL
root = DummyContext()
Expand Down Expand Up @@ -421,6 +436,14 @@ def test_route_url_no_elements(self):
self.assertEqual(result,
'http://example.com:5432/1/2/3?a=1#foo')

def test_route_url_with_query_None(self):
from pyramid.interfaces import IRoutesMapper
request = self._makeOne()
mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3'))
request.registry.registerUtility(mapper, IRoutesMapper)
result = request.route_url('flub', a=1, b=2, c=3, _query=None)
self.assertEqual(result, 'http://example.com:5432/1/2/3')

def test_route_url_with_anchor_binary(self):
from pyramid.interfaces import IRoutesMapper
request = self._makeOne()
Expand All @@ -442,6 +465,15 @@ def test_route_url_with_anchor_unicode(self):
self.assertEqual(result,
'http://example.com:5432/1/2/3#La%20Pe%C3%B1a')

def test_route_url_with_anchor_None(self):
from pyramid.interfaces import IRoutesMapper
request = self._makeOne()
mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3'))
request.registry.registerUtility(mapper, IRoutesMapper)
result = request.route_url('flub', _anchor=None)

self.assertEqual(result, 'http://example.com:5432/1/2/3')

def test_route_url_with_query(self):
from pyramid.interfaces import IRoutesMapper
request = self._makeOne()
Expand Down
63 changes: 37 additions & 26 deletions pyramid/url.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
ANCHOR_SAFE = QUERY_SAFE

def parse_url_overrides(request, kw):
"""Parse special arguments passed when generating urls.
"""
Parse special arguments passed when generating urls.
The supplied dictionary is mutated when we pop arguments.
Returns a 3-tuple of the format:
``(app_url, qs, anchor)``.
"""
app_url = kw.pop('_app_url', None)
scheme = kw.pop('_scheme', None)
Expand All @@ -59,10 +61,11 @@ def parse_url_overrides(request, kw):
else:
qs = '?' + urlencode(query, doseq=True)

frag = ''
if anchor:
anchor = '#' + url_quote(anchor, ANCHOR_SAFE)
frag = '#' + url_quote(anchor, ANCHOR_SAFE)

return app_url, qs, anchor
return app_url, qs, frag

class URLMethodsMixin(object):
""" Request methods mixin for BaseRequest having to do with URL
Expand All @@ -78,6 +81,7 @@ def _partial_application_url(self, scheme=None, host=None, port=None):
passed, the ``port`` value is assumed to ``443``. Likewise, if
``scheme`` is passed as ``http`` and ``port`` is not passed, the
``port`` value is assumed to be ``80``.
"""
e = self.environ
if scheme is None:
Expand Down Expand Up @@ -184,10 +188,6 @@ def route_url(self, route_name, *elements, **kw):
as values, and a k=v pair will be placed into the query string for
each value.
.. versionchanged:: 1.5
Allow the ``_query`` option to be a string to enable alternative
encodings.
If a keyword argument ``_anchor`` is present, its string
representation will be quoted per :rfc:`3986#section-3.5` and used as
a named anchor in the generated URL
Expand All @@ -201,10 +201,6 @@ def route_url(self, route_name, *elements, **kw):
``_anchor`` is passed as a Unicode object, it will be converted to
UTF-8 before being appended to the URL.
.. versionchanged:: 1.5
The ``_anchor`` option will be escaped instead of using
its raw string representation.
If both ``_anchor`` and ``_query`` are specified, the anchor
element will always follow the query element,
e.g. ``http://example.com?foo=1#bar``.
Expand Down Expand Up @@ -245,6 +241,18 @@ def route_url(self, route_name, *elements, **kw):
If the route object which matches the ``route_name`` argument has
a :term:`pregenerator`, the ``*elements`` and ``**kw``
arguments passed to this function might be augmented or changed.
.. versionchanged:: 1.5
Allow the ``_query`` option to be a string to enable alternative
encodings.
The ``_anchor`` option will be escaped instead of using
its raw string representation.
.. versionchanged:: 1.9
If ``_query`` or ``_anchor`` are falsey (such as ``None`` or an
empty string) they will not be included in the generated url.
"""
try:
reg = self.registry
Expand Down Expand Up @@ -298,13 +306,13 @@ def route_path(self, route_name, *elements, **kw):
implemented in terms of :meth:`pyramid.request.Request.route_url`
in just this way. As a result, any ``_app_url`` passed within the
``**kw`` values to ``route_path`` will be ignored.
"""
kw['_app_url'] = self.script_name
return self.route_url(route_name, *elements, **kw)

def resource_url(self, resource, *elements, **kw):
"""
Generate a string representing the absolute URL of the
:term:`resource` object based on the ``wsgi.url_scheme``,
``HTTP_HOST`` or ``SERVER_NAME`` in the request, plus any
Expand Down Expand Up @@ -370,10 +378,6 @@ def resource_url(self, resource, *elements, **kw):
as values, and a k=v pair will be placed into the query string for
each value.
.. versionchanged:: 1.5
Allow the ``query`` option to be a string to enable alternative
encodings.
If a keyword argument ``anchor`` is present, its string
representation will be used as a named anchor in the generated URL
(e.g. if ``anchor`` is passed as ``foo`` and the resource URL is
Expand All @@ -386,10 +390,6 @@ def resource_url(self, resource, *elements, **kw):
``anchor`` is passed as a Unicode object, it will be converted to
UTF-8 before being appended to the URL.
.. versionchanged:: 1.5
The ``anchor`` option will be escaped instead of using
its raw string representation.
If both ``anchor`` and ``query`` are specified, the anchor element
will always follow the query element,
e.g. ``http://example.com?foo=1#bar``.
Expand Down Expand Up @@ -418,9 +418,6 @@ def resource_url(self, resource, *elements, **kw):
pass ``app_url=''``. Passing ``app_url=''`` when the resource path is
``/baz/bar`` will return ``/baz/bar``.
.. versionadded:: 1.3
``app_url``
If ``app_url`` is passed and any of ``scheme``, ``port``, or ``host``
are also passed, ``app_url`` will take precedence and the values
passed for ``scheme``, ``host``, and/or ``port`` will be ignored.
Expand All @@ -432,9 +429,6 @@ def resource_url(self, resource, *elements, **kw):
.. seealso::
See also :ref:`overriding_resource_url_generation`.
.. versionadded:: 1.5
``route_name``, ``route_kw``, and ``route_remainder_name``
If ``route_name`` is passed, this function will delegate its URL
production to the ``route_url`` function. Calling
Expand Down Expand Up @@ -508,6 +502,23 @@ def resource_url(self, resource, *elements, **kw):
For backwards compatibility purposes, this method is also
aliased as the ``model_url`` method of request.
.. versionchanged:: 1.3
Added the ``app_url`` keyword argument.
.. versionchanged:: 1.5
Allow the ``query`` option to be a string to enable alternative
encodings.
The ``anchor`` option will be escaped instead of using
its raw string representation.
Added the ``route_name``, ``route_kw``, and
``route_remainder_name`` keyword arguments.
.. versionchanged:: 1.9
If ``query`` or ``anchor`` are falsey (such as ``None`` or an
empty string) they will not be included in the generated url.
"""
try:
reg = self.registry
Expand Down

0 comments on commit effe0e6

Please sign in to comment.