summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-05-01 09:06:54 +0000
committerChris McDonough <chrism@agendaless.com>2009-05-01 09:06:54 +0000
commit8e037fda9af695b608240d8fed085c403f657011 (patch)
tree9603414fe4bcb2ea8b6a93dd3b5856ae5c5d2728
parent25c8f66346eab8ec9455e8dc734bf2b407e2e423 (diff)
downloadpyramid-8e037fda9af695b608240d8fed085c403f657011.tar.gz
pyramid-8e037fda9af695b608240d8fed085c403f657011.tar.bz2
pyramid-8e037fda9af695b608240d8fed085c403f657011.zip
- In previous releases, the ``repoze.bfg.url.model_url``,
``repoze.bfg.traversal.model_path`` and ``repoze.bfg.traversal.model_path_tuple`` functions always ignored the ``__name__`` argument of the root object in a model graph ( effectively replacing it with a leading ``/`` in the returned value) when a path or URL was generated. The code required to perform this operation was not efficient. As of this release, the root object in a model graph *must* have a ``__name__`` attribute that is either ``None`` or the empty string (``''``) for URLs and paths to be generated properly from these APIs. If your root model object has a ``__name__`` argument that is not one of these values, you will need to change your code for URLs and paths to be generated properly. If your model graph has a root node with a string ``__name__`` that is not null, the value of ``__name__`` will be prepended to every path and URL generated.
-rw-r--r--CHANGES.txt16
-rw-r--r--docs/narr/models.rst9
-rw-r--r--repoze/bfg/tests/test_traversal.py26
-rw-r--r--repoze/bfg/traversal.py27
4 files changed, 66 insertions, 12 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index e51c238b4..ded5abc62 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -82,6 +82,22 @@ Features
Backwards Incompatibilities
---------------------------
+- In previous releases, the ``repoze.bfg.url.model_url``,
+ ``repoze.bfg.traversal.model_path`` and
+ ``repoze.bfg.traversal.model_path_tuple`` functions always ignored
+ the ``__name__`` argument of the root object in a model graph (
+ effectively replacing it with a leading ``/`` in the returned value)
+ when a path or URL was generated. The code required to perform this
+ operation was not efficient. As of this release, the root object in
+ a model graph *must* have a ``__name__`` attribute that is either
+ ``None`` or the empty string (``''``) for URLs and paths to be
+ generated properly from these APIs. If your root model object has a
+ ``__name__`` argument that is not one of these values, you will need
+ to change your code for URLs and paths to be generated properly. If
+ your model graph has a root node with a string ``__name__`` that is
+ not null, the value of ``__name__`` will be prepended to every path
+ and URL generated.
+
- The ``repoze.bfg.location.LocationProxy`` class and the
``repoze.bfg.location.ClassAndInstanceDescr`` class have both been
removed in order to be able to eventually shed a dependency on
diff --git a/docs/narr/models.rst b/docs/narr/models.rst
index 61e313830..9daa5668d 100644
--- a/docs/narr/models.rst
+++ b/docs/narr/models.rst
@@ -111,6 +111,15 @@ string. For instance:
__name__ = ''
__parent__ = None
+.. note:: If your root model object has a ``__name__`` argument that
+ is not ``None`` or the empty string, URLs returned by the
+ ``repoze.bfg.url.model_url`` function and paths generated by the
+ ``repoze.bfg.traversal.model_path`` and
+ ``repoze.bfg.traversal.model_path_tuple`` APIs will be generated
+ improperly. The value of ``__name__`` will be prepended to every
+ path and URL generated (as opposed to a single leading slash or
+ empty tuple element).
+
A node returned from the root item's ``__getitem__`` method should
have a ``__parent__`` attribute that is a reference to the root
object, and its ``__name__`` attribute should match the name by which
diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py
index f361d0a79..867dae318 100644
--- a/repoze/bfg/tests/test_traversal.py
+++ b/repoze/bfg/tests/test_traversal.py
@@ -384,7 +384,31 @@ class ModelPathTests(unittest.TestCase):
root.__name__ = None
result = self._callFUT(root)
self.assertEqual(result, '/')
-
+
+ def test_root_default_emptystring(self):
+ root = DummyContext()
+ root.__parent__ = None
+ root.__name__ = ''
+ result = self._callFUT(root)
+ self.assertEqual(result, '/')
+
+ def test_root_object_nonnull_name_direct(self):
+ root = DummyContext()
+ root.__parent__ = None
+ root.__name__ = 'flubadub'
+ result = self._callFUT(root)
+ self.assertEqual(result, 'flubadub') # insane case
+
+ def test_root_object_nonnull_name_indirect(self):
+ root = DummyContext()
+ root.__parent__ = None
+ root.__name__ = 'flubadub'
+ other = DummyContext()
+ other.__parent__ = root
+ other.__name__ = 'barker'
+ result = self._callFUT(other)
+ self.assertEqual(result, 'flubadub/barker') # insane case
+
def test_nonroot_default(self):
root = DummyContext()
root.__parent__ = None
diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py
index f4f64484f..9da1818fc 100644
--- a/repoze/bfg/traversal.py
+++ b/repoze/bfg/traversal.py
@@ -172,12 +172,14 @@ def model_path(model, *elements):
instance, if one of the models in your graph has a
``__name__`` which (by error) is a dictionary, the
``model_path`` function will attempt to append it to a
- string and it will cause a TypeError. A single
- exception to this rule exists: the :term:`root` model
- may have a ``__name__`` attribute of any value; the
- value of this attribute will always be ignored (and
- effectively replaced with a leading ``/``) when the path
- is generated.
+ string and it will cause a TypeError.
+
+ .. note:: The the :term:`root` model *must* have a ``__name__``
+ attribute with a value of either ``None`` or the empty
+ string for paths to be generated properly. If the root
+ model has a non-null ``__name__`` attribute, its name
+ will be prepended to the generated path rather than a
+ single leading '/' character.
"""
path = _model_path_list(model, *elements)
return path and '/'.join([quote_path_segment(x) for x in path]) or '/'
@@ -210,11 +212,14 @@ def model_path_tuple(model, *elements):
instance, if one of the models in your graph has a
``__name__`` which (by error) is a dictionary, that
dictionary will be placed in the path tuple; no warning
- or error will be given. A single exception to this rule
- exists: the :term:`root` model may have a ``__name__``
- attribute of any value; the value of this attribute will
- always be ignored (and effectively replaced with ``''``)
- when the path is generated.
+ or error will be given.
+
+ .. note:: The the :term:`root` model *must* have a ``__name__``
+ attribute with a value of either ``None`` or the empty
+ string for path tuples to be generated properly. If
+ the root model has a non-null ``__name__`` attribute,
+ its name will be the first element in the generated
+ path tuple rather than the empty string.
"""
return tuple(_model_path_list(model, *elements))