mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Remove __public__ and __proxy__ hold-overs from Plugin class
This commit is contained in:
committed by
Rob Crittenden
parent
b7cda86697
commit
1d6cc1bb7b
@@ -32,8 +32,6 @@ class Backend(plugable.Plugin):
|
|||||||
Base class for all backend plugins.
|
Base class for all backend plugins.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__proxy__ = False # Backend plugins are not wrapped in a PluginProxy
|
|
||||||
|
|
||||||
|
|
||||||
class Connectible(Backend):
|
class Connectible(Backend):
|
||||||
"""
|
"""
|
||||||
|
@@ -359,20 +359,6 @@ class Command(HasParam):
|
|||||||
ipalib.frontend.my_command()
|
ipalib.frontend.my_command()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__public__ = frozenset((
|
|
||||||
'get_default',
|
|
||||||
'convert',
|
|
||||||
'normalize',
|
|
||||||
'validate',
|
|
||||||
'execute',
|
|
||||||
'__call__',
|
|
||||||
'args',
|
|
||||||
'options',
|
|
||||||
'params',
|
|
||||||
'params_2_args_options',
|
|
||||||
'args_options_2_params',
|
|
||||||
'output_for_cli',
|
|
||||||
))
|
|
||||||
takes_options = tuple()
|
takes_options = tuple()
|
||||||
takes_args = tuple()
|
takes_args = tuple()
|
||||||
args = None
|
args = None
|
||||||
@@ -875,16 +861,6 @@ class LocalOrRemote(Command):
|
|||||||
|
|
||||||
|
|
||||||
class Object(HasParam):
|
class Object(HasParam):
|
||||||
__public__ = frozenset((
|
|
||||||
'backend',
|
|
||||||
'methods',
|
|
||||||
'properties',
|
|
||||||
'params',
|
|
||||||
'primary_key',
|
|
||||||
'params_minus_pk',
|
|
||||||
'params_minus',
|
|
||||||
'get_dn',
|
|
||||||
))
|
|
||||||
backend = None
|
backend = None
|
||||||
methods = None
|
methods = None
|
||||||
properties = None
|
properties = None
|
||||||
@@ -1011,10 +987,6 @@ class Attribute(Plugin):
|
|||||||
only the base class for the `Method` and `Property` classes. Also see
|
only the base class for the `Method` and `Property` classes. Also see
|
||||||
the `Object` class.
|
the `Object` class.
|
||||||
"""
|
"""
|
||||||
__public__ = frozenset((
|
|
||||||
'obj',
|
|
||||||
'obj_name',
|
|
||||||
))
|
|
||||||
__obj = None
|
__obj = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -1112,7 +1084,6 @@ class Method(Attribute, Command):
|
|||||||
attribute-to-object association. Also see the `Object` and the
|
attribute-to-object association. Also see the `Object` and the
|
||||||
`Property` classes.
|
`Property` classes.
|
||||||
"""
|
"""
|
||||||
__public__ = Attribute.__public__.union(Command.__public__)
|
|
||||||
extra_options_first = False
|
extra_options_first = False
|
||||||
extra_args_first = False
|
extra_args_first = False
|
||||||
|
|
||||||
@@ -1125,12 +1096,6 @@ class Method(Attribute, Command):
|
|||||||
|
|
||||||
|
|
||||||
class Property(Attribute):
|
class Property(Attribute):
|
||||||
__public__ = frozenset((
|
|
||||||
'rules',
|
|
||||||
'param',
|
|
||||||
'type',
|
|
||||||
)).union(Attribute.__public__)
|
|
||||||
|
|
||||||
klass = Str
|
klass = Str
|
||||||
default = None
|
default = None
|
||||||
default_from = None
|
default_from = None
|
||||||
|
@@ -154,11 +154,9 @@ class Plugin(ReadOnly):
|
|||||||
"""
|
"""
|
||||||
Base class for all plugins.
|
Base class for all plugins.
|
||||||
"""
|
"""
|
||||||
__public__ = frozenset()
|
|
||||||
__proxy__ = True
|
|
||||||
__api = None
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.__api = None
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
self.name = cls.__name__
|
self.name = cls.__name__
|
||||||
self.module = cls.__module__
|
self.module = cls.__module__
|
||||||
@@ -189,75 +187,6 @@ class Plugin(ReadOnly):
|
|||||||
return self.__api
|
return self.__api
|
||||||
api = property(__get_api)
|
api = property(__get_api)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def implements(cls, arg):
|
|
||||||
"""
|
|
||||||
Return True if this class implements ``arg``.
|
|
||||||
|
|
||||||
There are three different ways this method can be called:
|
|
||||||
|
|
||||||
With a <type 'str'> argument, e.g.:
|
|
||||||
|
|
||||||
>>> class base(Plugin):
|
|
||||||
... __public__ = frozenset(['attr1', 'attr2'])
|
|
||||||
...
|
|
||||||
>>> base.implements('attr1')
|
|
||||||
True
|
|
||||||
>>> base.implements('attr2')
|
|
||||||
True
|
|
||||||
>>> base.implements('attr3')
|
|
||||||
False
|
|
||||||
|
|
||||||
With a <type 'frozenset'> argument, e.g.:
|
|
||||||
|
|
||||||
With any object that has a `__public__` attribute that is
|
|
||||||
<type 'frozenset'>, e.g.:
|
|
||||||
|
|
||||||
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):
|
|
||||||
"""
|
|
||||||
Return True if ``arg`` implements public interface of this class.
|
|
||||||
|
|
||||||
This classmethod 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.
|
|
||||||
|
|
||||||
Otherwise, returns False.
|
|
||||||
|
|
||||||
Unlike `Plugin.implements`, this returns a concrete answer because
|
|
||||||
the attributes of the subclass are checked.
|
|
||||||
|
|
||||||
:param arg: An instance of or subclass of this class.
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
def finalize(self):
|
def finalize(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
@@ -39,7 +39,6 @@ class test_Backend(ClassChecker):
|
|||||||
|
|
||||||
def test_class(self):
|
def test_class(self):
|
||||||
assert self.cls.__bases__ == (plugable.Plugin,)
|
assert self.cls.__bases__ == (plugable.Plugin,)
|
||||||
assert self.cls.__proxy__ is False
|
|
||||||
|
|
||||||
|
|
||||||
class Disconnect(object):
|
class Disconnect(object):
|
||||||
|
@@ -250,7 +250,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the ``ipalib.frontend.Command.args`` instance attribute.
|
Test the ``ipalib.frontend.Command.args`` instance attribute.
|
||||||
"""
|
"""
|
||||||
assert 'args' in self.cls.__public__ # Public
|
|
||||||
assert self.cls().args is None
|
assert self.cls().args is None
|
||||||
o = self.cls()
|
o = self.cls()
|
||||||
o.finalize()
|
o.finalize()
|
||||||
@@ -300,7 +299,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the ``ipalib.frontend.Command.options`` instance attribute.
|
Test the ``ipalib.frontend.Command.options`` instance attribute.
|
||||||
"""
|
"""
|
||||||
assert 'options' in self.cls.__public__ # Public
|
|
||||||
assert self.cls().options is None
|
assert self.cls().options is None
|
||||||
o = self.cls()
|
o = self.cls()
|
||||||
o.finalize()
|
o.finalize()
|
||||||
@@ -389,7 +387,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.convert` method.
|
Test the `ipalib.frontend.Command.convert` method.
|
||||||
"""
|
"""
|
||||||
assert 'convert' in self.cls.__public__ # Public
|
|
||||||
kw = dict(
|
kw = dict(
|
||||||
option0=u'1.5',
|
option0=u'1.5',
|
||||||
option1=u'7',
|
option1=u'7',
|
||||||
@@ -403,7 +400,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.normalize` method.
|
Test the `ipalib.frontend.Command.normalize` method.
|
||||||
"""
|
"""
|
||||||
assert 'normalize' in self.cls.__public__ # Public
|
|
||||||
kw = dict(
|
kw = dict(
|
||||||
option0=u'OPTION0',
|
option0=u'OPTION0',
|
||||||
option1=u'OPTION1',
|
option1=u'OPTION1',
|
||||||
@@ -417,14 +413,12 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.get_default` method.
|
Test the `ipalib.frontend.Command.get_default` method.
|
||||||
"""
|
"""
|
||||||
assert 'get_default' in self.cls.__public__ # Public
|
|
||||||
# FIXME: Add an updated unit tests for get_default()
|
# FIXME: Add an updated unit tests for get_default()
|
||||||
|
|
||||||
def test_validate(self):
|
def test_validate(self):
|
||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.validate` method.
|
Test the `ipalib.frontend.Command.validate` method.
|
||||||
"""
|
"""
|
||||||
assert 'validate' in self.cls.__public__ # Public
|
|
||||||
|
|
||||||
sub = self.subcls()
|
sub = self.subcls()
|
||||||
sub.finalize()
|
sub.finalize()
|
||||||
@@ -457,7 +451,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.execute` method.
|
Test the `ipalib.frontend.Command.execute` method.
|
||||||
"""
|
"""
|
||||||
assert 'execute' in self.cls.__public__ # Public
|
|
||||||
o = self.cls()
|
o = self.cls()
|
||||||
e = raises(NotImplementedError, o.execute)
|
e = raises(NotImplementedError, o.execute)
|
||||||
assert str(e) == 'Command.execute()'
|
assert str(e) == 'Command.execute()'
|
||||||
@@ -466,7 +459,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.args_options_2_params` method.
|
Test the `ipalib.frontend.Command.args_options_2_params` method.
|
||||||
"""
|
"""
|
||||||
assert 'args_options_2_params' in self.cls.__public__ # Public
|
|
||||||
|
|
||||||
# Test that ZeroArgumentError is raised:
|
# Test that ZeroArgumentError is raised:
|
||||||
o = self.get_instance()
|
o = self.get_instance()
|
||||||
@@ -548,7 +540,6 @@ class test_Command(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Command.params_2_args_options` method.
|
Test the `ipalib.frontend.Command.params_2_args_options` method.
|
||||||
"""
|
"""
|
||||||
assert 'params_2_args_options' in self.cls.__public__ # Public
|
|
||||||
o = self.get_instance(args='one', options='two')
|
o = self.get_instance(args='one', options='two')
|
||||||
assert o.params_2_args_options() == ((None,), {})
|
assert o.params_2_args_options() == ((None,), {})
|
||||||
assert o.params_2_args_options(one=1) == ((1,), {})
|
assert o.params_2_args_options(one=1) == ((1,), {})
|
||||||
@@ -915,7 +906,6 @@ class test_Object(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
Test the `ipalib.frontend.Object.get_dn` method.
|
Test the `ipalib.frontend.Object.get_dn` method.
|
||||||
"""
|
"""
|
||||||
assert 'get_dn' in self.cls.__public__ # Public
|
|
||||||
o = self.cls()
|
o = self.cls()
|
||||||
e = raises(NotImplementedError, o.get_dn, 'primary key')
|
e = raises(NotImplementedError, o.get_dn, 'primary key')
|
||||||
assert str(e) == 'Object.get_dn()'
|
assert str(e) == 'Object.get_dn()'
|
||||||
@@ -1019,8 +1009,6 @@ class test_Method(ClassChecker):
|
|||||||
Test the `ipalib.frontend.Method` class.
|
Test the `ipalib.frontend.Method` class.
|
||||||
"""
|
"""
|
||||||
assert self.cls.__bases__ == (frontend.Attribute, frontend.Command)
|
assert self.cls.__bases__ == (frontend.Attribute, frontend.Command)
|
||||||
assert self.cls.implements(frontend.Command)
|
|
||||||
assert self.cls.implements(frontend.Attribute)
|
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
"""
|
"""
|
||||||
@@ -1032,10 +1020,6 @@ class test_Method(ClassChecker):
|
|||||||
assert o.name == 'user_add'
|
assert o.name == 'user_add'
|
||||||
assert o.obj_name == 'user'
|
assert o.obj_name == 'user'
|
||||||
assert o.attr_name == 'add'
|
assert o.attr_name == 'add'
|
||||||
assert frontend.Command.implemented_by(o)
|
|
||||||
assert frontend.Attribute.implemented_by(o)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class test_Property(ClassChecker):
|
class test_Property(ClassChecker):
|
||||||
|
@@ -209,7 +209,6 @@ class test_Plugin(ClassChecker):
|
|||||||
Test the `ipalib.plugable.Plugin` class.
|
Test the `ipalib.plugable.Plugin` class.
|
||||||
"""
|
"""
|
||||||
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||||
assert self.cls.__public__ == frozenset()
|
|
||||||
assert type(self.cls.api) is property
|
assert type(self.cls.api) is property
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
@@ -251,98 +250,6 @@ class test_Plugin(ClassChecker):
|
|||||||
assert str(e) == \
|
assert str(e) == \
|
||||||
"check.info attribute ('whatever') conflicts with Plugin logger"
|
"check.info attribute ('whatever') conflicts with Plugin logger"
|
||||||
|
|
||||||
def test_implements(self):
|
|
||||||
"""
|
|
||||||
Test the `ipalib.plugable.Plugin.implements` classmethod.
|
|
||||||
"""
|
|
||||||
class example(self.cls):
|
|
||||||
__public__ = frozenset((
|
|
||||||
'some_method',
|
|
||||||
'some_property',
|
|
||||||
))
|
|
||||||
class superset(self.cls):
|
|
||||||
__public__ = frozenset((
|
|
||||||
'some_method',
|
|
||||||
'some_property',
|
|
||||||
'another_property',
|
|
||||||
))
|
|
||||||
class subset(self.cls):
|
|
||||||
__public__ = frozenset((
|
|
||||||
'some_property',
|
|
||||||
))
|
|
||||||
class any_object(object):
|
|
||||||
__public__ = frozenset((
|
|
||||||
'some_method',
|
|
||||||
'some_property',
|
|
||||||
))
|
|
||||||
|
|
||||||
for ex in (example, example()):
|
|
||||||
# Test using str:
|
|
||||||
assert ex.implements('some_method')
|
|
||||||
assert not ex.implements('another_method')
|
|
||||||
|
|
||||||
# Test using frozenset:
|
|
||||||
assert ex.implements(frozenset(['some_method']))
|
|
||||||
assert not ex.implements(
|
|
||||||
frozenset(['some_method', 'another_method'])
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test using another object/class with __public__ frozenset:
|
|
||||||
assert ex.implements(example)
|
|
||||||
assert ex.implements(example())
|
|
||||||
|
|
||||||
assert ex.implements(subset)
|
|
||||||
assert not subset.implements(ex)
|
|
||||||
|
|
||||||
assert not ex.implements(superset)
|
|
||||||
assert superset.implements(ex)
|
|
||||||
|
|
||||||
assert ex.implements(any_object)
|
|
||||||
assert ex.implements(any_object())
|
|
||||||
|
|
||||||
def test_implemented_by(self):
|
|
||||||
"""
|
|
||||||
Test the `ipalib.plugable.Plugin.implemented_by` classmethod.
|
|
||||||
"""
|
|
||||||
class base(self.cls):
|
|
||||||
__public__ = frozenset((
|
|
||||||
'attr0',
|
|
||||||
'attr1',
|
|
||||||
'attr2',
|
|
||||||
))
|
|
||||||
|
|
||||||
class okay(base):
|
|
||||||
def attr0(self):
|
|
||||||
pass
|
|
||||||
def __get_attr1(self):
|
|
||||||
assert False # Make sure property isn't accesed on instance
|
|
||||||
attr1 = property(__get_attr1)
|
|
||||||
attr2 = 'hello world'
|
|
||||||
another_attr = 'whatever'
|
|
||||||
|
|
||||||
class fail(base):
|
|
||||||
def __init__(self):
|
|
||||||
# Check that class, not instance is inspected:
|
|
||||||
self.attr2 = 'hello world'
|
|
||||||
def attr0(self):
|
|
||||||
pass
|
|
||||||
def __get_attr1(self):
|
|
||||||
assert False # Make sure property isn't accesed on instance
|
|
||||||
attr1 = property(__get_attr1)
|
|
||||||
another_attr = 'whatever'
|
|
||||||
|
|
||||||
# Test that AssertionError is raised trying to pass something not
|
|
||||||
# subclass nor instance of base:
|
|
||||||
raises(AssertionError, base.implemented_by, object)
|
|
||||||
|
|
||||||
# Test on subclass with needed attributes:
|
|
||||||
assert base.implemented_by(okay) is True
|
|
||||||
assert base.implemented_by(okay()) is True
|
|
||||||
|
|
||||||
# Test on subclass *without* needed attributes:
|
|
||||||
assert base.implemented_by(fail) is False
|
|
||||||
assert base.implemented_by(fail()) is False
|
|
||||||
|
|
||||||
def test_set_api(self):
|
def test_set_api(self):
|
||||||
"""
|
"""
|
||||||
Test the `ipalib.plugable.Plugin.set_api` method.
|
Test the `ipalib.plugable.Plugin.set_api` method.
|
||||||
@@ -507,18 +414,10 @@ class test_API(ClassChecker):
|
|||||||
|
|
||||||
# Setup the test bases, create the API:
|
# Setup the test bases, create the API:
|
||||||
class base0(plugable.Plugin):
|
class base0(plugable.Plugin):
|
||||||
__public__ = frozenset((
|
|
||||||
'method',
|
|
||||||
))
|
|
||||||
|
|
||||||
def method(self, n):
|
def method(self, n):
|
||||||
return n
|
return n
|
||||||
|
|
||||||
class base1(plugable.Plugin):
|
class base1(plugable.Plugin):
|
||||||
__public__ = frozenset((
|
|
||||||
'method',
|
|
||||||
))
|
|
||||||
|
|
||||||
def method(self, n):
|
def method(self, n):
|
||||||
return n + 1
|
return n + 1
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user