def get_object_members(subject, objpath, attrgetter, analyzer=None): # type: (Any, List[unicode], Callable, Any) -> Dict[str, Attribute] # NOQA """Get members and attributes of target object.""" # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) # Py34 doesn't have enum members in __dict__. if sys.version_info[:2] == (3, 4) and isenumclass(subject): obj_dict = dict(obj_dict) for name, value in subject.__members__.items(): obj_dict[name] = value members = {} for name in dir(subject): try: value = attrgetter(subject, name) directly_defined = name in obj_dict members[name] = Attribute(name, directly_defined, value) except AttributeError: continue if analyzer: # append instance attributes (cf. self.attr1) if analyzer knows from sphinx.ext.autodoc import INSTANCEATTR namespace = '.'.join(objpath) for (ns, name) in analyzer.find_attr_docs(): if namespace == ns and name not in members: members[name] = Attribute(name, True, INSTANCEATTR) return members
def get_object_members(subject, objpath, attrgetter, analyzer=None): # type: (Any, List[unicode], Callable, Any) -> Dict[str, Attribute] # NOQA """Get members and attributes of target object.""" # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) # Py34 doesn't have enum members in __dict__. if sys.version_info[:2] == (3, 4) and isenumclass(subject): obj_dict = dict(obj_dict) for name, value in subject.__members__.items(): obj_dict[name] = value members = {} for name in dir(subject): try: value = attrgetter(subject, name) directly_defined = name in obj_dict members[name] = Attribute(name, directly_defined, value) except AttributeError: continue if analyzer: # append instance attributes (cf. self.attr1) if analyzer knows from sphinx.ext.autodoc import INSTANCEATTR namespace = '.'.join(objpath) for (ns, name) in analyzer.find_attr_docs(): if namespace == ns and name not in members: members[name] = Attribute(name, True, INSTANCEATTR) return members
def get_object_members( subject: Any, objpath: List[str], attrgetter: Callable, analyzer: ModuleAnalyzer = None) -> Dict[str, Attribute]: """Get members and attributes of target object.""" from sphinx.ext.autodoc import INSTANCEATTR # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) members = {} # type: Dict[str, Attribute] # enum members if isenumclass(subject): for name, value in subject.__members__.items(): if name not in members: members[name] = Attribute(name, True, value) superclass = subject.__mro__[1] for name in obj_dict: if name not in superclass.__dict__: value = safe_getattr(subject, name) members[name] = Attribute(name, True, value) # members in __slots__ if isclass(subject) and getattr(subject, '__slots__', None) is not None: from sphinx.ext.autodoc import SLOTSATTR for name in subject.__slots__: members[name] = Attribute(name, True, SLOTSATTR) # other members for name in dir(subject): try: value = attrgetter(subject, name) directly_defined = name in obj_dict name = unmangle(subject, name) if name and name not in members: members[name] = Attribute(name, directly_defined, value) except AttributeError: continue # annotation only member (ex. attr: int) if hasattr(subject, '__annotations__') and isinstance( subject.__annotations__, Mapping): for name in subject.__annotations__: name = unmangle(subject, name) if name and name not in members: members[name] = Attribute(name, True, INSTANCEATTR) if analyzer: # append instance attributes (cf. self.attr1) if analyzer knows namespace = '.'.join(objpath) for (ns, name) in analyzer.find_attr_docs(): if namespace == ns and name not in members: members[name] = Attribute(name, True, INSTANCEATTR) return members
def get_object_members(subject, objpath, attrgetter, analyzer=None): # type: (Any, List[str], Callable, Any) -> Dict[str, Attribute] # NOQA """Get members and attributes of target object.""" # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) members = {} # type: Dict[str, Attribute] # enum members if isenumclass(subject): for name, value in subject.__members__.items(): if name not in members: members[name] = Attribute(name, True, value) superclass = subject.__mro__[1] for name, value in obj_dict.items(): if name not in superclass.__dict__: members[name] = Attribute(name, True, value) # members in __slots__ if isclass(subject) and hasattr(subject, '__slots__'): from sphinx.ext.autodoc import SLOTSATTR for name in subject.__slots__: members[name] = Attribute(name, True, SLOTSATTR) # other members for name in dir(subject): try: value = attrgetter(subject, name) directly_defined = name in obj_dict if name not in members: members[name] = Attribute(name, directly_defined, value) except AttributeError: continue if analyzer: # append instance attributes (cf. self.attr1) if analyzer knows from sphinx.ext.autodoc import INSTANCEATTR namespace = '.'.join(objpath) for (ns, name) in analyzer.find_attr_docs(): if namespace == ns and name not in members: members[name] = Attribute(name, True, INSTANCEATTR) return members
def add_annotations(app: Sphinx, what: str, name: str, object: Any, *args: Any) -> None: if what not in {"class", "function", "method"} or isenumclass(object): return # can't have annotations if isinstance(object, type): annotations: dict[str, Any] = {} for base in reversed(object.__mro__[:-1]): for name, evaled_type in get_annotations( base, what, f"{base.__module__}.{base.__name__}"): if evaled_type is MISSING: continue try: base.__annotations__[name] = evaled_type except AttributeError: # TODO remove when postponed annotations are available try: base.__annotations__ = {name: evaled_type} except AttributeError: break base.__module__ = ("steam" if base.__module__.startswith("steam") and not base.__module__.endswith( ("abc", "guard", "utils")) else base.__module__) try: base.__annotations__ = annotations = getattr( base, "__annotations__", {}) | annotations except AttributeError: pass else: for name, evaled_type in get_annotations(object, what, name): if evaled_type is MISSING: continue try: object.__annotations__[name] = evaled_type except AttributeError: # TODO remove when postponed annotations are available try: object.__annotations__ = {name: evaled_type} except AttributeError: break
def get_object_members(subject, objpath, attrgetter, analyzer=None): # type: (Any, List[str], Callable, Any) -> Dict[str, Attribute] # NOQA """Get members and attributes of target object.""" # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) members = {} # type: Dict[str, Attribute] # enum members if isenumclass(subject): for name, value in subject.__members__.items(): if name not in members: members[name] = Attribute(name, True, value) superclass = subject.__mro__[1] for name, value in obj_dict.items(): if name not in superclass.__dict__: members[name] = Attribute(name, True, value) # other members for name in dir(subject): try: value = attrgetter(subject, name) directly_defined = name in obj_dict if name not in members: members[name] = Attribute(name, directly_defined, value) except AttributeError: continue if analyzer: # append instance attributes (cf. self.attr1) if analyzer knows from sphinx.ext.autodoc import INSTANCEATTR namespace = '.'.join(objpath) for (ns, name) in analyzer.find_attr_docs(): if namespace == ns and name not in members: members[name] = Attribute(name, True, INSTANCEATTR) return members
def get_class_members(subject: Any, objpath: List[str], attrgetter: Callable) -> Dict[str, "ObjectMember"]: """Get members and attributes of target class.""" from sphinx.ext.autodoc import INSTANCEATTR, ObjectMember # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) members = {} # type: Dict[str, ObjectMember] # enum members if isenumclass(subject): for name, value in subject.__members__.items(): if name not in members: members[name] = ObjectMember(name, value, class_=subject) superclass = subject.__mro__[1] for name in obj_dict: if name not in superclass.__dict__: value = safe_getattr(subject, name) members[name] = ObjectMember(name, value, class_=subject) # members in __slots__ try: __slots__ = getslots(subject) if __slots__: from sphinx.ext.autodoc import SLOTSATTR for name, docstring in __slots__.items(): members[name] = ObjectMember(name, SLOTSATTR, class_=subject, docstring=docstring) except (TypeError, ValueError): pass # other members for name in dir(subject): try: value = attrgetter(subject, name) if ismock(value): value = undecorate(value) unmangled = unmangle(subject, name) if unmangled and unmangled not in members: if name in obj_dict: members[unmangled] = ObjectMember(unmangled, value, class_=subject) else: members[unmangled] = ObjectMember(unmangled, value) except AttributeError: continue try: for cls in getmro(subject): try: modname = safe_getattr(cls, '__module__') qualname = safe_getattr(cls, '__qualname__') analyzer = ModuleAnalyzer.for_module(modname) analyzer.analyze() except AttributeError: qualname = None analyzer = None except PycodeError: analyzer = None # annotation only member (ex. attr: int) for name in getannotations(cls): name = unmangle(cls, name) if name and name not in members: if analyzer and (qualname, name) in analyzer.attr_docs: docstring = '\n'.join(analyzer.attr_docs[qualname, name]) else: docstring = None members[name] = ObjectMember(name, INSTANCEATTR, class_=cls, docstring=docstring) # append instance attributes (cf. self.attr1) if analyzer knows if analyzer: for (ns, name), docstring in analyzer.attr_docs.items(): if ns == qualname and name not in members: members[name] = ObjectMember( name, INSTANCEATTR, class_=cls, docstring='\n'.join(docstring)) except AttributeError: pass return members
def get_class_members( subject: Any, objpath: List[str], attrgetter: Callable, inherit_docstrings: bool = True) -> Dict[str, "ObjectMember"]: """Get members and attributes of target class.""" from sphinx.ext.autodoc import INSTANCEATTR, ObjectMember # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) members: Dict[str, ObjectMember] = {} # enum members if isenumclass(subject): for name, value in subject.__members__.items(): if name not in members: members[name] = ObjectMember(name, value, class_=subject) superclass = subject.__mro__[1] for name in obj_dict: if name not in superclass.__dict__: value = safe_getattr(subject, name) members[name] = ObjectMember(name, value, class_=subject) # members in __slots__ try: __slots__ = getslots(subject) if __slots__: from sphinx.ext.autodoc import SLOTSATTR for name, docstring in __slots__.items(): members[name] = ObjectMember(name, SLOTSATTR, class_=subject, docstring=docstring) except (TypeError, ValueError): pass # other members for name in dir(subject): try: value = attrgetter(subject, name) if ismock(value): value = undecorate(value) unmangled = unmangle(subject, name) if unmangled and unmangled not in members: if name in obj_dict: members[unmangled] = ObjectMember(unmangled, value, class_=subject) else: members[unmangled] = ObjectMember(unmangled, value) except AttributeError: continue try: for cls in getmro(subject): try: modname = safe_getattr(cls, '__module__') qualname = safe_getattr(cls, '__qualname__') analyzer = ModuleAnalyzer.for_module(modname) analyzer.analyze() except AttributeError: qualname = None analyzer = None except PycodeError: analyzer = None # annotation only member (ex. attr: int) for name in getannotations(cls): name = unmangle(cls, name) if name and name not in members: if analyzer and (qualname, name) in analyzer.attr_docs: docstring = '\n'.join(analyzer.attr_docs[qualname, name]) else: docstring = None members[name] = ObjectMember(name, INSTANCEATTR, class_=cls, docstring=docstring) # append or complete instance attributes (cf. self.attr1) if analyzer knows if analyzer: for (ns, name), docstring in analyzer.attr_docs.items(): if ns == qualname and name not in members: # otherwise unknown instance attribute members[name] = ObjectMember( name, INSTANCEATTR, class_=cls, docstring='\n'.join(docstring)) elif (ns == qualname and docstring and isinstance(members[name], ObjectMember) and not members[name].docstring): if cls != subject and not inherit_docstrings: # If we are in the MRO of the class and not the class itself, # and we do not want to inherit docstrings, then skip setting # the docstring below continue # attribute is already known, because dir(subject) enumerates it. # But it has no docstring yet members[name].docstring = '\n'.join(docstring) except AttributeError: pass return members