Skip to content
Merged
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
=========

0.3.0 - 2013-10-22
------------------

- Add ``#partial`` to partially expand templates and return new instances of
``URITemplate``.

0.2.0 - 2013-07-26
------------------

Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
uritemplate.py (0.3.0-1) Saucy; urgency=low

* New upstream release

-- Dennis Kaarsemaker <dennis@kaarsemaker.net> Sun, 06 Apr 2014 14:34:16 +0200

uritemplate.py (0.2.0-2) quantal; urgency=low

* ctually working package this time
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ Code relying on methods defined on :class:`URIVariable` and other classes,
methods, and functions in this section may break in future releases.

.. autoclass:: uritemplate.template.URIVariable
:members: original, operator, safe, variables, expand
:members: expand
12 changes: 10 additions & 2 deletions test_uritemplate.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from unittest import TestCase, main
from uritemplate import URITemplate, expand
from uritemplate import URITemplate, expand, partial
from uritemplate import variable


Expand Down Expand Up @@ -551,7 +551,7 @@ def test_list_test(self):
l = str([1, 2, 3, 4])
self.assertEqual(variable.list_test(l), False)

def test_list_test(self):
def test_list_of_tuples_test(self):
l = [(1, 2), (3, 4)]
self.assertEqual(variable.dict_test(l), False)

Expand All @@ -566,6 +566,14 @@ def test_expand(self):
self.assertEqual(expand(self.uri, {'endpoint': 'users'}),
'https://api.github.com/users')

def test_partial(self):
self.assertEqual(partial(self.uri), URITemplate(self.uri))
uri = self.uri + '/sigmavirus24{/other}'
self.assertEqual(
partial(uri, endpoint='users'),
URITemplate('https://api.github.com/users/sigmavirus24{/other}')
)


if __name__ == '__main__':
main()
6 changes: 3 additions & 3 deletions uritemplate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
__author__ = 'Ian Cordasco'
__license__ = 'Modified BSD'
__copyright__ = 'Copyright 2013 Ian Cordasco'
__version__ = '0.2.0'
__version__ = '0.3.0'
__version_info__ = tuple(int(i) for i in __version__.split('.'))

from uritemplate.api import URITemplate, expand
from uritemplate.api import URITemplate, expand, partial

__all__ = [URITemplate, expand]
__all__ = [URITemplate, expand, partial]
19 changes: 19 additions & 0 deletions uritemplate/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,22 @@ def expand(uri, var_dict=None, **kwargs):

"""
return URITemplate(uri).expand(var_dict, **kwargs)


def partial(uri, var_dict=None, **kwargs):
"""Partially expand the template with the given parameters.

If all of the parameters for the template are not given, return a
partially expanded template.

:param dict var_dict: Optional dictionary with variables and values
:param kwargs: Alternative way to pass arguments
:returns: :class:`URITemplate`

Example::

t = URITemplate('https://api.github.com{/end}')
t.partial() # => URITemplate('https://api.github.com{/end}')

"""
return URITemplate(uri).partial(var_dict, **kwargs)
53 changes: 43 additions & 10 deletions uritemplate/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,27 @@ def __eq__(self, other):
def __hash__(self):
return hash(self.uri)

def _expand(self, var_dict, replace):
if not self.variables:
return self.uri

expansion = var_dict
expanded = {}
for v in self.variables:
expanded.update(v.expand(expansion))

def replace_all(match):
return expanded.get(match.groups()[0], '')

def replace_partial(match):
match = match.groups()[0]
var = '{%s}' % match
return expanded.get(match) or var

replace = replace_partial if replace else replace_all

return template_re.sub(replace, self.uri)

def expand(self, var_dict=None, **kwargs):
"""Expand the template with the given parameters.

Expand All @@ -100,16 +121,28 @@ def expand(self, var_dict=None, **kwargs):
``val2`` will be used instead of ``val1``.

"""
if not self.variables:
return self.uri
var_dict = var_dict or {}
var_dict.update(kwargs)

expansion = var_dict or {}
expansion.update(kwargs)
expanded = {}
for v in self.variables:
expanded.update(v.expand(expansion))
return self._expand(var_dict, False)

def replace(match):
return expanded.get(match.groups()[0], '')
def partial(self, var_dict=None, **kwargs):
"""Partially expand the template with the given parameters.

return template_re.sub(replace, self.uri)
If all of the parameters for the template are not given, return a
partially expanded template.

:param dict var_dict: Optional dictionary with variables and values
:param kwargs: Alternative way to pass arguments
:returns: :class:`URITemplate`

Example::

t = URITemplate('https://api.github.com{/end}')
t.partial() # => URITemplate('https://api.github.com{/end}')

"""
var_dict = var_dict or {}
var_dict.update(kwargs)

return URITemplate(self._expand(var_dict, True))