Commits

Jason R. Coombs committed dfc06eb

Added DictStack, global_format, and namespace_format

  • Participants
  • Parent commits d8f740b
  • Tags 4.2

Comments (0)

Files changed (4)

 Changes
 -------
 
+4.2
+~~~
+
+* Added `dictlib.DictStack` for stacking dictionaries on one another.
+* Added `string.global_format` and `string.namespace_format` for formatting
+  a string with globals and with both globals and locals.
+
 4.1
 ~~~
 

jaraco/util/dictlib.py

 import re
 import sys
 import operator
+import collections
+import itertools
 
 from jaraco.lang.python import callable
 import jaraco.util.string
 	"""
 	def __missing__(self, key):
 		return key
+
+class DictStack(list, collections.Mapping):
+	"""
+	A stack of dictionaries that behaves as a view on those dictionaries,
+	giving preference to the last.
+
+	>>> stack = DictStack([dict(a=1, c=2), dict(b=2, a=2)])
+	>>> stack['a']
+	2
+	>>> stack['b']
+	2
+	>>> stack['c']
+	2
+	>>> stack.push(dict(a=3))
+	>>> stack['a']
+	3
+	>>> stack.keys()
+	['a', 'c', 'b']
+	>>> d = stack.pop()
+	>>> stack['a']
+	2
+	>>> d = stack.pop()
+	>>> stack['a']
+	1
+	"""
+	def keys(self):
+		return list(set(itertools.chain.from_iterable(c.keys() for c in self)))
+	def __getitem__(self, key):
+		for scope in reversed(self):
+			if key in scope: return scope[key]
+		raise KeyError(key)
+	push = list.append

jaraco/util/string.py

 from __future__ import absolute_import, unicode_literals
 
+import sys
 import re
 import inspect
 import itertools
 
 from .functools import compose
 from .exceptions import throws_exception
+import jaraco.util.dictlib
 
 
 def substitution(old, new):
 	>>> local_format("{a:5}")
 	u'    3'
 	"""
-	return string.format(**inspect.currentframe().f_back.f_locals)
+	context = inspect.currentframe().f_back.f_locals
+	if sys.version_info < (3,2):
+		return string.format(**context)
+	return string.format_map(context)
+
+def global_format(string):
+	"""
+	format the string using variables in the caller's global namespace.
+
+	>>> a = 3
+	>>> global_format("The func name: {global_format.func_name}")
+	u'The func name: global_format'
+	"""
+	context = inspect.currentframe().f_back.f_globals
+	if sys.version_info < (3,2):
+		return string.format(**context)
+	return string.format_map(context)
+
+def namespace_format(string):
+	"""
+	Format the string using variable in the caller's scope (locals + globals).
+
+	>>> a = 3
+	>>> namespace_format("A is {a} and this func is {namespace_format.func_name}")
+	u'A is 3 and this func is namespace_format'
+	"""
+	context = jaraco.util.dictlib.DictStack()
+	context.push(inspect.currentframe().f_back.f_globals)
+	context.push(inspect.currentframe().f_back.f_locals)
+	if sys.version_info < (3,2):
+		return string.format(**context)
+	return string.format_map(context)
 
 def is_decodable(value):
 	"""
 
 setup_params = dict(
 	name = name,
-	use_hg_version=dict(increment="0.0.1"),
+	use_hg_version=dict(increment="0.1"),
 	description = 'General utility modules that supply commonly-used functionality',
 	long_description = open('README').read(),
 	author = 'Jason R. Coombs',