Rev 5558: Implement a simple interpolation mechanism. in file:///home/vila/src/bzr/experimental/config/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Fri Feb 4 15:48:32 UTC 2011
At file:///home/vila/src/bzr/experimental/config/
------------------------------------------------------------
revno: 5558
revision-id: v.ladeuil+lp at free.fr-20110204154832-l0d43q84i15fg32x
parent: v.ladeuil+lp at free.fr-20110203103909-lgp491y9s2t1tj83
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: interpolate
timestamp: Fri 2011-02-04 16:48:32 +0100
message:
Implement a simple interpolation mechanism.
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py 2011-02-03 10:39:09 +0000
+++ b/bzrlib/config.py 2011-02-04 15:48:32 +0000
@@ -146,30 +146,48 @@
option_ref_re = None
- def interpolate(self, string, env=None):
+ def interpolate(self, string, env=None, ref_stack=None):
+ if ref_stack is None:
+ # What references are currently resolved (to detect loops)
+ ref_stack = []
if self.option_ref_re is None:
# We want to match the most embedded reference first (i.e. for
# '{{foo}}' we will get '{foo}',
# for '{bar{baz}}' we will get '{baz}'
self.option_ref_re = re.compile('({[^{}]+})')
- while True:
- found = self.option_ref_re.search(string)
- if found is None:
- # No more references, interpolation is done
- break
- ref = found.group()
- name = ref[1:-1]
- if env is not None and name in env:
- # Special case, values provided in env takes precedence over
- # anything else
- value = env[name]
+ result = string
+ is_ref = False
+ chunks = []
+ import pdb; pdb.set_trace()
+ # Split will isolate refs so that every other chunk is a ref
+ for chunk in self.option_ref_re.split(result):
+ if not is_ref:
+ chunks.append(chunk)
+ is_ref = True
else:
- # FIXME: This is a limited implementation, what we really need
- # is a way to query the bzr config for the value of an option,
- # respecting the scope rules -- vila 20101222
- value = self[name]
- string = string.replace(ref, value)
- return string
+ name = chunk[1:-1]
+ if name in ref_stack:
+ raise errors.InterpolationLoop(string, ref_stack)
+ ref_stack.append(name)
+ value = self._interpolate_option(name, env, ref_stack)
+ raw_chunks.append(value)
+ ref_stack.pop()
+ is_ref = False
+ result = ''.join(chunks)
+ return result
+
+ def _interpolate_option(self, name, env, ref_stack):
+ if env is not None and name in env:
+ # Special case, values provided in env takes precedence over
+ # anything else
+ value = env[name]
+ else:
+ # FIXME: This is a limited implementation, what we really need
+ # is a way to query the bzr config for the value of an option,
+ # respecting the scope rules -- vila 20101222
+ value = self[name]
+ return self.interpolate(value, env, ref_stack)
+
class Config(object):
"""A configuration policy - what username, editor, gpg needs etc."""
=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py 2011-02-03 10:39:09 +0000
+++ b/bzrlib/errors.py 2011-02-04 15:48:32 +0000
@@ -3222,10 +3222,10 @@
self.branch_url = branch_url
# FIXME: I would prefer to define the config related exception classes in
-# config.py but the lazy import mechanism proscribe this -- vila 20101222
+# config.py but the lazy import mechanism proscribes this -- vila 20101222
class InterpolationLoop(BzrError):
- _fmt = 'Loop involving %(refs)s while evaluating %(string)s.'
+ _fmt = 'Loop involving %(refs)r while evaluating <%(string)s>.'
def __init__(self, string, refs):
self.string = string
=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py 2011-02-03 10:39:09 +0000
+++ b/bzrlib/tests/test_config.py 2011-02-04 15:48:32 +0000
@@ -376,7 +376,7 @@
self.assertInterpolate('xxx', c, '{{bar}}')
def test_simple_loop(self):
- c = self.get_config('foo=food')
+ c = self.get_config('foo={foo}')
self.assertRaises(errors.InterpolationLoop, c.interpolate, '{foo}')
More information about the bazaar-commits
mailing list