mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 07:33:27 -06:00
Allow indexing API object types by class
This allows code like: from ipalib.plugins.dns import dnszone_mod api.Command[dnszone_mod] This form should be preferred when getting specific objects because it ensures that the appropriate plugin is imported. https://fedorahosted.org/freeipa/ticket/4185 Reviewed-By: Martin Kosek <mkosek@redhat.com>
This commit is contained in:
parent
6ecc4600e9
commit
4f302f6500
@ -287,7 +287,7 @@ class NameSpace(ReadOnly):
|
||||
>>> class Member(object):
|
||||
... def __init__(self, i):
|
||||
... self.i = i
|
||||
... self.name = 'member%d' % i
|
||||
... self.name = self.__name__ = 'member%d' % i
|
||||
... def __repr__(self):
|
||||
... return 'Member(%d)' % self.i
|
||||
...
|
||||
@ -378,6 +378,14 @@ class NameSpace(ReadOnly):
|
||||
>>> unsorted_ns[0]
|
||||
Member(7)
|
||||
|
||||
As a special extension, NameSpace objects can be indexed by objects that
|
||||
have a "__name__" attribute (e.g. classes). These lookups are converted
|
||||
to lookups on the name:
|
||||
|
||||
>>> class_ns = NameSpace([Member(7), Member(3), Member(5)], sort=False)
|
||||
>>> unsorted_ns[Member(3)]
|
||||
Member(3)
|
||||
|
||||
The `NameSpace` class is used in many places throughout freeIPA. For a few
|
||||
examples, see the `plugable.API` and the `frontend.Command` classes.
|
||||
"""
|
||||
@ -447,6 +455,7 @@ class NameSpace(ReadOnly):
|
||||
"""
|
||||
Return ``True`` if namespace has a member named ``name``.
|
||||
"""
|
||||
name = getattr(name, '__name__', name)
|
||||
return name in self.__map
|
||||
|
||||
def __getitem__(self, key):
|
||||
@ -455,12 +464,14 @@ class NameSpace(ReadOnly):
|
||||
|
||||
:param key: The name or index of a member, or a slice object.
|
||||
"""
|
||||
key = getattr(key, '__name__', key)
|
||||
if isinstance(key, basestring):
|
||||
return self.__map[key]
|
||||
if type(key) in (int, slice):
|
||||
return self.__members[key]
|
||||
raise TypeError(
|
||||
TYPE_ERROR % ('key', (str, int, slice), key, type(key))
|
||||
TYPE_ERROR % ('key', (str, int, slice, 'object with __name__'),
|
||||
key, type(key))
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -195,7 +195,7 @@ def membername(i):
|
||||
class DummyMember(object):
|
||||
def __init__(self, i):
|
||||
self.i = i
|
||||
self.name = membername(i)
|
||||
self.name = self.__name__ = membername(i)
|
||||
|
||||
|
||||
def gen_members(*indexes):
|
||||
@ -283,8 +283,10 @@ class test_NameSpace(ClassChecker):
|
||||
for i in yes:
|
||||
assert membername(i) in o
|
||||
assert membername(i).upper() not in o
|
||||
assert DummyMember(i) in o
|
||||
for i in no:
|
||||
assert membername(i) not in o
|
||||
assert DummyMember(i) not in o
|
||||
|
||||
def test_getitem(self):
|
||||
"""
|
||||
@ -320,9 +322,15 @@ class test_NameSpace(ClassChecker):
|
||||
assert o[:-4] == members[:-4]
|
||||
assert o[-9:-4] == members[-9:-4]
|
||||
|
||||
# Test retrieval by value
|
||||
for member in members:
|
||||
assert o[DummyMember(member.i)] is member
|
||||
|
||||
# Test that TypeError is raised with wrong type
|
||||
e = raises(TypeError, o.__getitem__, 3.0)
|
||||
assert str(e) == TYPE_ERROR % ('key', (str, int, slice), 3.0, float)
|
||||
assert str(e) == TYPE_ERROR % (
|
||||
'key', (str, int, slice, 'object with __name__'),
|
||||
3.0, float)
|
||||
|
||||
def test_repr(self):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user