summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-27 03:35:00 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-27 03:35:00 +0000
commitd9a76e61e75f77fbacf6ee5525f64fe2ac37184f (patch)
tree314c90fb54e272ef4d45a08694b34aeae5ad29fd
parent9a9af812bc56fada307c784173dab9045f7d70a2 (diff)
downloadpyramid-d9a76e61e75f77fbacf6ee5525f64fe2ac37184f.tar.gz
pyramid-d9a76e61e75f77fbacf6ee5525f64fe2ac37184f.tar.bz2
pyramid-d9a76e61e75f77fbacf6ee5525f64fe2ac37184f.zip
- Use the ``pkg_resources`` API to locate template filenames instead
of dead-reckoning using the ``os.path`` module.
-rw-r--r--CHANGES.txt9
-rw-r--r--repoze/bfg/path.py41
-rw-r--r--repoze/bfg/tests/test_path.py105
3 files changed, 112 insertions, 43 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index e905e4cfd..94a17563d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,12 @@
+Next release
+============
+
+Features
+--------
+
+- Use the ``pkg_resources`` API to locate template filenames instead
+ of dead-reckoning using the ``os.path`` module.
+
1.0a4 (2009-06-25)
==================
diff --git a/repoze/bfg/path.py b/repoze/bfg/path.py
index 6fee43791..d8e90f0ff 100644
--- a/repoze/bfg/path.py
+++ b/repoze/bfg/path.py
@@ -1,27 +1,32 @@
import os
import sys
+import pkg_resources
-def caller_path(path, level=2, package_globals=None): # package_globals==testing
+def caller_path(path, level=2):
if not os.path.isabs(path):
+ module = caller_module(level+1)
+ prefix = package_path(module)
+ path = os.path.join(prefix, path)
+ return path
- if package_globals is None:
- package_globals = sys._getframe(level).f_globals
-
- if '__bfg_abspath__' in package_globals:
- return os.path.join(package_globals['__bfg_abspath__'], path)
+def caller_module(level=2):
+ module_globals = sys._getframe(level).f_globals
+ module_name = module_globals['__name__']
+ module = sys.modules[module_name]
+ return module
- # computing the abspath is actually kinda expensive so we
- # memoize the result
- package_name = package_globals['__name__']
- package = sys.modules[package_name]
- prefix = package_path(package)
+def package_path(package):
+ # computing the abspath is actually kinda expensive so we memoize
+ # the result
+ prefix = getattr(package, '__bfg_abspath__', None)
+ if prefix is None:
+ prefix = pkg_resources.resource_filename(package.__name__, '')
+ # pkg_resources doesn't care whether we feed it a package
+ # name or a module name within the package, the result
+ # will be the same: a directory name to the package itself
try:
- package_globals['__bfg_abspath__'] = prefix
+ package.__bfg_abspath__ = prefix
except:
+ # this is only an optimization, ignore any error
pass
- path = os.path.join(prefix, path)
- return path
-
-def package_path(package):
- return os.path.abspath(os.path.dirname(package.__file__))
-
+ return prefix
diff --git a/repoze/bfg/tests/test_path.py b/repoze/bfg/tests/test_path.py
index 42ab1f8fe..e8068e52d 100644
--- a/repoze/bfg/tests/test_path.py
+++ b/repoze/bfg/tests/test_path.py
@@ -1,51 +1,106 @@
import unittest
class TestCallerPath(unittest.TestCase):
- def _callFUT(self, path, level=2, package_globals=None):
+ def tearDown(self):
+ from repoze.bfg.tests import test_path
+ if hasattr(test_path, '__bfg_abspath__'):
+ del test_path.__bfg_abspath__
+
+ def _callFUT(self, path, level=2):
from repoze.bfg.path import caller_path
- return caller_path(path, level, package_globals)
+ return caller_path(path, level)
def test_isabs(self):
- self.assertEqual(self._callFUT('/a/b/c'), '/a/b/c')
+ result = self._callFUT('/a/b/c')
+ self.assertEqual(result, '/a/b/c')
def test_pkgrelative(self):
import os
here = os.path.abspath(os.path.dirname(__file__))
- self.assertEqual(self._callFUT('a/b/c'), os.path.join(here, 'a/b/c'))
+ result = self._callFUT('a/b/c')
+ self.assertEqual(result, os.path.join(here, 'a/b/c'))
def test_memoization_has_bfg_abspath(self):
import os
+ from repoze.bfg.tests import test_path
+ test_path.__bfg_abspath__ = '/foo/bar'
here = os.path.abspath(os.path.dirname(__file__))
- package_globals = {'__bfg_abspath__':'/foo/bar'}
- self.assertEqual(
- self._callFUT('a/b/c',
- package_globals=package_globals),
- os.path.join('/foo/bar', 'a/b/c'))
+ result = self._callFUT('a/b/c')
+ self.assertEqual(result, os.path.join('/foo/bar', 'a/b/c'))
def test_memoization_success(self):
import os
here = os.path.abspath(os.path.dirname(__file__))
- package_globals = {'__name__':'repoze.bfg.tests.test_path'}
- self.assertEqual(
- self._callFUT('a/b/c',
- package_globals=package_globals),
- os.path.join(here, 'a/b/c'))
- self.assertEqual(package_globals['__bfg_abspath__'], here)
+ from repoze.bfg.tests import test_path
+ result = self._callFUT('a/b/c')
+ self.assertEqual(result, os.path.join(here, 'a/b/c'))
+ self.assertEqual(test_path.__bfg_abspath__, here)
+
+class TestCallerModule(unittest.TestCase):
+ def _callFUT(self, level=2):
+ from repoze.bfg.path import caller_module
+ return caller_module(level)
+
+ def test_it_level_1(self):
+ from repoze.bfg.tests import test_path
+ result = self._callFUT(1)
+ self.assertEqual(result, test_path)
+
+ def test_it_level_2(self):
+ from repoze.bfg.tests import test_path
+ result = self._callFUT(2)
+ self.assertEqual(result, test_path)
+
+ def test_it_level_3(self):
+ import unittest
+ result = self._callFUT(3)
+ self.assertEqual(result, unittest)
+
+class TestPackagePath(unittest.TestCase):
+ def _callFUT(self, package):
+ from repoze.bfg.path import package_path
+ return package_path(package)
+
+ def test_it_package(self):
+ from repoze.bfg import tests
+ package = DummyPackageOrModule(tests)
+ result = self._callFUT(package)
+ self.assertEqual(result, package.package_path)
+
+ def test_it_module(self):
+ from repoze.bfg.tests import test_path
+ module = DummyPackageOrModule(test_path)
+ result = self._callFUT(module)
+ self.assertEqual(result, module.package_path)
+
+ def test_memoization_success(self):
+ from repoze.bfg.tests import test_path
+ module = DummyPackageOrModule(test_path)
+ result = self._callFUT(module)
+ self.assertEqual(module.__bfg_abspath__, module.package_path)
def test_memoization_fail(self):
+ from repoze.bfg.tests import test_path
+ module = DummyPackageOrModule(test_path, raise_exc=TypeError)
+ result = self._callFUT(module)
+ self.failIf(hasattr(module, '__bfg_abspath__'))
+ self.assertEqual(result, module.package_path)
+
+class DummyPackageOrModule:
+ def __init__(self, real_package_or_module, raise_exc=None):
+ self.__dict__['raise_exc'] = raise_exc
+ self.__dict__['__name__'] = real_package_or_module.__name__
import os
- here = os.path.abspath(os.path.dirname(__file__))
- class faildict(dict):
- def __setitem__(self, *arg):
- raise KeyError('name')
- package_globals = faildict({'__name__':'repoze.bfg.tests.test_path'})
- self.assertEqual(
- self._callFUT('a/b/c',
- package_globals=package_globals),
- os.path.join(here, 'a/b/c'))
- self.failIf('__bfg_abspath__' in package_globals)
+ self.__dict__['package_path'] = os.path.dirname(
+ os.path.abspath(real_package_or_module.__file__))
+
+ def __setattr__(self, key, val):
+ if self.raise_exc is not None:
+ raise self.raise_exc
+ self.__dict__[key] = val
+