Skip to content

Commit

Permalink
- Interpolation variables now try to use the registry first, but fall
Browse files Browse the repository at this point in the history
  back to "stack" values; the most important of where is ``%(here)s``;
  this interpolation variable can be used in any config file.  It will
  be the absolute path to the parent directory of the configuration
  file in which it was declared.  Any stack variable can be overridden
  (for interpolation purposes) by a registry variable.
  • Loading branch information
mcdonc committed Jul 26, 2009
1 parent f0bdfd2 commit 84d10be
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 7 deletions.
10 changes: 10 additions & 0 deletions CHANGES.txt
@@ -1,6 +1,16 @@
repoze.configuration Changelog
==============================

Next release
------------

- Interpolation variables now try to use the registry first, but fall
back to "stack" values; the most important of where is ``%(here)s``;
this interpolation variable can be used in any config file. It will
be the absolute path to the parent directory of the configuration
file in which it was declared. Any stack variable can be overridden
(for interpolation purposes) by a registry variable.

0.4 (2009-07-25)
----------------

Expand Down
22 changes: 18 additions & 4 deletions repoze/configuration/context.py
Expand Up @@ -21,9 +21,11 @@ def __init__(self, registry, loader=None):
def interpolate(self, value):
def _interpolation_replace(match):
s = match.group(1)
if not s in self.registry:
raise KeyError(s)
return self.registry[s]
if s in self.registry:
return self.registry[s]
if self.stack and s in self.stack[-1]:
return self.stack[-1][s]
raise KeyError(s)
if '%(' in value:
value = _INTERP.sub(_interpolation_replace, value)
return value.encode('utf-8')
Expand Down Expand Up @@ -73,11 +75,23 @@ def stream(self, filename, package=None):
return open(filename)
else:
return pkg_resources.resource_stream(package.__name__, filename)

def abs_filename(self, filename, package=None):
if os.path.isabs(filename):
return filename
if package is None:
package = self.current_package()
if package is None:
return os.path.abspath(filename)
else:
return pkg_resources.resource_filename(package.__name__, filename)

def load(self, filename, package, override=False, loader=None):
fn = self.abs_filename(filename, package)
here = os.path.dirname(fn)
stream = self.stream(filename, package)
self.stack.append({'filename':filename, 'package':package,
'override':override})
'override':override, 'here':here})
if loader is None:
loader = self.loader
try:
Expand Down
66 changes: 63 additions & 3 deletions repoze/configuration/tests/test_context.py
Expand Up @@ -18,12 +18,26 @@ def test_ctor(self):
self.assertEqual(context.stack, [])
self.assertEqual(context.actions, [])

def test_interpolate(self):
def test_interpolate_from_registry(self):
registry = {'here':'/here', 'there':'/there'}
context = self._makeOne(registry)
result = context.interpolate('Here is %(here)s, there is %(there)s')
self.assertEqual(result, 'Here is /here, there is /there')

def test_interpolate_from_registry_overrides_stack(self):
registry = {'here':'/here', 'there':'/there'}
context = self._makeOne(registry)
context.stack = [{'here':'stack_here', 'there':'stack_there'}]
result = context.interpolate('Here is %(here)s, there is %(there)s')
self.assertEqual(result, 'Here is /here, there is /there')

def test_interpolate_from_registry_falls_back_to_stack(self):
registry = {'here':'/here'}
context = self._makeOne(registry)
context.stack = [{'here':'stack_here', 'there':'stack_there'}]
result = context.interpolate('Here is %(here)s, there is %(there)s')
self.assertEqual(result, 'Here is /here, there is stack_there')

def test_interpolate_nothing_to_interpolate(self):
registry = {'here':'/here', 'there':'/there'}
context = self._makeOne(registry)
Expand Down Expand Up @@ -180,6 +194,38 @@ def test_stream_nopackage_currentpackage(self):
expected = open(filename).read()
self.assertEqual(context.stream('__init__.py').read(), expected)

def test_abs_filename_absolute(self):
import os
from repoze.configuration.tests import fixtures
filename = os.path.join(os.path.dirname(
os.path.abspath(fixtures.__file__)), '__init__.py')
context = self._makeOne()
result = context.abs_filename(filename)
self.assertEqual(result, filename)

def test_abs_filename_nopackage_nocurrentpackage(self):
import os
from repoze.configuration.tests import fixtures
old_cwd = os.getcwd()
fixtures = os.path.dirname(os.path.abspath(fixtures.__file__))
filename = os.path.join(fixtures, '__init__.py')
try:
os.chdir(fixtures)
context = self._makeOne()
result = context.abs_filename('__init__.py')
self.assertEqual(result, filename)
finally:
os.chdir(old_cwd)

def test_abs_filename_nopackage_currentpackage(self):
import os
from repoze.configuration.tests import fixtures
context = self._makeOne()
context.stack.append({'package':fixtures})
fixtures = os.path.dirname(os.path.abspath(fixtures.__file__))
filename = os.path.join(fixtures, '__init__.py')
self.assertEqual(context.abs_filename('__init__.py'), filename)

def test_load_standard_loader(self):
def loader(context, stream):
context.loaded = True
Expand All @@ -197,9 +243,23 @@ def loader(context, stream):
context.load('configure.yml', fixtures, loader=loader)
self.assertEqual(context.stack, [])
self.assertEqual(context.loaded, True)

# doesn't blow up


def test_load_sets_stack(self):
import os
result = []
def loader(context, stream):
result.append(context.stack[-1])
context = self._makeOne()
from repoze.configuration.tests import fixtures
context.stack = [{'package':fixtures}]
context.load('configure.yml', fixtures, loader=loader)
result = result[0]
expect_here = os.path.dirname(os.path.abspath(fixtures.__file__))
self.assertEqual(result['here'], expect_here)
self.assertEqual(result['override'], False)
self.assertEqual(result['filename'], 'configure.yml')
self.assertEqual(result['package'], fixtures)

def test_execute(self):
registry = {}
Expand Down

0 comments on commit 84d10be

Please sign in to comment.