def test_mangle_signature(): TEST = """ () :: () (a, b, c, d, e) :: (a, b, c, d, e) (a, b, c=1, d=2, e=3) :: (a, b[, c, d, e]) (a, b, aaa=1, bbb=1, ccc=1, eee=1, fff=1, ggg=1, hhh=1, iii=1, jjj=1)\ :: (a, b[, aaa, bbb, ccc, ...]) (a, b, c=(), d=<foo>) :: (a, b[, c, d]) (a, b, c='foobar()', d=123) :: (a, b[, c, d]) (a, b[, c]) :: (a, b[, c]) (a, b[, cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]) :: (a, b[, ...) (a, b='c=d, e=f, g=h', c=3) :: (a[, b, c]) (a, b='c=d, \\'e=f,\\' g=h', c=3) :: (a[, b, c]) (a, b='c=d, ', e='\\\\' g=h, c=3) :: (a[, b, e, c]) (a, b={'c=d, ': 3, '\\\\': 3}) :: (a[, b]) (a=1, b=2, c=3) :: ([a, b, c]) (a=1, b=<SomeClass: a, b, c>, c=3) :: ([a, b, c]) (a: int, b: int) -> str :: (a, b) """ TEST = [[y.strip() for y in x.split("::")] for x in TEST.split("\n") if '::' in x] for inp, outp in TEST: res = mangle_signature(inp).strip().replace(u"\u00a0", " ") assert res == outp, (u"'%s' -> '%s' != '%s'" % (inp, res, outp))
def get_items(self, names): items = [] env = self.state.document.settings.env all_objects = env.autoapi_all_objects max_item_chars = 60 for name in names: obj = all_objects[name] if isinstance(obj, PythonFunction): if obj.overloads: sig = "(\u2026)" else: sig = "({})".format(obj.args) if obj.return_annotation is not None: sig += " \u2192 {}".format(obj.return_annotation) else: sig = "" if sig: max_sig_chars = max(10, max_item_chars - len(obj.short_name)) sig = mangle_signature(sig, max_chars=max_sig_chars) item = (obj.short_name, sig, obj.summary, obj.id) items.append(item) return items
def get_items(self, names: List[str]) -> List[Tuple[str, str, str, str]]: items = [] # type: List[Tuple[str, str, str, str]] for display_name, sig, summary, real_name in super().get_items(names): if summary == 'Initialize self.': continue real_name, obj, parent, modname = import_by_name(real_name) del parent del modname if summary == 'Overloaded function.': for part_sig, part in _parse_overloaded_function_docstring( obj.__doc__): max_item_chars = 50 max_chars = max(10, max_item_chars - len(display_name)) mangled_sig = mangle_signature(part_sig, max_chars=max_chars) part_summary = extract_summary(part.splitlines(), self.state.document) items.append( (display_name, mangled_sig, part_summary, real_name)) else: if isinstance(obj, property): retann = _get_attribute_type(obj) if retann is not None: sig = ': ' + retann items.append((display_name, sig, summary, real_name)) return items
def test_mangle_signature(): TEST = """ () :: () (a, b, c, d, e) :: (a, b, c, d, e) (a, b, c=1, d=2, e=3) :: (a, b[, c, d, e]) (a, b, aaa=1, bbb=1, ccc=1, eee=1, fff=1, ggg=1, hhh=1, iii=1, jjj=1)\ :: (a, b[, aaa, bbb, ccc, ...]) (a, b, c=(), d=<foo>) :: (a, b[, c, d]) (a, b, c='foobar()', d=123) :: (a, b[, c, d]) """ TEST = [map(string.strip, x.split("::")) for x in TEST.split("\n") if '::' in x] for inp, outp in TEST: res = mangle_signature(inp).strip().replace(u"\u00a0", " ") assert res == outp, (u"'%s' -> '%s' != '%s'" % (inp, res, outp))
def test_mangle_signature(): TEST = """ () :: () (a, b, c, d, e) :: (a, b, c, d, e) (a, b, c=1, d=2, e=3) :: (a, b[, c, d, e]) (a, b, aaa=1, bbb=1, ccc=1, eee=1, fff=1, ggg=1, hhh=1, iii=1, jjj=1)\ :: (a, b[, aaa, bbb, ccc, ...]) (a, b, c=(), d=<foo>) :: (a, b[, c, d]) (a, b, c='foobar()', d=123) :: (a, b[, c, d]) """ TEST = [ map(string.strip, x.split("::")) for x in TEST.split("\n") if '::' in x ] for inp, outp in TEST: res = mangle_signature(inp).strip().replace(u"\u00a0", " ") assert res == outp, (u"'%s' -> '%s' != '%s'" % (inp, res, outp))
def get_items_from_documenters(self, documenters): """Return the items needed for creating the tables This method creates the items that are used by the :meth:`sphinx.ext.autosummary.Autosummary.get_table` method by what is taken from the values of the :meth:`AutoSummModuleDocumenter.get_grouped_documenters` method. Returns ------- list A list containing tuples like ``(name, signature, summary_string, real_name)`` that can be used for the :meth:`sphinx.ext.autosummary.Autosummary.get_table` method.""" items = [] max_item_chars = 50 base_documenter = self.autosummary_documenter try: base_documenter.analyzer = ModuleAnalyzer.for_module( base_documenter.real_modname) attr_docs = base_documenter.analyzer.find_attr_docs() except PycodeError as err: logger.debug('[autodocsumm] module analyzer failed: %s', err) # no source file -- e.g. for builtin and C modules base_documenter.analyzer = None attr_docs = {} # at least add the module.__file__ as a dependency if (hasattr(base_documenter.module, '__file__') and base_documenter.module.__file__): base_documenter.directive.filename_set.add( base_documenter.module.__file__) else: base_documenter.directive.filename_set.add( base_documenter.analyzer.srcname) for documenter, check_module in documenters: documenter.parse_name() documenter.import_object() documenter.real_modname = documenter.get_real_modname() real_name = documenter.fullname display_name = documenter.object_name if display_name is None: # for instance attributes display_name = documenter.objpath[-1] if check_module and not documenter.check_module(): continue # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) # sig = sig.replace('*', r'\*') # -- Grab the documentation no_docstring = False if documenter.objpath: key = ('.'.join(documenter.objpath[:-1]), documenter.objpath[-1]) try: doc = attr_docs[key] no_docstring = True except KeyError: pass if not no_docstring: documenter.add_content(None) doc = documenter.get_doc() if doc: doc = doc[0] else: continue while doc and not doc[0].strip(): doc.pop(0) # If there's a blank line, then we can assume the first sentence / # paragraph has ended, so anything after shouldn't be part of the # summary for i, piece in enumerate(doc): if not piece.strip(): doc = doc[:i] break # Try to find the "first sentence", which may span multiple lines m = re.search(r"^([A-Z].*?\.)(?:\s|$)", " ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items
def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ env = self.state.document.settings.env prefixes = get_import_prefixes_from_env(env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: real_name, obj, parent = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('failed to import %s' % name) items.append((name, '', '', name)) continue # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): self.warn('failed to import object %s' % real_name) items.append((display_name, '', '', real_name)) continue display_name = documenter.format_name() # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the summary doc = list(documenter.process_doc(documenter.get_doc())) while doc and not doc[0].strip(): doc.pop(0) m = re.search(r"^([A-Z][^A-Z]*?\.\s)", " ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items
def get_items_from_documenters(self, documenters): """Return the items needed for creating the tables This method creates the items that are used by the :meth:`sphinx.ext.autosummary.Autosummary.get_table` method by what is taken from the values of the :meth:`AutoSummModuleDocumenter.get_grouped_documenters` method. Returns ------- list A list containing tuples like ``(name, signature, summary_string, real_name)`` that can be used for the :meth:`sphinx.ext.autosummary.Autosummary.get_table` method.""" items = [] max_item_chars = 50 base_documenter = self.autosummary_documenter base_documenter.analyzer = ModuleAnalyzer.for_module( base_documenter.real_modname) attr_docs = base_documenter.analyzer.find_attr_docs() for documenter, check_module in documenters: documenter.parse_name() documenter.import_object() documenter.real_modname = documenter.get_real_modname() real_name = documenter.fullname display_name = documenter.object_name if check_module and not documenter.check_module(): continue # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the documentation no_docstring = False if documenter.objpath: key = ('.'.join(documenter.objpath[:-1]), documenter.objpath[-1]) try: doc = attr_docs[key] no_docstring = True except KeyError: pass if not no_docstring: documenter.add_content(None) doc = documenter.get_doc() if doc: doc = doc[0] else: continue while doc and not doc[0].strip(): doc.pop(0) # If there's a blank line, then we can assume the first sentence / # paragraph has ended, so anything after shouldn't be part of the # summary for i, piece in enumerate(doc): if not piece.strip(): doc = doc[:i] break # Try to find the "first sentence", which may span multiple lines m = re.search(r"^([A-Z].*?\.)(?:\s|$)", " ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items
def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ prefixes = autosummary.get_import_prefixes_from_env(self.env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith("~"): name = name[1:] display_name = name.split(".")[-1] try: with autosummary.mock(self.config.autosummary_mock_imports): real_name, obj, parent, modname = autosummary.import_by_name( name, prefixes=prefixes) except ImportError: autosummary.logger.warning( __("autosummary: failed to import %s"), name, location=self.get_source_info(), ) continue # initialize for each documenter self.bridge.result = autosummary.StringList() full_name = real_name if not isinstance(obj, autosummary.ModuleType): # give explicitly separated module name, so that members # of inner classes can be documented full_name = modname + "::" + full_name[len(modname) + 1:] # NB. using full_name here is important, since Documenters # handle module prefixes slightly differently documenter = self.create_documenter(self.env.app, obj, parent, full_name) if not documenter.parse_name(): autosummary.logger.warning( __("failed to parse name %s"), real_name, location=self.get_source_info(), ) items.append((display_name, "", "", real_name)) continue if not documenter.import_object(): autosummary.logger.warning( __("failed to import object %s"), real_name, location=self.get_source_info(), ) items.append((display_name, "", "", real_name)) continue if documenter.options.members and not documenter.check_module(): continue # try to also get a source code analyzer for attribute docs try: documenter.analyzer = autosummary.ModuleAnalyzer.for_module( documenter.get_real_modname()) # parse right now, to get PycodeErrors on parsing (results will # be cached anyway) documenter.analyzer.find_attr_docs() except autosummary.PycodeError as err: autosummary.logger.debug( "[autodoc] module analyzer failed: %s", err) # no source file -- e.g. for builtin and C modules documenter.analyzer = None # -- Grab the signature try: sig = documenter.format_signature(show_annotation=False) except TypeError: # the documenter does not support ``show_annotation`` option sig = documenter.format_signature() if not sig: sig = "" else: max_chars = max(10, max_item_chars - len(display_name)) sig = autosummary.mangle_signature(sig, max_chars=max_chars) # -- Grab the summary documenter.add_content(None) summary = autosummary.extract_summary(self.bridge.result.data[:], self.state.document) items.append((display_name, sig, summary, real_name)) return items
def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ from sphinx.ext.autosummary import (get_import_prefixes_from_env, import_by_name, get_documenter, mangle_signature) env = self.state.document.settings.env prefixes = get_import_prefixes_from_env(env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: import_by_name_values = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('[astropyautosummary] failed to import %s' % name) items.append((name, '', '', name)) continue # to accommodate Sphinx v1.2.2 and v1.2.3 if len(import_by_name_values) == 3: real_name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: real_name, obj, parent, module_name = import_by_name_values # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('[astropyautosummary] failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): self.warn('[astropyautosummary] failed to import object %s' % real_name) items.append((display_name, '', '', real_name)) continue # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the summary doc = list(documenter.process_doc(documenter.get_doc())) while doc and not doc[0].strip(): doc.pop(0) m = _itemsummrex.search(" ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items
def get_items(self, names: List[str]) -> List[Tuple[str, str, str, str, str]]: """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name, env_summary), ...]``. """ prefixes = get_import_prefixes_from_env(self.env) items = [] # type: List[Tuple[str, str, str, str, str]] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: with mock(self.config.autosummary_mock_imports): real_name, obj, parent, modname = import_by_name( name, prefixes=prefixes) except ImportError: logger.warning(__('failed to import %s'), name) items.append((name, '', '', name, '')) continue self.bridge.result = StringList() # initialize for each documenter full_name = real_name if not isinstance(obj, ModuleType): # give explicitly separated module name, so that members # of inner classes can be documented full_name = modname + '::' + full_name[len(modname) + 1:] # NB. using full_name here is important, since Documenters # handle module prefixes slightly differently doccls = get_documenter(self.env.app, obj, parent) documenter = doccls(self.bridge, full_name) if not documenter.parse_name(): logger.warning(__('failed to parse name %s'), real_name) items.append((display_name, '', '', real_name, '')) continue if not documenter.import_object(): logger.warning(__('failed to import object %s'), real_name) items.append((display_name, '', '', real_name, '')) continue if documenter.options.members and not documenter.check_module(): continue # try to also get a source code analyzer for attribute docs try: documenter.analyzer = ModuleAnalyzer.for_module( documenter.get_real_modname()) # parse right now, to get PycodeErrors on parsing (results will # be cached anyway) documenter.analyzer.find_attr_docs() except PycodeError as err: logger.debug('[autodoc] module analyzer failed: %s', err) # no source file -- e.g. for builtin and C modules documenter.analyzer = None # -- Grab the signature try: sig = documenter.format_signature(show_annotation=False) except TypeError: # the documenter does not support ``show_annotation`` option sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) # -- Grab the summary documenter.add_content(None) summary = extract_summary(self.bridge.result.data[:], self.state.document) env_sum = self.extract_env_summary(self.bridge.result.data[:]) items.append((display_name, sig, summary, real_name, env_sum)) return items