mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 15:40:01 -06:00
120: Moved ProxyTarget below Proxy to emphasize relationship with Plugin; added docstrings for ProxyTarget.implements() and implemented_by() classmethods; fixed typo in Plugin.finalize() docstring
This commit is contained in:
parent
8640523632
commit
f767543fe7
@ -112,42 +112,6 @@ class ReadOnly(object):
|
|||||||
return object.__delattr__(self, name)
|
return object.__delattr__(self, name)
|
||||||
|
|
||||||
|
|
||||||
class ProxyTarget(ReadOnly):
|
|
||||||
__public__ = frozenset()
|
|
||||||
|
|
||||||
def __get_name(self):
|
|
||||||
"""
|
|
||||||
Convenience property to return the class name.
|
|
||||||
"""
|
|
||||||
return self.__class__.__name__
|
|
||||||
name = property(__get_name)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def implements(cls, arg):
|
|
||||||
assert type(cls.__public__) is frozenset
|
|
||||||
if isinstance(arg, str):
|
|
||||||
return arg in cls.__public__
|
|
||||||
if type(getattr(arg, '__public__', None)) is frozenset:
|
|
||||||
return cls.__public__.issuperset(arg.__public__)
|
|
||||||
if type(arg) is frozenset:
|
|
||||||
return cls.__public__.issuperset(arg)
|
|
||||||
raise TypeError(
|
|
||||||
"must be str, frozenset, or have frozenset '__public__' attribute"
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def implemented_by(cls, arg):
|
|
||||||
if inspect.isclass(arg):
|
|
||||||
subclass = arg
|
|
||||||
else:
|
|
||||||
subclass = arg.__class__
|
|
||||||
assert issubclass(subclass, cls), 'must be subclass of %r' % cls
|
|
||||||
for name in cls.__public__:
|
|
||||||
if not hasattr(subclass, name):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class Proxy(ReadOnly):
|
class Proxy(ReadOnly):
|
||||||
"""
|
"""
|
||||||
Allows access to only certain attributes on its target object (a
|
Allows access to only certain attributes on its target object (a
|
||||||
@ -251,6 +215,86 @@ class Proxy(ReadOnly):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyTarget(ReadOnly):
|
||||||
|
__public__ = frozenset()
|
||||||
|
|
||||||
|
def __get_name(self):
|
||||||
|
"""
|
||||||
|
Convenience property to return the class name.
|
||||||
|
"""
|
||||||
|
return self.__class__.__name__
|
||||||
|
name = property(__get_name)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def implements(cls, arg):
|
||||||
|
"""
|
||||||
|
Returns True if this cls.__public__ frozenset contains `arg`;
|
||||||
|
returns False otherwise.
|
||||||
|
|
||||||
|
There are three different ways this can be called:
|
||||||
|
|
||||||
|
1. With a <type 'str'> argument, e.g.:
|
||||||
|
|
||||||
|
>>> class base(ProxyTarget):
|
||||||
|
>>> __public__ = frozenset(['some_attr', 'another_attr'])
|
||||||
|
>>> base.implements('some_attr')
|
||||||
|
True
|
||||||
|
>>> base.implements('an_unknown_attribute')
|
||||||
|
False
|
||||||
|
|
||||||
|
2. With a <type 'frozenset'> argument, e.g.:
|
||||||
|
|
||||||
|
>>> base.implements(frozenset(['some_attr']))
|
||||||
|
True
|
||||||
|
>>> base.implements(frozenset(['some_attr', 'an_unknown_attribute']))
|
||||||
|
False
|
||||||
|
|
||||||
|
3. With any object that has a `__public__` attribute that is
|
||||||
|
<type 'frozenset'>, e.g.:
|
||||||
|
|
||||||
|
>>> class whatever(object):
|
||||||
|
>>> __public__ = frozenset(['another_attr'])
|
||||||
|
>>> base.implements(whatever)
|
||||||
|
True
|
||||||
|
|
||||||
|
Unlike ProxyTarget.implemented_by(), this returns an abstract answer
|
||||||
|
because only the __public__ frozenset is checked... a ProxyTarget
|
||||||
|
need not itself have attributes for all names in __public__
|
||||||
|
(subclasses might provide them).
|
||||||
|
"""
|
||||||
|
assert type(cls.__public__) is frozenset
|
||||||
|
if isinstance(arg, str):
|
||||||
|
return arg in cls.__public__
|
||||||
|
if type(getattr(arg, '__public__', None)) is frozenset:
|
||||||
|
return cls.__public__.issuperset(arg.__public__)
|
||||||
|
if type(arg) is frozenset:
|
||||||
|
return cls.__public__.issuperset(arg)
|
||||||
|
raise TypeError(
|
||||||
|
"must be str, frozenset, or have frozenset '__public__' attribute"
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def implemented_by(cls, arg):
|
||||||
|
"""
|
||||||
|
Returns True if (1) `arg` is an instance of or subclass of this class,
|
||||||
|
and (2) `arg` (or `arg.__class__` if instance) has an attribute for
|
||||||
|
each name in this class's __public__ frozenset; returns False
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
Unlike ProxyTarget.implements(), this returns a concrete answer
|
||||||
|
because the attributes of the subclass are checked.
|
||||||
|
"""
|
||||||
|
if inspect.isclass(arg):
|
||||||
|
subclass = arg
|
||||||
|
else:
|
||||||
|
subclass = arg.__class__
|
||||||
|
assert issubclass(subclass, cls), 'must be subclass of %r' % cls
|
||||||
|
for name in cls.__public__:
|
||||||
|
if not hasattr(subclass, name):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Plugin(ProxyTarget):
|
class Plugin(ProxyTarget):
|
||||||
"""
|
"""
|
||||||
Base class for all plugins.
|
Base class for all plugins.
|
||||||
@ -270,7 +314,7 @@ class Plugin(ProxyTarget):
|
|||||||
"""
|
"""
|
||||||
After all the plugins are instantiated, the plugable.API calls this
|
After all the plugins are instantiated, the plugable.API calls this
|
||||||
method, passing itself as the only argument. This is where plugins
|
method, passing itself as the only argument. This is where plugins
|
||||||
should check that other plugins they depend upon have actually be
|
should check that other plugins they depend upon have actually been
|
||||||
loaded.
|
loaded.
|
||||||
"""
|
"""
|
||||||
assert self.__api is None, 'finalize() can only be called once'
|
assert self.__api is None, 'finalize() can only be called once'
|
||||||
|
Loading…
Reference in New Issue
Block a user