mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-24 07:06:37 -06:00
67: Deleted NameSpace, Proxy; renamed NameSpace2, Proxy2 to NameSpace, Proxy
This commit is contained in:
parent
e63453a858
commit
03bad04e7b
@ -123,52 +123,6 @@ class ReadOnly(object):
|
|||||||
|
|
||||||
|
|
||||||
class Proxy(ReadOnly):
|
class Proxy(ReadOnly):
|
||||||
"""
|
|
||||||
Used to only export certain attributes into the generative API.
|
|
||||||
|
|
||||||
Subclasses must list names of attributes to be proxied in the __slots__
|
|
||||||
class attribute.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = (
|
|
||||||
'__obj',
|
|
||||||
'name',
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, obj, proxy_name=None):
|
|
||||||
"""
|
|
||||||
Proxy attributes on `obj`.
|
|
||||||
"""
|
|
||||||
if proxy_name is None:
|
|
||||||
proxy_name = obj.__class__.__name__
|
|
||||||
check_identifier(proxy_name)
|
|
||||||
object.__setattr__(self, '_Proxy__obj', obj)
|
|
||||||
object.__setattr__(self, 'name', proxy_name)
|
|
||||||
for name in self.__slots__:
|
|
||||||
attr = getattr(obj, name)
|
|
||||||
if callable(attr):
|
|
||||||
object.__setattr__(self, name, attr)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return '%s(%r)' % (self.__class__.__name__, self.__obj)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return to_cli(self.name)
|
|
||||||
|
|
||||||
def _clone(self, new_name):
|
|
||||||
return self.__class__(self.__obj, proxy_name=new_name)
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
if name in self.__slots__:
|
|
||||||
return getattr(self.__obj, name)
|
|
||||||
raise AttributeError('attribute %r not in %s.__slots__' % (
|
|
||||||
name,
|
|
||||||
self.__class__.__name__
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Proxy2(ReadOnly):
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
'base',
|
'base',
|
||||||
'name',
|
'name',
|
||||||
@ -180,7 +134,7 @@ class Proxy2(ReadOnly):
|
|||||||
if not isinstance(target, base):
|
if not isinstance(target, base):
|
||||||
raise ValueError('arg2 must be instance of arg1, got %r' % target)
|
raise ValueError('arg2 must be instance of arg1, got %r' % target)
|
||||||
object.__setattr__(self, 'base', base)
|
object.__setattr__(self, 'base', base)
|
||||||
object.__setattr__(self, '_Proxy2__target', target)
|
object.__setattr__(self, '_Proxy__target', target)
|
||||||
|
|
||||||
# Check base.public
|
# Check base.public
|
||||||
assert type(self.base.public) is frozenset
|
assert type(self.base.public) is frozenset
|
||||||
@ -206,8 +160,11 @@ class Proxy2(ReadOnly):
|
|||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
return self['__call__'](*args, **kw)
|
return self['__call__'](*args, **kw)
|
||||||
|
|
||||||
|
def _clone(self, name_attr):
|
||||||
|
return self.__class__(self.base, self.__target, name_attr)
|
||||||
|
|
||||||
class NameSpace2(ReadOnly):
|
|
||||||
|
class NameSpace(ReadOnly):
|
||||||
"""
|
"""
|
||||||
A read-only namespace of (key, value) pairs that can be accessed
|
A read-only namespace of (key, value) pairs that can be accessed
|
||||||
both as instance attributes and as dictionary items.
|
both as instance attributes and as dictionary items.
|
||||||
@ -215,12 +172,12 @@ class NameSpace2(ReadOnly):
|
|||||||
|
|
||||||
def __init__(self, proxies):
|
def __init__(self, proxies):
|
||||||
"""
|
"""
|
||||||
NameSpace2
|
NameSpace
|
||||||
"""
|
"""
|
||||||
object.__setattr__(self, '_NameSpace2__proxies', tuple(proxies))
|
object.__setattr__(self, '_NameSpace__proxies', tuple(proxies))
|
||||||
object.__setattr__(self, '_NameSpace2__d', dict())
|
object.__setattr__(self, '_NameSpace__d', dict())
|
||||||
for proxy in self.__proxies:
|
for proxy in self.__proxies:
|
||||||
assert isinstance(proxy, Proxy2)
|
assert isinstance(proxy, Proxy)
|
||||||
assert proxy.name not in self.__d
|
assert proxy.name not in self.__d
|
||||||
self.__d[proxy.name] = proxy
|
self.__d[proxy.name] = proxy
|
||||||
assert not hasattr(self, proxy.name)
|
assert not hasattr(self, proxy.name)
|
||||||
@ -258,68 +215,6 @@ class NameSpace2(ReadOnly):
|
|||||||
return '%s(<%d proxies>)' % (self.__class__.__name__, len(self))
|
return '%s(<%d proxies>)' % (self.__class__.__name__, len(self))
|
||||||
|
|
||||||
|
|
||||||
class NameSpace(ReadOnly):
|
|
||||||
"""
|
|
||||||
A read-only namespace of (key, value) pairs that can be accessed
|
|
||||||
both as instance attributes and as dictionary items.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, items):
|
|
||||||
"""
|
|
||||||
`items` should be an iterable providing the members of this
|
|
||||||
NameSpace.
|
|
||||||
"""
|
|
||||||
object.__setattr__(self, '_NameSpace__items', tuple(items))
|
|
||||||
|
|
||||||
# dict mapping Python name to item:
|
|
||||||
object.__setattr__(self, '_NameSpace__pname', {})
|
|
||||||
|
|
||||||
# dict mapping human-readibly name to item:
|
|
||||||
object.__setattr__(self, '_NameSpace__hname', {})
|
|
||||||
|
|
||||||
for item in self.__items:
|
|
||||||
object.__setattr__(self, item.name, item)
|
|
||||||
for (key, d) in [
|
|
||||||
(item.name, self.__pname),
|
|
||||||
(str(item), self.__hname),
|
|
||||||
]:
|
|
||||||
assert key not in d
|
|
||||||
d[key] = item
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
"""
|
|
||||||
Iterates through the items in this NameSpace in the same order they
|
|
||||||
were passed in the contructor.
|
|
||||||
"""
|
|
||||||
for item in self.__items:
|
|
||||||
yield item
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
"""
|
|
||||||
Returns number of items in this NameSpace.
|
|
||||||
"""
|
|
||||||
return len(self.__items)
|
|
||||||
|
|
||||||
def __contains__(self, key):
|
|
||||||
"""
|
|
||||||
Returns True if an item with pname or hname `key` is in this
|
|
||||||
NameSpace.
|
|
||||||
"""
|
|
||||||
return (key in self.__pname) or (key in self.__hname)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
"""
|
|
||||||
Returns item with pname or hname `key`; otherwise raises KeyError.
|
|
||||||
"""
|
|
||||||
if key in self.__pname:
|
|
||||||
return self.__pname[key]
|
|
||||||
if key in self.__hname:
|
|
||||||
return self.__hname[key]
|
|
||||||
raise KeyError('NameSpace has no item for key %r' % key)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return '%s(<%d proxies>)' % (self.__class__.__name__, len(self))
|
|
||||||
|
|
||||||
|
|
||||||
class Registrar(object):
|
class Registrar(object):
|
||||||
def __init__(self, *allowed):
|
def __init__(self, *allowed):
|
||||||
|
@ -105,71 +105,7 @@ def test_ReadOnly():
|
|||||||
|
|
||||||
|
|
||||||
def test_Proxy():
|
def test_Proxy():
|
||||||
assert issubclass(plugable.Proxy, plugable.ReadOnly)
|
cls = plugable.Proxy
|
||||||
|
|
||||||
class CommandProxy(plugable.Proxy):
|
|
||||||
__slots__ = (
|
|
||||||
'validate',
|
|
||||||
'__call__',
|
|
||||||
)
|
|
||||||
|
|
||||||
class do_something(object):
|
|
||||||
def __repr__(self):
|
|
||||||
return '<my repr>'
|
|
||||||
|
|
||||||
def __call__(self, arg):
|
|
||||||
return arg + 1
|
|
||||||
|
|
||||||
def validate(self, arg):
|
|
||||||
return arg + 2
|
|
||||||
|
|
||||||
def not_public(self, arg):
|
|
||||||
return arg + 3
|
|
||||||
|
|
||||||
# Test basic Proxy functionality
|
|
||||||
i = do_something()
|
|
||||||
p = CommandProxy(i)
|
|
||||||
assert '__dict__' not in dir(p)
|
|
||||||
assert p.name == 'do_something'
|
|
||||||
assert str(p) == 'do-something'
|
|
||||||
assert repr(p) == 'CommandProxy(<my repr>)'
|
|
||||||
assert p(1) == 2
|
|
||||||
assert p.validate(1) == 3
|
|
||||||
|
|
||||||
# Test that proxy_name can be overriden:
|
|
||||||
i = do_something()
|
|
||||||
p = CommandProxy(i, proxy_name='user_add')
|
|
||||||
assert '__dict__' not in dir(p)
|
|
||||||
assert p.name == 'user_add'
|
|
||||||
assert str(p) == 'user-add'
|
|
||||||
assert repr(p) == 'CommandProxy(<my repr>)'
|
|
||||||
assert p(1) == 2
|
|
||||||
assert p.validate(1) == 3
|
|
||||||
|
|
||||||
# Test that attributes not listed in __slots__ are not present:
|
|
||||||
name = 'not_public'
|
|
||||||
i = do_something()
|
|
||||||
p = CommandProxy(i)
|
|
||||||
assert getattr(i, name)(1) == 4
|
|
||||||
raises(AttributeError, getattr, p, name)
|
|
||||||
|
|
||||||
# Test that attributes are read-only:
|
|
||||||
name = 'validate'
|
|
||||||
i = do_something()
|
|
||||||
p = CommandProxy(i)
|
|
||||||
assert getattr(p, name)(1) == 3
|
|
||||||
assert read_only(p, name)(1) == 3
|
|
||||||
|
|
||||||
# Test cloning:
|
|
||||||
i = do_something()
|
|
||||||
p = CommandProxy(i)
|
|
||||||
c = p._clone('do_a_thing')
|
|
||||||
assert isinstance(c, CommandProxy)
|
|
||||||
assert c.name == 'do_a_thing'
|
|
||||||
|
|
||||||
|
|
||||||
def test_Proxy2():
|
|
||||||
cls = plugable.Proxy2
|
|
||||||
assert issubclass(cls, plugable.ReadOnly)
|
assert issubclass(cls, plugable.ReadOnly)
|
||||||
|
|
||||||
# Setup:
|
# Setup:
|
||||||
@ -209,7 +145,7 @@ def test_Proxy2():
|
|||||||
i = plugin()
|
i = plugin()
|
||||||
p = cls(base, i)
|
p = cls(base, i)
|
||||||
assert read_only(p, 'base') is base
|
assert read_only(p, 'base') is base
|
||||||
assert read_only(p, 'name') is 'user_add'
|
assert read_only(p, 'name') == 'user_add'
|
||||||
assert list(p) == sorted(base.public)
|
assert list(p) == sorted(base.public)
|
||||||
|
|
||||||
# Test normal methods:
|
# Test normal methods:
|
||||||
@ -230,11 +166,22 @@ def test_Proxy2():
|
|||||||
|
|
||||||
# Test name_attr='name' kw arg
|
# Test name_attr='name' kw arg
|
||||||
i = plugin()
|
i = plugin()
|
||||||
|
p = cls(base, i, 'attr_name')
|
||||||
|
assert read_only(p, 'name') == 'add'
|
||||||
|
|
||||||
|
# Test _clone():
|
||||||
|
i = plugin()
|
||||||
p = cls(base, i)
|
p = cls(base, i)
|
||||||
|
assert read_only(p, 'name') == 'user_add'
|
||||||
|
c = p._clone('attr_name')
|
||||||
|
assert isinstance(c, cls)
|
||||||
|
assert read_only(c, 'name') == 'add'
|
||||||
|
assert c is not p
|
||||||
|
assert c('whoever') == p('whoever')
|
||||||
|
|
||||||
|
|
||||||
def test_NameSpace2():
|
def test_NameSpace():
|
||||||
cls = plugable.NameSpace2
|
cls = plugable.NameSpace
|
||||||
assert issubclass(cls, plugable.ReadOnly)
|
assert issubclass(cls, plugable.ReadOnly)
|
||||||
|
|
||||||
class base(object):
|
class base(object):
|
||||||
@ -254,7 +201,7 @@ def test_NameSpace2():
|
|||||||
|
|
||||||
def get_proxies(n):
|
def get_proxies(n):
|
||||||
for i in xrange(n):
|
for i in xrange(n):
|
||||||
yield plugable.Proxy2(base, plugin(get_name(i)))
|
yield plugable.Proxy(base, plugin(get_name(i)))
|
||||||
|
|
||||||
cnt = 20
|
cnt = 20
|
||||||
ns = cls(get_proxies(cnt))
|
ns = cls(get_proxies(cnt))
|
||||||
@ -265,7 +212,7 @@ def test_NameSpace2():
|
|||||||
# Test __iter__
|
# Test __iter__
|
||||||
i = None
|
i = None
|
||||||
for (i, proxy) in enumerate(ns):
|
for (i, proxy) in enumerate(ns):
|
||||||
assert type(proxy) is plugable.Proxy2
|
assert type(proxy) is plugable.Proxy
|
||||||
assert proxy.name == get_name(i)
|
assert proxy.name == get_name(i)
|
||||||
assert i == cnt - 1
|
assert i == cnt - 1
|
||||||
|
|
||||||
@ -276,7 +223,7 @@ def test_NameSpace2():
|
|||||||
assert name in ns
|
assert name in ns
|
||||||
proxy = ns[name]
|
proxy = ns[name]
|
||||||
assert proxy.name == name
|
assert proxy.name == name
|
||||||
assert type(proxy) is plugable.Proxy2
|
assert type(proxy) is plugable.Proxy
|
||||||
assert proxy in proxies
|
assert proxy in proxies
|
||||||
assert read_only(ns, name) is proxy
|
assert read_only(ns, name) is proxy
|
||||||
|
|
||||||
@ -291,8 +238,6 @@ def test_NameSpace2():
|
|||||||
no_set(ns, name)
|
no_set(ns, name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_Registrar():
|
def test_Registrar():
|
||||||
class Base1(object):
|
class Base1(object):
|
||||||
pass
|
pass
|
||||||
@ -404,72 +349,6 @@ def test_Registrar():
|
|||||||
assert r[base.__name__] == d
|
assert r[base.__name__] == d
|
||||||
|
|
||||||
|
|
||||||
def test_NameSpace():
|
|
||||||
assert issubclass(plugable.NameSpace, plugable.ReadOnly)
|
|
||||||
|
|
||||||
class DummyProxy(object):
|
|
||||||
def __init__(self, name):
|
|
||||||
self.__name = name
|
|
||||||
|
|
||||||
def __get_name(self):
|
|
||||||
return self.__name
|
|
||||||
name = property(__get_name)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return plugable.to_cli(self.__name)
|
|
||||||
|
|
||||||
def get_name(i):
|
|
||||||
return 'noun_verb%d' % i
|
|
||||||
|
|
||||||
def get_cli(i):
|
|
||||||
return 'noun-verb%d' % i
|
|
||||||
|
|
||||||
def get_proxies(n):
|
|
||||||
for i in xrange(n):
|
|
||||||
yield DummyProxy(get_name(i))
|
|
||||||
|
|
||||||
cnt = 20
|
|
||||||
ns = plugable.NameSpace(get_proxies(cnt))
|
|
||||||
|
|
||||||
# Test __len__
|
|
||||||
assert len(ns) == cnt
|
|
||||||
|
|
||||||
# Test __iter__
|
|
||||||
i = None
|
|
||||||
for (i, item) in enumerate(ns):
|
|
||||||
assert type(item) is DummyProxy
|
|
||||||
assert item.name == get_name(i)
|
|
||||||
assert str(item) == get_cli(i)
|
|
||||||
assert i == cnt - 1
|
|
||||||
|
|
||||||
# Test __contains__, __getitem__, getattr():
|
|
||||||
for i in xrange(cnt):
|
|
||||||
name = get_name(i)
|
|
||||||
cli = get_cli(i)
|
|
||||||
assert name in ns
|
|
||||||
assert cli in ns
|
|
||||||
item = ns[name]
|
|
||||||
assert isinstance(item, DummyProxy)
|
|
||||||
assert item.name == name
|
|
||||||
assert str(item) == cli
|
|
||||||
assert ns[name] is item
|
|
||||||
assert ns[cli] is item
|
|
||||||
assert read_only(ns, name) is item
|
|
||||||
|
|
||||||
# Test dir():
|
|
||||||
assert set(get_name(i) for i in xrange(cnt)).issubset(set(dir(ns)))
|
|
||||||
|
|
||||||
# Test that KeyError, AttributeError is raised:
|
|
||||||
name = get_name(cnt)
|
|
||||||
cli = get_cli(cnt)
|
|
||||||
assert name not in ns
|
|
||||||
assert cli not in ns
|
|
||||||
raises(KeyError, getitem, ns, name)
|
|
||||||
raises(KeyError, getitem, ns, cli)
|
|
||||||
raises(AttributeError, getattr, ns, name)
|
|
||||||
no_set(ns, name)
|
|
||||||
|
|
||||||
|
|
||||||
def test_API():
|
def test_API():
|
||||||
assert issubclass(plugable.API, plugable.ReadOnly)
|
assert issubclass(plugable.API, plugable.ReadOnly)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user