summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/__init__.py24
-rw-r--r--ipalib/frontend.py8
-rw-r--r--ipalib/plugable.py67
-rwxr-xr-xmake-test2
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
"""
diff --git a/make-test b/make-test
index 08cdae7e..46456d6d 100755
--- a/make-test
+++ b/make-test
@@ -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