mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
make-test now runs doctests also; fixed several broken doctests
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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((
|
||||
|
||||
@@ -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('an_unknown_attribute')
|
||||
>>> base.implements('attr2')
|
||||
True
|
||||
>>> 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
|
||||
"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user