def test_do_not_doc_on_method(self): """The simple decorator is not aware of inheritance.""" class Parent(object): @doc_controls.do_not_generate_docs def my_method(self): pass class Child(Parent): def my_method(self): pass class GrandChild(Child): pass self.assertTrue(doc_controls.should_skip(Parent.my_method)) self.assertFalse(doc_controls.should_skip(Child.my_method)) self.assertFalse(doc_controls.should_skip(GrandChild.my_method)) self.assertTrue(doc_controls.should_skip_class_attr(Parent, 'my_method')) self.assertFalse(doc_controls.should_skip_class_attr(Child, 'my_method')) self.assertFalse( doc_controls.should_skip_class_attr(GrandChild, 'my_method'))
def test_do_not_doc_inheritable_property(self): class Parent(object): @property @doc_controls.do_not_doc_inheritable def my_method(self): pass class Child(Parent): @property def my_method(self): pass class GrandChild(Child): pass self.assertTrue(doc_controls.should_skip(Parent.my_method)) self.assertFalse(doc_controls.should_skip(Child.my_method)) self.assertFalse(doc_controls.should_skip(GrandChild.my_method)) self.assertTrue(doc_controls.should_skip_class_attr(Parent, 'my_method')) self.assertTrue(doc_controls.should_skip_class_attr(Child, 'my_method')) self.assertTrue( doc_controls.should_skip_class_attr(GrandChild, 'my_method'))
def test_do_not_doc_inheritable_property(self): class Parent(object): @property @doc_controls.do_not_doc_inheritable def my_method(self): pass class Child(Parent): @property def my_method(self): pass class GrandChild(Child): pass self.assertTrue(doc_controls.should_skip(Parent.my_method)) self.assertFalse(doc_controls.should_skip(Child.my_method)) self.assertFalse(doc_controls.should_skip(GrandChild.my_method)) self.assertTrue( doc_controls.should_skip_class_attr(Parent, 'my_method')) self.assertTrue(doc_controls.should_skip_class_attr( Child, 'my_method')) self.assertTrue( doc_controls.should_skip_class_attr(GrandChild, 'my_method'))
def _is_private(self, path, name, obj): """Return whether a name is private.""" # Skip objects blocked by doc_controls. if doc_controls.should_skip(obj): return True # Skip modules outside of the package root. if inspect.ismodule(obj): if hasattr(obj, '__file__'): # `startswith` will match any item in a tuple. if not obj.__file__.startswith(self._base_dir): return True # Skip objects blocked by the private_map if name in self._private_map.get('.'.join(path), []): return True # Skip "_" hidden attributes is_dunder = name.startswith('__') and name.endswith('__') if name.startswith('_') and not is_dunder: return True if name in ['__base__', '__class__']: return True return False
def _is_private(self, path, name, obj): """Returns whether a name is private or not.""" # Skip objects blocked by doc_controls. if doc_controls.should_skip(obj): return True if doc_controls.should_doc_private(obj): return False if inspect.ismodule(obj): mod_base_dirs = get_module_base_dirs(obj) # This check only handles normal packages/modules. Namespace-package # contents will get filtered when the submodules are checked. if len(mod_base_dirs) == 1: mod_base_dir = mod_base_dirs[0] # Check that module is in one of the `self._base_dir`s if not any(base in mod_base_dir.parents for base in self._base_dir): return True # Skip objects blocked by the private_map if name in self._private_map.get('.'.join(path), []): return True # Skip "_" hidden attributes if name.startswith('_') and name not in ALLOWED_DUNDER_METHODS: return True return False
def test_do_not_generate_docs(self): @doc_controls.do_not_generate_docs def dummy_function(): pass self.assertTrue(doc_controls.should_skip(dummy_function))
def _is_private(self, path, name, obj): """Return whether a name is private.""" # Skip objects blocked by doc_controls. if doc_controls.should_skip(obj): return True # Skip modules outside of the package root. if inspect.ismodule(obj): if hasattr(obj, '__file__'): # `startswith` will match any item in a tuple if a tuple of base_dir # are passed. # It's important that this is a string comparison not a `relpath`, # because in some cases `base_dir` may not a directory but a single # file path. if not obj.__file__.startswith(self._base_dir): return True # Skip objects blocked by the private_map if name in self._private_map.get('.'.join(path), []): return True # Skip "_" hidden attributes if name.startswith('_') and name not in ALLOWED_DUNDER_METHODS: return True return False
def filter_doc_controls_skip(path: Sequence[str], parent: Any, children: Children) -> Children: del path for name, child in children: if doc_controls.should_skip(child): continue if isinstance(parent, type): if doc_controls.should_skip_class_attr(parent, name): continue yield (name, child)
def test_skip_class_short_circuit(self): class GrandParent(object): def my_method(self): pass @doc_controls.do_not_generate_docs class Parent(GrandParent): pass class Child(Parent): pass self.assertFalse(doc_controls.should_skip(Child)) self.assertTrue(doc_controls.should_skip(Parent)) self.assertFalse(doc_controls.should_skip(GrandParent)) self.assertFalse( doc_controls.should_skip_class_attr(GrandParent, 'my_method')) self.assertFalse(doc_controls.should_skip_class_attr(Parent, 'my_method')) self.assertTrue(doc_controls.should_skip_class_attr(Child, 'my_method'))
def test_skip_class_short_circuit(self): class GrandParent(object): def my_method(self): pass @doc_controls.do_not_generate_docs class Parent(GrandParent): pass class Child(Parent): pass self.assertFalse(doc_controls.should_skip(Child)) self.assertTrue(doc_controls.should_skip(Parent)) self.assertFalse(doc_controls.should_skip(GrandParent)) self.assertFalse( doc_controls.should_skip_class_attr(GrandParent, 'my_method')) self.assertFalse( doc_controls.should_skip_class_attr(Parent, 'my_method')) self.assertFalse( doc_controls.should_skip_class_attr(Child, 'my_method'))
def _is_private(self, path, name, obj): if doc_controls.should_skip(obj): return True return super(DocControlsAwareCrawler, self)._is_private(path, name, obj)