diff options
-rw-r--r-- | ipalib/__init__.py | 24 | ||||
-rw-r--r-- | ipalib/frontend.py | 8 | ||||
-rw-r--r-- | ipalib/plugable.py | 67 | ||||
-rwxr-xr-x | make-test | 2 |
4 files changed, 36 insertions, 65 deletions
diff --git a/ipalib/__init__.py b/ipalib/__init__.py index 92544e10..4593e581 100644 --- a/ipalib/__init__.py +++ b/ipalib/__init__.py @@ -27,30 +27,6 @@ To learn about the ``ipalib`` library, you should read the code in this order: 2. Learn about the base classes for frontend plugins in `frontend`. 3. Learn about the core plugin framework in `plugable`. - -Here is a short console example on using the plugable API: - ->>> from ipalib import api ->>> list(api.register) # Plugins must subclass from one of these base classes: -['Command', 'Method', 'Object', 'Property'] ->>> 'user_add' in api.register.Command # Has 'user_add' been registered? -False ->>> import ipalib.load_plugins # This causes all plugins to be loaded ->>> 'user_add' in api.register.Command # Yes, 'user_add' has been registered: -True ->>> list(api) # API is empty till finalize() is called: -[] ->>> api.finalize() # Instantiates plugins, builds API namespaces: ->>> list(api) # Lists the namespaces in the API: -['Command', 'Method', 'Object', 'Property'] ->>> 'user_add' in api.Command # Yes, the 'user_add' command exists: -True ->>> api['Command'] is api.Command # Access as dict item or as attribute: -True ->>> list(api.Command) # List available commands: -['discover', 'group_add', 'group_del', 'group_find', 'group_mod', 'krbtest', 'service_add', 'service_del', 'service_find', 'service_mod', 'user_add', 'user_del', 'user_find', 'user_mod'] ->>> list(api.Command.user_add) # List public methods for user_add: -['__call__', 'default', 'execute', 'get_doc', 'normalize', 'options', 'validate'] """ import plugable diff --git a/ipalib/frontend.py b/ipalib/frontend.py index bf3eb7f2..2c34b972 100644 --- a/ipalib/frontend.py +++ b/ipalib/frontend.py @@ -63,8 +63,8 @@ class DefaultFrom(plugable.ReadOnly): The callback is available through the ``DefaultFrom.callback`` instance attribute, like this: - >>> login.callback - <function <lambda> at 0x7fdd225cd7d0> + >>> login.callback # doctest:+ELLIPSIS + <function <lambda> at 0x...> >>> login.callback.func_code.co_varnames # The keys ('first', 'last') @@ -473,8 +473,8 @@ class Command(plugable.Plugin): >>> api.finalize() >>> list(api.Command) ['my_command'] - >>> api.Command.my_command - PluginProxy(Command, __main__.my_command()) + >>> api.Command.my_command # doctest:+ELLIPSIS + PluginProxy(Command, ...my_command()) """ __public__ = frozenset(( diff --git a/ipalib/plugable.py b/ipalib/plugable.py index 98aa4172..2a1bdb62 100644 --- a/ipalib/plugable.py +++ b/ipalib/plugable.py @@ -208,14 +208,15 @@ class DictProxy(SetProxy): class MagicDict(DictProxy): """ - A read-only mapping container whose values can also be accessed as - attributes. + A mapping container whose values can be accessed as attributes. - For example, assuming ``magic`` is a MagicDict instance that contains the - key ``name``, you could do this: + For example: - >>> magic[name] is getattr(magic, name) - True + >>> magic = MagicDict({'the_key': 'the value'}) + >>> magic['the_key'] + 'the value' + >>> magic.the_key + 'the value' This container acts as a proxy to an actual mapping object (a dict) that is passed to the constructor. To the extent possible in Python, this @@ -270,35 +271,27 @@ class Plugin(ReadOnly): @classmethod def implements(cls, arg): """ - Returns True if this cls.__public__ frozenset contains `arg`; - returns False otherwise. + Return True if class implements ``arg``. - There are three different ways this can be called: + There are three different ways this method can be called: With a <type 'str'> argument, e.g.: - >>> class base(ProxyTarget): - >>> __public__ = frozenset(['some_attr', 'another_attr']) - >>> base.implements('some_attr') + >>> class base(Plugin): + ... __public__ = frozenset(['attr1', 'attr2']) + ... + >>> base.implements('attr1') + True + >>> base.implements('attr2') True - >>> base.implements('an_unknown_attribute') + >>> base.implements('attr3') False With a <type 'frozenset'> argument, e.g.: - >>> base.implements(frozenset(['some_attr'])) - True - >>> base.implements(frozenset(['some_attr', 'an_unknown_attribute'])) - False - 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__ @@ -493,34 +486,36 @@ class NameSpace(ReadOnly): classes or instances, and of any type. The members can be accessed as attributes on the NameSpace instance or - through a dictionary interface. For example, assuming ``obj`` is a member - in the NameSpace instance ``namespace``, you could do this: + through a dictionary interface. For example: - >>> obj is getattr(namespace, obj.name) # As attribute + >>> class obj(object): + ... name = 'my_obj' + ... + >>> namespace = NameSpace([obj]) + >>> obj is getattr(namespace, 'my_obj') # As attribute True - >>> obj is namespace[obj.name] # As dictionary item + >>> obj is namespace['my_obj'] # As dictionary item True Here is a more detailed example: >>> class member(object): ... def __init__(self, i): + ... self.i = i ... self.name = 'member_%d' % i + ... def __repr__(self): + ... return 'member(%d)' % self.i ... - >>> def get_members(cnt): - ... for i in xrange(cnt): - ... yield member(i) - ... - >>> namespace = NameSpace(get_members(2)) + >>> namespace = NameSpace(member(i) for i in xrange(3)) >>> namespace.member_0 is namespace['member_0'] True >>> len(namespace) # Returns the number of members in namespace - 2 + 3 >>> list(namespace) # As iterable, iterates through the member names - ['member_0', 'member_1'] + ['member_0', 'member_1', 'member_2'] >>> list(namespace()) # Calling a NameSpace iterates through the members - [<__main__.member object at 0x836710>, <__main__.member object at 0x836750>] - >>> 'member_1' in namespace # NameSpace.__contains__() + [member(0), member(1), member(2)] + >>> 'member_1' in namespace # Does namespace contain 'member_1'? True """ @@ -10,7 +10,7 @@ do if [[ -f $executable ]]; then echo "[ $name: Starting tests... ]" ((runs += 1)) - if $executable /usr/bin/nosetests -v + if $executable /usr/bin/nosetests -v --with-doctest then echo "[ $name: Tests OK ]" else |