Moved p.url._join_elements to p.util.join_elements and
p.traversal.quote_path_segment to p.util.quote_path_segment.
| | |
| | | result = self._callFUT(other2) |
| | | self.assertEqual(result, ('', '', 'other2')) |
| | | |
| | | class QuotePathSegmentTests(unittest.TestCase): |
| | | def _callFUT(self, s): |
| | | from pyramid.traversal import quote_path_segment |
| | | return quote_path_segment(s) |
| | | |
| | | def test_unicode(self): |
| | | la = unicode('/La Pe\xc3\xb1a', 'utf-8') |
| | | result = self._callFUT(la) |
| | | self.assertEqual(result, '%2FLa%20Pe%C3%B1a') |
| | | |
| | | def test_string(self): |
| | | s = '/ hello!' |
| | | result = self._callFUT(s) |
| | | self.assertEqual(result, '%2F%20hello%21') |
| | | |
| | | def test_int(self): |
| | | s = 12345 |
| | | result = self._callFUT(s) |
| | | self.assertEqual(result, '12345') |
| | | |
| | | def test_long(self): |
| | | import sys |
| | | s = long(sys.maxint + 1) |
| | | result = self._callFUT(s) |
| | | expected = str(s) |
| | | self.assertEqual(result, expected) |
| | | |
| | | def test_other(self): |
| | | class Foo(object): |
| | | def __str__(self): |
| | | return 'abc' |
| | | s = Foo() |
| | | result = self._callFUT(s) |
| | | self.assertEqual(result, 'abc') |
| | | |
| | | class TraversalContextURLTests(unittest.TestCase): |
| | | def _makeOne(self, context, url): |
| | | return self._getTargetClass()(context, url) |
| | |
| | | self.assertEqual(list(wos), []) |
| | | self.assertEqual(wos.last, None) |
| | | |
| | | class QuotePathSegmentTests(unittest.TestCase): |
| | | def _callFUT(self, s): |
| | | from pyramid.traversal import quote_path_segment |
| | | return quote_path_segment(s) |
| | | |
| | | def test_unicode(self): |
| | | la = unicode('/La Pe\xc3\xb1a', 'utf-8') |
| | | result = self._callFUT(la) |
| | | self.assertEqual(result, '%2FLa%20Pe%C3%B1a') |
| | | |
| | | def test_string(self): |
| | | s = '/ hello!' |
| | | result = self._callFUT(s) |
| | | self.assertEqual(result, '%2F%20hello%21') |
| | | |
| | | def test_int(self): |
| | | s = 12345 |
| | | result = self._callFUT(s) |
| | | self.assertEqual(result, '12345') |
| | | |
| | | def test_long(self): |
| | | import sys |
| | | s = long(sys.maxint + 1) |
| | | result = self._callFUT(s) |
| | | expected = str(s) |
| | | self.assertEqual(result, expected) |
| | | |
| | | def test_other(self): |
| | | class Foo(object): |
| | | def __str__(self): |
| | | return 'abc' |
| | | s = Foo() |
| | | result = self._callFUT(s) |
| | | self.assertEqual(result, 'abc') |
| | | |
| | | class Dummy(object): |
| | | pass |
| | |
| | | from pyramid.interfaces import ITraverser |
| | | from pyramid.interfaces import VH_ROOT_KEY |
| | | |
| | | from pyramid.encode import url_quote |
| | | from pyramid.exceptions import URLDecodeError |
| | | from pyramid.location import lineage |
| | | from pyramid.threadlocal import get_current_registry |
| | | from pyramid.util import quote_path_segment # bw-compat |
| | | |
| | | def find_root(resource): |
| | | """ Find the root node in the resource tree to which ``resource`` |
| | |
| | | ) |
| | | clean.append(segment) |
| | | return tuple(clean) |
| | | |
| | | _segment_cache = {} |
| | | |
| | | def quote_path_segment(segment, safe=''): |
| | | """ Return a quoted representation of a 'path segment' (such as |
| | | the string ``__name__`` attribute of a resource) as a string. If the |
| | | ``segment`` passed in is a unicode object, it is converted to a |
| | | UTF-8 string, then it is URL-quoted using Python's |
| | | ``urllib.quote``. If the ``segment`` passed in is a string, it is |
| | | URL-quoted using Python's :mod:`urllib.quote`. If the segment |
| | | passed in is not a string or unicode object, an error will be |
| | | raised. The return value of ``quote_path_segment`` is always a |
| | | string, never Unicode. |
| | | |
| | | You may pass a string of characters that need not be encoded as |
| | | the ``safe`` argument to this function. This corresponds to the |
| | | ``safe`` argument to :mod:`urllib.quote`. |
| | | |
| | | .. note:: The return value for each segment passed to this |
| | | function is cached in a module-scope dictionary for |
| | | speed: the cached version is returned when possible |
| | | rather than recomputing the quoted version. No cache |
| | | emptying is ever done for the lifetime of an |
| | | application, however. If you pass arbitrary |
| | | user-supplied strings to this function (as opposed to |
| | | some bounded set of values from a 'working set' known to |
| | | your application), it may become a memory leak. |
| | | """ |
| | | # The bit of this code that deals with ``_segment_cache`` is an |
| | | # optimization: we cache all the computation of URL path segments |
| | | # in this module-scope dictionary with the original string (or |
| | | # unicode value) as the key, so we can look it up later without |
| | | # needing to reencode or re-url-quote it |
| | | try: |
| | | return _segment_cache[(segment, safe)] |
| | | except KeyError: |
| | | if segment.__class__ is unicode: # isinstance slighly slower (~15%) |
| | | result = url_quote(segment.encode('utf-8'), safe) |
| | | else: |
| | | result = url_quote(str(segment), safe) |
| | | # we don't need a lock to mutate _segment_cache, as the below |
| | | # will generate exactly one Python bytecode (STORE_SUBSCR) |
| | | _segment_cache[(segment, safe)] = result |
| | | return result |
| | | |
| | | class ResourceTreeTraverser(object): |
| | | """ A resource tree traverser that should be used (for speed) when |
| | |
| | | |
| | | from zope.deprecation import deprecated |
| | | |
| | | from repoze.lru import lru_cache |
| | | |
| | | from pyramid.interfaces import IContextURL |
| | | from pyramid.interfaces import IRoutesMapper |
| | | from pyramid.interfaces import IStaticURLInfo |
| | |
| | | from pyramid.path import caller_package |
| | | from pyramid.threadlocal import get_current_registry |
| | | from pyramid.traversal import TraversalContextURL |
| | | from pyramid.traversal import quote_path_segment |
| | | from pyramid.util import join_elements |
| | | |
| | | def route_url(route_name, request, *elements, **kw): |
| | | """Generates a fully qualified URL for a named :app:`Pyramid` |
| | |
| | | path = route.generate(kw) # raises KeyError if generate fails |
| | | |
| | | if elements: |
| | | suffix = _join_elements(elements) |
| | | suffix = join_elements(elements) |
| | | if not path.endswith('/'): |
| | | suffix = '/' + suffix |
| | | else: |
| | |
| | | anchor = '#' + anchor |
| | | |
| | | if elements: |
| | | suffix = _join_elements(elements) |
| | | suffix = join_elements(elements) |
| | | else: |
| | | suffix = '' |
| | | |
| | |
| | | newkw.update(request.matchdict) |
| | | newkw.update(kw) |
| | | return route_url(route_name, request, *elements, **newkw) |
| | | |
| | | @lru_cache(1000) |
| | | def _join_elements(elements): |
| | | return '/'.join([quote_path_segment(s, safe=':@&+$,') for s in elements]) |
| | |
| | | import sys |
| | | import weakref |
| | | |
| | | from repoze.lru import lru_cache |
| | | |
| | | from pyramid.encode import url_quote |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.path import package_of |
| | | |
| | |
| | | if self._order: |
| | | oid = self._order[-1] |
| | | return self._items[oid]() |
| | | |
| | | _segment_cache = {} |
| | | |
| | | def quote_path_segment(segment, safe=''): |
| | | """ Return a quoted representation of a 'path segment' (such as |
| | | the string ``__name__`` attribute of a resource) as a string. If the |
| | | ``segment`` passed in is a unicode object, it is converted to a |
| | | UTF-8 string, then it is URL-quoted using Python's |
| | | ``urllib.quote``. If the ``segment`` passed in is a string, it is |
| | | URL-quoted using Python's :mod:`urllib.quote`. If the segment |
| | | passed in is not a string or unicode object, an error will be |
| | | raised. The return value of ``quote_path_segment`` is always a |
| | | string, never Unicode. |
| | | |
| | | You may pass a string of characters that need not be encoded as |
| | | the ``safe`` argument to this function. This corresponds to the |
| | | ``safe`` argument to :mod:`urllib.quote`. |
| | | |
| | | .. note:: The return value for each segment passed to this |
| | | function is cached in a module-scope dictionary for |
| | | speed: the cached version is returned when possible |
| | | rather than recomputing the quoted version. No cache |
| | | emptying is ever done for the lifetime of an |
| | | application, however. If you pass arbitrary |
| | | user-supplied strings to this function (as opposed to |
| | | some bounded set of values from a 'working set' known to |
| | | your application), it may become a memory leak. |
| | | """ |
| | | # The bit of this code that deals with ``_segment_cache`` is an |
| | | # optimization: we cache all the computation of URL path segments |
| | | # in this module-scope dictionary with the original string (or |
| | | # unicode value) as the key, so we can look it up later without |
| | | # needing to reencode or re-url-quote it |
| | | try: |
| | | return _segment_cache[(segment, safe)] |
| | | except KeyError: |
| | | if segment.__class__ is unicode: # isinstance slighly slower (~15%) |
| | | result = url_quote(segment.encode('utf-8'), safe) |
| | | else: |
| | | result = url_quote(str(segment), safe) |
| | | # we don't need a lock to mutate _segment_cache, as the below |
| | | # will generate exactly one Python bytecode (STORE_SUBSCR) |
| | | _segment_cache[(segment, safe)] = result |
| | | return result |
| | | |
| | | @lru_cache(1000) |
| | | def join_elements(elements): |
| | | return '/'.join([quote_path_segment(s, safe=':@&+$,') for s in elements]) |