fix: add get_value() convenience function
This commit is contained in:
parent
fb1a7b22d8
commit
5ec0a8e82d
5 changed files with 102 additions and 1 deletions
|
|
@ -38,6 +38,7 @@ from webhelpers2.html import HTML
|
|||
|
||||
from wuttjamaican.util import (
|
||||
get_timezone_by_name,
|
||||
get_value,
|
||||
localtime,
|
||||
load_entry_points,
|
||||
load_object,
|
||||
|
|
@ -374,6 +375,22 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
|||
self.__dict__["enum"] = importlib.import_module(spec)
|
||||
return self.enum
|
||||
|
||||
def get_value(self, obj, key):
|
||||
"""
|
||||
Convenience wrapper around
|
||||
:func:`wuttjamaican.util.get_value()`.
|
||||
|
||||
:param obj: Arbitrary dict or object of any kind which would
|
||||
have named attributes.
|
||||
|
||||
:param key: Key/name of the field to get.
|
||||
|
||||
:returns: Whatever value is found. Or maybe an
|
||||
``AttributeError`` is raised if the object does not have
|
||||
the key/attr set.
|
||||
"""
|
||||
return get_value(obj, key)
|
||||
|
||||
def load_object(self, spec):
|
||||
"""
|
||||
Import and/or load and return the object designated by the
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ class ModelBase: # pylint: disable=empty-docstring
|
|||
|
||||
def __iter__(self):
|
||||
# nb. we override this to allow for `dict(self)`
|
||||
# nb. this does *not* include association proxy values
|
||||
# nb. this does *not* include association proxy values;
|
||||
# see also wuttjamaican.util.get_value()
|
||||
state = sa.inspect(self)
|
||||
fields = [attr.key for attr in state.attrs]
|
||||
return iter([(field, getattr(self, field)) for field in fields])
|
||||
|
|
|
|||
|
|
@ -82,6 +82,34 @@ def get_class_hierarchy(klass, topfirst=True):
|
|||
return hierarchy
|
||||
|
||||
|
||||
def get_value(obj, key):
|
||||
"""
|
||||
Convenience function to retrive a value by name from the given
|
||||
object. This will first try to assume the object is a dict but
|
||||
will fallback to using ``getattr()`` on it.
|
||||
|
||||
:param obj: Arbitrary dict or object of any kind which would have
|
||||
named attributes.
|
||||
|
||||
:param key: Key/name of the field to get.
|
||||
|
||||
:returns: Whatever value is found. Or maybe an ``AttributeError``
|
||||
is raised if the object does not have the key/attr set.
|
||||
"""
|
||||
# nb. we try dict access first, since wutta data model objects
|
||||
# should all support that anyway, so it's 2 birds 1 stone.
|
||||
try:
|
||||
return obj[key]
|
||||
|
||||
except (KeyError, TypeError):
|
||||
# nb. key error means the object supports key lookup (i.e. is
|
||||
# dict-like) but did not have that key set. which is actually
|
||||
# an expected scenario for association proxy fields, but for
|
||||
# those a getattr() should still work; see also
|
||||
# wuttjamaican.db.util.ModelBase
|
||||
return getattr(obj, key)
|
||||
|
||||
|
||||
def load_entry_points(group, ignore_errors=False):
|
||||
"""
|
||||
Load a set of ``setuptools``-style entry points.
|
||||
|
|
|
|||
|
|
@ -48,6 +48,32 @@ class TestAppHandler(FileTestCase):
|
|||
def test_get_enum(self):
|
||||
self.assertIs(self.app.get_enum(), wuttjamaican.enum)
|
||||
|
||||
def test_get_value(self):
|
||||
|
||||
class Object:
|
||||
def __init__(self, **kw):
|
||||
self.__dict__.update(kw)
|
||||
|
||||
class Dict(dict):
|
||||
pass
|
||||
|
||||
# dict object
|
||||
obj = {"foo": "bar"}
|
||||
self.assertEqual(self.app.get_value(obj, "foo"), "bar")
|
||||
|
||||
# object w/ attrs
|
||||
obj = Object(foo="bar")
|
||||
self.assertEqual(self.app.get_value(obj, "foo"), "bar")
|
||||
|
||||
# dict-like w/ attrs
|
||||
obj = Dict({"foo": "bar"})
|
||||
obj.baz = "yyy"
|
||||
self.assertEqual(self.app.get_value(obj, "baz"), "yyy")
|
||||
|
||||
# missing attr
|
||||
obj = Object(foo="bar")
|
||||
self.assertRaises(AttributeError, self.app.get_value, obj, "baz")
|
||||
|
||||
def test_load_object(self):
|
||||
|
||||
# just confirm the method works on a basic level; the
|
||||
|
|
|
|||
|
|
@ -41,6 +41,35 @@ class TestGetClassHierarchy(TestCase):
|
|||
self.assertEqual(classes, [C, B, A])
|
||||
|
||||
|
||||
class TestGetValue(TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
|
||||
class Object:
|
||||
def __init__(self, **kw):
|
||||
self.__dict__.update(kw)
|
||||
|
||||
class Dict(dict):
|
||||
pass
|
||||
|
||||
# dict object
|
||||
obj = {"foo": "bar"}
|
||||
self.assertEqual(mod.get_value(obj, "foo"), "bar")
|
||||
|
||||
# object w/ attrs
|
||||
obj = Object(foo="bar")
|
||||
self.assertEqual(mod.get_value(obj, "foo"), "bar")
|
||||
|
||||
# dict-like w/ attrs
|
||||
obj = Dict({"foo": "bar"})
|
||||
obj.baz = "yyy"
|
||||
self.assertEqual(mod.get_value(obj, "baz"), "yyy")
|
||||
|
||||
# missing attr
|
||||
obj = Object(foo="bar")
|
||||
self.assertRaises(AttributeError, mod.get_value, obj, "baz")
|
||||
|
||||
|
||||
class TestLoadEntryPoints(TestCase):
|
||||
|
||||
def test_empty(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue