def test_map_ancestor(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) m = Map() m[a] = u'Value for A' assert m[b] == u'Value for A'
def test_exact_getitem(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) m[a] = u"Value for A" with py.test.raises(KeyError): m.exact_getitem(b) assert m.exact_getitem(a) == u'Value for A'
def test_exact_get(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) m[a] = u"Value for A" assert m.exact_get(b) is None assert m.exact_get(b, u'default') == u'default' assert m.exact_get(a) == u'Value for A'
def test_map_exact_get(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) m[a] = u"Value for A" assert m.exact_get(b) is None assert m.exact_get(b, u'default') == u'default' assert m.exact_get(a) == u'Value for A'
def test_map_exact_getitem(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) m[a] = u"Value for A" with pytest.raises(KeyError): m.exact_getitem(b) assert m.exact_getitem(a) == u'Value for A'
def test_map_all_empty(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) c = MapKey('c', parents=[a]) d = MapKey('d', parents=[b, c]) m[b] = u'Value for B' m[c] = u'Value for C' m[d] = u'Value for D' assert list(m.all(d)) == [u'Value for D', u'Value for B', u'Value for C']
def singledispatch(func): registry = Map() def dispatch(typ): """generic_func.dispatch(type) -> <function implementation> Runs the dispatch algorithm to return the best available implementation for the given `type` registered on `generic_func`. """ return registry[ClassMapKey(typ)] def register(typ, func=None): """generic_func.register(type, func) -> func Registers a new implementation for the given `type` on a `generic_func`. """ if func is None: return lambda f: register(typ, f) registry[ClassMapKey(typ)] = func return func def wrapper(*args, **kw): return dispatch(args[0].__class__)(*args, **kw) registry[ClassMapKey(object)] = func wrapper.register = register wrapper.dispatch = dispatch update_wrapper(wrapper, func) return wrapper
def test_map_deletion(): m = Map() a = MapKey('a') m[a] = u'Value for A' del m[a] with pytest.raises(KeyError): m[a]
def test_map_ancestor_mro2(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) c = MapKey('c', parents=[a]) d = MapKey('d', parents=[b, c]) m[c] = u'Value for C' # now we do get C assert m[d] == u'Value for C'
def test_map_parent(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) c = MapKey('c', parents=[a]) m[b] = u'Value for B' assert m[b] == u'Value for B' with pytest.raises(KeyError): m[c] with pytest.raises(KeyError): m[a]
def test_map_ancestor_mro(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) c = MapKey('c', parents=[a]) d = MapKey('d', parents=[b, c]) m[b] = u'Value for B' m[c] = u'Value for C' # b comes first in mro assert m[d] == u'Value for B'
def test_map_ancestor_direct_key_wins(): m = Map() a = MapKey('a') b = MapKey('b', parents=[a]) c = MapKey('c', parents=[a]) d = MapKey('d', parents=[b, c]) m[b] = u'Value for B' m[c] = u'Value for C' m[d] = u'Value for D' assert m[d] == u'Value for D'
class ConverterRegistry(object): """A registry for converters. Used to decode/encode URL parameters and path variables used by the :meth:`morepath.AppBase.path` directive. Is aware of inheritance. """ def __init__(self): self._map = Map() def register_converter(self, type, converter): """Register a converter for type. :param type: the Python type for which to register the converter. :param converter: a :class:`morepath.Converter` instance. """ self._map[ClassMapKey(type)] = converter def converter_for_type(self, type): """Get converter for type. Is aware of inheritance; if nothing is registered for given type will return converter registered for base class. :param type: The type for which to look up the converter. :returns: a :class:`morepath.Converter` instance. """ return self._map.get(ClassMapKey(type)) def converter_for_value(self, v): """Get converter for value. Is aware of inheritance; if nothing is registered for type of given value will return converter registered for base class. :param value: The value for which to look up the converter. :returns: a :class:`morepath.Converter` instance. """ if v is None: return IDENTITY_CONVERTER return self.converter_for_type(type(v))
def clear(self): self._map = Map()
def __init__(self): self._map = Map()
class ConverterRegistry(object): """A registry for converters. Used to decode/encode URL parameters and path variables used by the :meth:`morepath.App.path` directive. Is aware of inheritance. """ def __init__(self): self._map = Map() def clear(self): self._map = Map() def register_converter(self, type, converter): """Register a converter for type. :param type: the Python type for which to register the converter. :param converter: a :class:`morepath.Converter` instance. """ self._map[ClassMapKey(type)] = converter def converter_for_type(self, type): """Get converter for type. Is aware of inheritance; if nothing is registered for given type it returns the converter registered for its base class. :param type: The type for which to look up the converter. :returns: a :class:`morepath.Converter` instance. """ result = self._map.get(ClassMapKey(type)) if result is None: raise DirectiveError( "Cannot find converter for type: %r" % type) return result def converter_for_value(self, v): """Get converter for value. Is aware of inheritance; if nothing is registered for type of given value it returns the converter registered for its base class. :param value: The value for which to look up the converter. :returns: a :class:`morepath.Converter` instance. """ if v is None: return IDENTITY_CONVERTER try: return self.converter_for_type(type(v)) except DirectiveError: raise DirectiveError( "Cannot find converter for default value: %r (%s)" % (v, type(v))) def converter_for_explicit_or_type(self, c): """Given a converter or a type, turn it into an explicit one. """ if type(c) in [type, ClassType]: return self.converter_for_type(c) return c def converter_for_explicit_or_type_or_list(self, c): """Given a converter or type or list, turn it into an explicit one. :param c: can either be a converter, or a type for which a converter can be looked up, or a list with a converter or a type in it. :returns: a :class:`Converter` instance. """ if isinstance(c, list): if len(c) == 0: c = IDENTITY_CONVERTER else: c = self.converter_for_explicit_or_type(c[0]) return ListConverter(c) return self.converter_for_explicit_or_type(c) def explicit_converters(self, converters): """Given converter dictionary, make everything in it explicit. This means types have converters looked up for them, and lists are turned into :class:`ListConverter`. """ return {name: self.converter_for_explicit_or_type_or_list(value) for name, value in converters.items()} def argument_and_explicit_converters(self, arguments, converters): """Use explict converters unless none supplied, then use default args. """ result = self.explicit_converters(converters) for name, value in arguments.items(): if name not in result: result[name] = self.converter_for_value(value) return result
def test_map_simple_key(): m = Map() a = MapKey('a') m[a] = u'Value for A' assert m[a] == u'Value for A'
def test_map_get(): m = Map() a = MapKey('a') m[a] = u'Value for A' assert m.get(a) == u'Value for A'
def test_map_get_default(): m = Map() a = MapKey('a') assert m.get(a, 'default') == 'default'
def test_map_same_underlying_key_is_same(): m = Map() a = MapKey('a') a_another = MapKey('a') m[a] = u'Value for A' assert m[a_another] == u'Value for A'