Skip to content
Snippets Groups Projects
Commit 1081b8ba authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

add DocsFromParent

parent d8639153
No related branches found
No related tags found
No related merge requests found
# v2.9.10
* semantics of `catch_exception` changed
* added `DocsFromParent`
......@@ -43,6 +43,12 @@ You can also decorate given callables in order not to be wrapped with
.. autofunction:: satella.coding.dont_wrap
DocsFromParent
--------------
.. autoclass:: satella.coding.DocsFromParent
:members:
metaclass_maker
---------------
......
......@@ -10,7 +10,7 @@ from .decorators import precondition, short_none, has_keys, \
from .deleters import ListDeleter, DictDeleter
from .fun_static import static_var
from .iterators import hint_with_length, SelfClosingGenerator, exhaust, chain
from .metaclasses import metaclass_maker, wrap_with, dont_wrap, wrap_property
from .metaclasses import metaclass_maker, wrap_with, dont_wrap, wrap_property, DocsFromParent
from .misc import update_if_not_none
from .recast_exceptions import rethrow_as, silence_excs, catch_exception, log_exceptions, \
raises_exception
......
import inspect
from .recast_exceptions import silence_excs
from .decorators import wraps
"""
......@@ -9,7 +10,30 @@ modified
from abc import ABCMeta
import typing as tp
__all__ = ['metaclass_maker', 'wrap_with', 'dont_wrap', 'wrap_property']
__all__ = ['metaclass_maker', 'wrap_with', 'dont_wrap', 'wrap_property',
'DocsFromParent']
class DocsFromParent(type):
"""
A metaclass that fetches missing docstring's for methods from class's immediate parent
>>> class Father:
>>> def test(self):
>>> '''my docstring'''
>>> class Child(Father, metaclass=DocsFromParent):
>>> def test(self):
>>> ...
>>> assert Child.test.__doc__ == 'my docstring'
"""
def __call__(cls, name, bases, dictionary):
for key, value in dictionary.items():
if bases and callable(value) and not value.__doc__:
with silence_excs(AttributeError):
value.__doc__ = getattr(bases[0], key).__doc__
dictionary[key] = value
return super().__call__(name, bases, dictionary)
def skip_redundant(iterable, skip_set=None):
......
import abc
import unittest
from satella.coding import metaclass_maker, wrap_with, dont_wrap, rethrow_as, wrap_property
from satella.coding import metaclass_maker, wrap_with, dont_wrap, rethrow_as, wrap_property, \
DocsFromParent
class MetaA(type):
......@@ -25,6 +26,18 @@ class AB(A, B, metaclass=metaclass_maker):
class TestMetaclasses(unittest.TestCase):
def test_docs_from_parent(self):
class Father:
def test(self):
"""my docstring"""
class Child(Father, metaclass=DocsFromParent):
def test(self):
pass
self.assertEqual(Child.test.__doc, Father.test.__doc__)
def test_metaclasses(self):
AB()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment