diff --git a/ipalib/cli.py b/ipalib/cli.py index f7b198012..7ae8ae3bc 100644 --- a/ipalib/cli.py +++ b/ipalib/cli.py @@ -63,7 +63,7 @@ class CLI(object): for cmd in self.api.cmd: print ' %s %s' % ( to_cli(cmd.name).ljust(self.mcl), - cmd.get_doc(_), + cmd.doc, ) def __contains__(self, key): diff --git a/ipalib/plugable.py b/ipalib/plugable.py index 89eb423b1..fbe5e638f 100644 --- a/ipalib/plugable.py +++ b/ipalib/plugable.py @@ -128,6 +128,7 @@ class Proxy(ReadOnly): '__name_attr', '__public__', 'name', + 'doc', ) def __init__(self, base, target, name_attr='name'): @@ -146,10 +147,11 @@ class Proxy(ReadOnly): self.__target = target self.__name_attr = name_attr self.__public__ = base.__public__ - assert type(self.__public__) is frozenset self.name = getattr(target, name_attr) - check_identifier(self.name) + self.doc = target.doc self.__lock__() + assert type(self.__public__) is frozenset + check_identifier(self.name) def implements(self, arg): """ @@ -225,6 +227,13 @@ class ProxyTarget(ReadOnly): return self.__class__.__name__ name = property(__get_name) + def __get_doc(self): + """ + Convenience property to return the class docstring. + """ + return self.__class__.__doc__ + doc = property(__get_doc) + @classmethod def implements(cls, arg): """ diff --git a/ipalib/plugins/example.py b/ipalib/plugins/example.py index caf963d2a..770ed33b8 100644 --- a/ipalib/plugins/example.py +++ b/ipalib/plugins/example.py @@ -28,52 +28,43 @@ from ipalib.api import api # Hypothetical functional commands (not associated with any object): class krbtest(public.cmd): - def get_doc(self, _): - return _('test your Kerberos ticket') + 'test your Kerberos ticket' api.register(krbtest) class discover(public.cmd): - def get_doc(self, _): - return _('discover IPA servers on network') + 'discover IPA servers on network' api.register(discover) # Register some methods for the 'user' object: class user_add(public.mthd): - def get_doc(self, _): - return _('add new user') + 'add new user' api.register(user_add) class user_del(public.mthd): - def get_doc(self, _): - return _('delete existing user') + 'delete existing user' api.register(user_del) class user_mod(public.mthd): - def get_doc(self, _): - return _('edit existing user') + 'edit existing user' api.register(user_mod) class user_find(public.mthd): - def get_doc(self, _): - return _('search for users') + 'search for users' api.register(user_find) # Register some properties for the 'user' object: class user_givenname(public.prop): - def get_doc(self, _): - return _('user first name') + 'user first name' api.register(user_givenname) class user_sn(public.prop): - def get_doc(self, _): - return _('user last name') + 'user last name' api.register(user_sn) class user_login(public.prop): - def get_doc(self, _): - return _('user login') + 'user login' def default(self, **kw): givenname = kw.get('givenname', None) sn = kw.get('sn', None) @@ -83,8 +74,7 @@ class user_login(public.prop): api.register(user_login) class user_initials(public.prop): - def get_doc(self, _): - return _('user initials') + 'user initials' def default(self, **kw): givenname = kw.get('givenname', None) sn = kw.get('sn', None) @@ -96,61 +86,50 @@ api.register(user_initials) # Register some methods for the 'group' object: class group_add(public.mthd): - def get_doc(self, _): - return _('add new group') + 'add new group' api.register(group_add) class group_del(public.mthd): - def get_doc(self, _): - return _('delete existing group') + 'delete existing group' api.register(group_del) class group_mod(public.mthd): - def get_doc(self, _): - return _('edit existing group') + 'edit existing group' api.register(group_mod) class group_find(public.mthd): - def get_doc(self, _): - return _('search for groups') + 'search for groups' api.register(group_find) # Register some methods for the 'service' object class service_add(public.mthd): - def get_doc(self, _): - return _('add new service') + 'add new service' api.register(service_add) class service_del(public.mthd): - def get_doc(self, _): - return _('delete existing service') + 'delete existing service' api.register(service_del) class service_mod(public.mthd): - def get_doc(self, _): - return _('edit existing service') + 'edit existing service' api.register(service_mod) class service_find(public.mthd): - def get_doc(self, _): - return _('search for services') + 'search for services' api.register(service_find) # And to emphasis that the registration order doesn't matter, # we'll register the objects last: class group(public.obj): - def get_doc(self, _): - return _('') + 'group object' api.register(group) class service(public.obj): - def get_doc(self, _): - return _('') + 'service object' api.register(service) class user(public.obj): - def get_doc(self, _): - return _('') + 'user object' api.register(user) diff --git a/ipalib/public.py b/ipalib/public.py index 798b258c2..9677358ff 100644 --- a/ipalib/public.py +++ b/ipalib/public.py @@ -45,7 +45,6 @@ class option(plugable.Plugin): """ __public__ = frozenset(( - 'get_doc', 'normalize', 'default', 'validate', diff --git a/ipalib/tests/test_plugable.py b/ipalib/tests/test_plugable.py index 89bb948e4..ba90c2034 100644 --- a/ipalib/tests/test_plugable.py +++ b/ipalib/tests/test_plugable.py @@ -126,7 +126,7 @@ class test_ProxyTarget(ClassChecker): def test_name(self): """ - Test the `name` property. + Tests the `name` property. """ assert read_only(self.cls(), 'name') == 'ProxyTarget' @@ -134,9 +134,17 @@ class test_ProxyTarget(ClassChecker): pass assert read_only(some_subclass(), 'name') == 'some_subclass' + def test_doc(self): + """ + Tests the `doc` property. + """ + class some_subclass(self.cls): + 'here is the doc string' + assert read_only(some_subclass(), 'doc') == 'here is the doc string' + def test_implements(self): """ - Test the `implements` classmethod. + Tests the `implements` classmethod. """ class example(self.cls): __public__ = frozenset(( @@ -263,6 +271,7 @@ class test_Proxy(ClassChecker): class plugin(base): name = 'user_add' attr_name = 'add' + doc = 'add a new user' # Test that TypeError is raised when base is not a class: raises(TypeError, self.cls, base(), None) @@ -273,7 +282,8 @@ class test_Proxy(ClassChecker): # Test with correct arguments: i = plugin() p = self.cls(base, i) - assert read_only(p, 'name') == 'user_add' + assert read_only(p, 'name') is plugin.name + assert read_only(p, 'doc') == plugin.doc assert list(p) == sorted(base.__public__) # Test normal methods: @@ -304,6 +314,7 @@ class test_Proxy(ClassChecker): class base(object): __public__ = frozenset() name = 'base' + doc = 'doc' @classmethod def implements(cls, arg): return arg + 7 @@ -329,6 +340,7 @@ class test_Proxy(ClassChecker): __public__ = frozenset() class sub(base): name = 'some_name' + doc = 'doc' label = 'another_name' p = self.cls(base, sub()) @@ -389,6 +401,7 @@ class test_NameSpace(ClassChecker): __public__ = frozenset(( 'plusplus', )) + doc = 'doc' def plusplus(self, n): return n + 1