diff --git a/sphinxtools/constants.py b/sphinxtools/constants.py index 27f59b11..fb6eebce 100644 --- a/sphinxtools/constants.py +++ b/sphinxtools/constants.py @@ -42,7 +42,7 @@ CONSTANT_INSTANCES = ['NullAcceleratorTable', 'TheApp', 'DefaultPosition', 'Defa 'NullFont', 'NullBrush', 'NullPalette', 'NullPen', 'EmptyString', 'TheFontList', 'NullIcon', 'NullBitmap', 'constructor', 'ThePenList', 'DefaultValidator', 'String.Capitalize'] - + # Phoenix full version VERSION = '%d.%d.%d' % (version.VER_MAJOR, version.VER_MINOR, version.VER_RELEASE) @@ -53,11 +53,11 @@ PUNCTUATION = '!"#$%\'()*,./:;<=>?@\\^{|}~' SECTIONS = [('return' , ':returns:'), ('since' , '.. versionadded::'), ('deprecated', '.. deprecated::'), - ('warning' , '.. warning::'), + ('warning' , '.. warning::'), ('remarks' , '.. note::'), ('remark' , '.. note::'), ('available' , '.. availability::'), - ('note' , '.. note::'), + ('note' , '.. note::'), ('see' , '.. seealso::'), ('todo' , '.. todo::'), ('par' , '')] @@ -231,7 +231,7 @@ TYPE_DESCRIPTION = ['library', 'package', 'py_module', 'pyd_module', 'pyc_module', 'pyw_module', 'klass', - 'function', + 'function', 'method', 'static_method', 'class_method', 'instance_method', 'method_descriptor', 'builtin_method', 'builtin_function', 'property', diff --git a/sphinxtools/inheritance.py b/sphinxtools/inheritance.py index 67637d8e..7e0cb8af 100644 --- a/sphinxtools/inheritance.py +++ b/sphinxtools/inheritance.py @@ -26,7 +26,7 @@ EPIPE = getattr(errno, 'EPIPE', 0) if sys.version_info < (3, ): string_base = basestring -else: +else: string_base = str @@ -43,7 +43,7 @@ class InheritanceDiagram(object): self.class_info, self.specials = classes else: self.class_info, self.specials = self._class_info(classes) - + self.main_class = main_class @@ -62,7 +62,7 @@ class InheritanceDiagram(object): fullname = self.class_name(cls) if cls in [object] or fullname.startswith('sip.'): return - + baselist = [] all_classes[cls] = (fullname, baselist) @@ -144,8 +144,8 @@ class InheritanceDiagram(object): 'Arial, Helvetica, sans"', 'style': '"setlinewidth(0.5)"', 'labelloc': 'c', 'fontcolor': 'grey45'} - inheritance_edge_attrs = {'arrowsize': 0.5, - 'style': '"setlinewidth(0.5)"', + inheritance_edge_attrs = {'arrowsize': 0.5, + 'style': '"setlinewidth(0.5)"', 'color': '"#23238E"', 'dir': 'back', 'arrowtail': 'open', @@ -181,7 +181,7 @@ class InheritanceDiagram(object): full_page = formatExternalLink(fullname, inheritance=True) if full_page: this_node_attrs['URL'] = full_page - + res.append(' "%s" [%s];\n' % (fullname, self._format_node_attrs(this_node_attrs))) @@ -225,7 +225,7 @@ class InheritanceDiagram(object): if self.main_class is not None: filename = self.main_class.name - else: + else: filename = self.specials[0] outfn = os.path.join(static_root, filename + '_inheritance.png') @@ -258,7 +258,7 @@ class InheritanceDiagram(object): 'stdin': PIPE, 'stderr': PIPE } - + if sys.platform == 'win32': popen_args['shell'] = True diff --git a/sphinxtools/librarydescription.py b/sphinxtools/librarydescription.py index 27271a55..6f99e952 100644 --- a/sphinxtools/librarydescription.py +++ b/sphinxtools/librarydescription.py @@ -24,29 +24,29 @@ if sys.version_info < (3,): def make_class_tree(tree): class_tree = [] - + if isinstance(tree, list): for node in tree: class_tree.append(make_class_tree(node)) else: name = tree[0].__name__ class_tree.append(name) - + return class_tree - + def generic_summary(libraryItem, stream): write_toc = True add_tilde = [True, True] - + if libraryItem.kind in [object_types.LIBRARY, object_types.PACKAGE]: list1 = libraryItem.GetItemByKind(object_types.PACKAGE) list2 = libraryItem.GetItemByKind(object_types.PY_MODULE, object_types.PYW_MODULE) templ = [templates.TEMPLATE_PACKAGE_SUMMARY, templates.TEMPLATE_MODULE_SUMMARY] refs = ['mod', 'mod'] - + elif libraryItem.kind in range(object_types.PY_MODULE, object_types.PYW_MODULE+1): list1 = libraryItem.GetItemByKind(object_types.FUNCTION) list2 = libraryItem.GetItemByKind(object_types.KLASS, recurse=True) @@ -63,16 +63,16 @@ def generic_summary(libraryItem, stream): templ = [templates.TEMPLATE_METHOD_SUMMARY, templates.TEMPLATE_PROPERTY_SUMMARY] refs = ['meth', 'attr'] add_tilde = [True, True] - - else: + + else: raise Exception('Invalid library item: %s'%libraryItem.GetShortName()) - - toctree = '' + + toctree = '' for index, sub_list in enumerate([list1, list2]): table = [] for item in sub_list: - + if item.is_redundant: continue @@ -87,7 +87,7 @@ def generic_summary(libraryItem, stream): if table: summary = makeSummary(libraryItem.name, table, templ[index], refs[index], add_tilde[index]) stream.write(summary) - + if toctree and write_toc: stream.write(templates.TEMPLATE_TOCTREE%toctree) stream.write('\n\n') @@ -108,7 +108,7 @@ def replaceWxDot(text): if old not in text: continue - + if new in [':keyword', ':param']: if not space_added: space_added = True @@ -116,7 +116,7 @@ def replaceWxDot(text): text = text.replace(old, new_with_newline, 1) text = text.replace(old, new) - + lines = text.splitlines(True) newtext = '' @@ -148,9 +148,9 @@ def GetTopLevelParent(klass): if not parent: return klass - + parents = [parent] - + while parent: parent = parent.parent parents.append(parent) @@ -167,7 +167,7 @@ def findInHierarchy(klass, newlink): def findBestLink(klass, newlink): parent_class = klass.parent - + if klass.kind in range(object_types.FUNCTION, object_types.INSTANCE_METHOD): if parent_class.GetShortName() == newlink: return ':class:`%s`'%newlink @@ -200,9 +200,9 @@ def killEpydoc(klass, newtext): if not epydocs: return newtext - + newepydocs = epydocs[:] - + for item in epydocs: if '#{' in item: # this is for masked stuff @@ -215,7 +215,7 @@ def killEpydoc(klass, newtext): start = regex.index('{') end = regex.index('}') - + if 'U{' in regex: # Simple link, leave it as it is newlink = regex[start+1:end] @@ -248,7 +248,7 @@ def killEpydoc(klass, newtext): bestlink = findBestLink(klass, newlink) if bestlink: newlink = bestlink - + else: # Something else, don't bother for the moment continue @@ -259,7 +259,7 @@ def killEpydoc(klass, newtext): class ParentBase(object): - + def __init__(self, name, kind): self.name = name @@ -281,7 +281,7 @@ class ParentBase(object): for child in self.children: if child.name == klass.name: return - + klass.parent = self self.children.append(klass) @@ -298,7 +298,7 @@ class ParentBase(object): if self.comments is None or not self.comments.strip(): self.comments = '' - + for child in self.children: child.Save() @@ -321,7 +321,7 @@ class ParentBase(object): def GetObject(self): return self.obj_type - + def GetChildren(self): @@ -337,7 +337,7 @@ class ParentBase(object): """ count = len(self.children) - + if not recursively: return count @@ -345,10 +345,10 @@ class ParentBase(object): for n in range(count): total += self.children[n].GetChildrenCount() - + return total - + def GetKindCount(self, minObj, maxObj=None): if maxObj is None: @@ -359,10 +359,10 @@ class ParentBase(object): if minObj <= child.kind <= maxObj: count += 1 - return count + return count - def GetItemByKind(self, minObj, maxObj=None, recurse=False): + def GetItemByKind(self, minObj, maxObj=None, recurse=False): if maxObj is None: maxObj = minObj @@ -375,13 +375,13 @@ class ParentBase(object): if recurse: items = items + child.GetItemByKind(minObj, maxObj, recurse) - return items + return items def ToRest(self, class_summary): pass - + class Library(ParentBase): @@ -401,8 +401,8 @@ class Library(ParentBase): def GetShortName(self): - return self.name - + return self.name + def Walk(self, obj, class_summary): @@ -413,7 +413,7 @@ class Library(ParentBase): children = obj.GetChildren() if not children: - return + return # check each name for child in children: @@ -431,14 +431,14 @@ class Library(ParentBase): if obj is None: obj = self - + # must have at least root folder children = obj.GetChildren() bestlink = '' - + if not children: return bestlink - + # check each name for child in children: @@ -458,12 +458,12 @@ class Library(ParentBase): return ':attr:`~%s`'%child.name bestlink = self.FindItem(newlink, child) - + if bestlink: return bestlink return bestlink - + def GetPythonVersion(self): @@ -500,7 +500,7 @@ class Library(ParentBase): if child.kind == object_types.KLASS: if child.is_redundant: continue - + class_dict[child.name] = (child.method_list, child.bases, chopDescription(child.docs)) # recursively scan other folders, appending results @@ -525,7 +525,7 @@ class Module(ParentBase): def __init__(self, name, kind): ParentBase.__init__(self, name, kind) - + self.filename = '' self.sphinx_file = makeSphinxFile(name) @@ -535,7 +535,7 @@ class Module(ParentBase): return self.order = object_types.PY_MODULE - + for dummy, icon, description in MODULE_TO_ICON: if icon == kind: self.obj_type = description @@ -558,11 +558,11 @@ class Module(ParentBase): stream.write('.. module:: %s\n\n' % self.name) stream.write('.. currentmodule:: %s\n\n' % self.name) stream.write('.. highlight:: python\n\n') - + header = templates.TEMPLATE_DESCRIPTION % (self.name, self.name) - + stream.write(header) - + newtext = replaceWxDot(self.docs) newtext = killEpydoc(self, newtext) @@ -574,7 +574,7 @@ class Module(ParentBase): # Remove this line to get back the inheritance diagram for a module # self.inheritance_diagram = None - + if self.kind != object_types.PACKAGE: print(('%s - %s (module)'%(spacer, self.name))) if self.inheritance_diagram: @@ -597,7 +597,7 @@ class Module(ParentBase): if count > 0: stream.write('\n\nFunctions\n------------\n\n') - + for fun in functions: if fun.is_redundant: continue @@ -626,7 +626,7 @@ class Class(ParentBase): subs = [] sups = list(obj.__bases__) - + sortedSubClasses = [] sortedSupClasses = [] @@ -650,8 +650,8 @@ class Class(ParentBase): sortedSupClasses.append(sup) - sortedSupClasses.sort() - + sortedSupClasses.sort() + for s in subs: s = repr(s) @@ -668,18 +668,18 @@ class Class(ParentBase): if len(sortedSubClasses) == 1 and sortedSubClasses[0] == 'object': sortedSubClasses = [] - + if len(sortedSupClasses) == 1 and sortedSupClasses[0] == 'object': sortedSupClasses = [] self.class_tree = make_class_tree(getclasstree(getmro(obj))) - + self.subClasses = sortedSubClasses self.superClasses = sortedSupClasses self.signature = '' self.inheritance_diagram = None - + self.order = 3 self.obj_type = 'Class' self.sphinx_file = makeSphinxFile(name) @@ -700,7 +700,7 @@ class Class(ParentBase): class_docs = replaceWxDot(self.docs) class_docs = killEpydoc(self, class_docs) - + header = templates.TEMPLATE_DESCRIPTION % (self.name, self.name) stream.write(header) stream.write(class_docs + '\n\n') @@ -736,27 +736,27 @@ class Class(ParentBase): docs = '' for line in class_docs.splitlines(True): docs += ' '*3 + line - + stream.write(docs + '\n\n') methods = self.GetItemByKind(object_types.METHOD, object_types.INSTANCE_METHOD) properties = self.GetItemByKind(object_types.PROPERTY) - + for meth in methods: meth.Write(stream) - + for prop in properties: prop.Write(stream, short_name) - + writeSphinxOutput(stream, self.sphinx_file) self.bases = self.superClasses - + def Save(self): ParentBase.Save(self) pop = -1 - + for index, child in enumerate(self.children): name = child.GetShortName() if name == '__init__': @@ -781,29 +781,29 @@ class Class(ParentBase): if self.GetShortName().startswith('__test') or '.extern.' in self.name: self.is_redundant = True - + if self.is_redundant: return methods = self.GetItemByKind(object_types.METHOD, object_types.INSTANCE_METHOD) method_list = [] - + for meth in methods: if not meth.is_redundant: method_list.append(meth.GetShortName()) self.method_list = method_list self.bases = self.superClasses - + class ChildrenBase(object): - + def __init__(self, name, kind): self.name = name self.kind = kind - self.order = 4 + self.order = 4 self.docs = '' self.comments = '' @@ -831,11 +831,11 @@ class ChildrenBase(object): def GetChildren(self): return [] - + def GetChildrenCount(self, recursively=True): - return 0 + return 0 def GetObject(self): @@ -844,7 +844,7 @@ class ChildrenBase(object): def Save(self): - + if self.docs is None: self.docs = '' @@ -855,25 +855,25 @@ class ChildrenBase(object): def ToRest(self, class_summary): pass - + class Method(ChildrenBase): def __init__(self, name, kind): ChildrenBase.__init__(self, name, kind) - + self.order = 5 - + self.arguments = [] self.signature = '' self.obj_type = 'Method/Function' - + def Save(self): - ChildrenBase.Save(self) + ChildrenBase.Save(self) newargs = [] if self.arguments and any(self.arguments[0]): @@ -884,7 +884,7 @@ class Method(ChildrenBase): self.arguments = newargs self.signature = self.signature.rstrip(':').lstrip() - + if self.signature.startswith('def '): self.signature = self.signature[4:] @@ -899,16 +899,16 @@ class Method(ChildrenBase): if '*' in self.signature: self.signature = self.signature.replace('*', r'\*') - + if not self.signature.strip(): - self.is_redundant = True + self.is_redundant = True def Write(self, stream): if self.is_redundant: return - + if self.kind == object_types.FUNCTION: stream.write('.. function:: %s\n\n'%self.signature) indent = 3*' ' @@ -924,10 +924,10 @@ class Method(ChildrenBase): if not self.docs.strip(): stream.write('\n') return - + text = '' newdocs = replaceWxDot(self.docs) - + for line in newdocs.splitlines(True): text += indent + line @@ -959,10 +959,10 @@ class Property(ChildrenBase): self.setter = item.fset.__class__.__name__ if item.fdel: self.deleter = item.fdel.__class__.__name__ - + self.docs = getdoc(item) self.comments = getcomments(item) - + self.obj_type = 'Property' self.order = 6 @@ -998,7 +998,7 @@ class Attribute(ChildrenBase): specs = str(specs) else: specs = unicode(specs) - + start, end = specs.find("'"), specs.rfind("'") specs = specs[start+1:end] @@ -1011,19 +1011,19 @@ class Attribute(ChildrenBase): try: uspecs = uspecs + 'TYPE' kind = getattr(object_types, uspecs) - except AttributeError: + except AttributeError: kind = object_types.UNKNOWNTYPE - + try: reprValue = repr(value.__class__) except (NameError, AttributeError): reprValue = '' - + if 'class' in strValue or 'class' in reprValue: kind = object_types.INSTANCETYPE ChildrenBase.__init__(self, name, kind) - + self.value = strValue self.specs = specs @@ -1034,7 +1034,7 @@ class Attribute(ChildrenBase): self.obj_type = 'Attribute' self.order = 7 - + def ToRest(self, class_summary): diff --git a/sphinxtools/modulehunter.py b/sphinxtools/modulehunter.py index 7fbd5a55..d1d20526 100644 --- a/sphinxtools/modulehunter.py +++ b/sphinxtools/modulehunter.py @@ -37,7 +37,7 @@ except ImportError: wxPath = '' basePath = '' - + for path in sys.path: if 'wx-' in path: dummy, newPath = os.path.split(path) @@ -47,9 +47,9 @@ except ImportError: if not wxPath: raise Exception('Unable to find the wx package') - + sys.path.insert(0, os.path.join(basePath, wxPath)) - + import wx print(('\nUSING VERSION: %s\n'%wx.VERSION_STRING)) @@ -73,7 +73,7 @@ else: rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: return os.path.curdir - + return os.path.join(*rel_list) @@ -103,7 +103,7 @@ def format_method(method): params = params.rstrip() else: params = signature - + return name, params @@ -163,7 +163,7 @@ def analyze_params(obj, signature): pname = p param_tuple.append((pname, pvalue, peval)) - + return signature, param_tuple @@ -171,12 +171,12 @@ def get_constructor(source): description = '' hasComma = False - + for line in source.split('\n'): if '#' in line: line = line[0:line.index('#')].strip() - + if ':' in line: hasComma = True commaPos = line.index(':') @@ -188,23 +188,23 @@ def get_constructor(source): defPos = line.index(' def ') if defPos > commaPos: break - + description += ' ' + line.strip() - + if '):' in line or ') :' in line or ') :' in line: break return description - + def inspect_source(method_class, obj, source): - description = get_constructor(source) + description = get_constructor(source) name, params = format_method(description) if name is None: return - + signature, param_tuple = analyze_params(obj, params) method_class.arguments = param_tuple @@ -214,7 +214,7 @@ def inspect_source(method_class, obj, source): method_class.kind = object_types.CLASS_METHOD elif 'staticmethod ' in description: method_class.kind = object_types.STATIC_METHOD - + def is_classmethod(instancemethod): """ Determine if an instancemethod is a classmethod. """ @@ -226,7 +226,7 @@ def is_classmethod(instancemethod): return False - + def describe_func(obj, parent_class, module_name): """ Describe the function object passed as argument. @@ -239,15 +239,15 @@ def describe_func(obj, parent_class, module_name): except AttributeError: # Funny comtypes... return - + if name.startswith('_') and '__init__' not in name: return name = parent_class.name + '.' + name - + docs = getdoc(obj) comments = getcomments(obj) - + if isfunction(obj): # in Py3 unbound methods have same type as functions. if isinstance(parent_class, Class): @@ -277,7 +277,7 @@ def describe_func(obj, parent_class, module_name): if source_code: inspect_source(klass, obj, source_code) klass.number_lines = '%d' % len(source_code.split('\n')) - + if isinstance(obj, staticmethod): klass.method = method = object_types.STATIC_METHOD @@ -303,9 +303,9 @@ def describe_func(obj, parent_class, module_name): if code is not None: klass.firstlineno = '%d' % code.co_firstlineno - + parent_class.Add(klass) - + def describe_class(obj, module_class, module_name, constants): """ @@ -319,16 +319,16 @@ def describe_class(obj, module_class, module_name, constants): return class_name = module_class.name + '.' + class_name - + docs = getdoc(obj) comments = getcomments(obj) - + obj_dict = obj.__dict__ - + klass = Class(class_name, obj) count = 0 - + for name in obj_dict: if name.startswith('_') and '__init__' not in name: @@ -336,7 +336,7 @@ def describe_class(obj, module_class, module_name, constants): if name in EXCLUDED_ATTRS: continue - + try: item = getattr(obj, name) except AttributeError: @@ -347,13 +347,13 @@ def describe_class(obj, module_class, module_name, constants): message = "ImportError from '%s.%s'.\n Exception was: %s"%(obj, name, format_traceback()) print(('\nWARNING: %s\n' % message)) continue - + if ismodule(item): continue if ismemberdescriptor(item) or isgetsetdescriptor(item): continue - + if isbuiltin(item): count += 1 elif ismethod(item) or isfunction(item) or ismethoddescriptor(item) or \ @@ -376,7 +376,7 @@ def describe_class(obj, module_class, module_name, constants): else: item_class = Attribute(name, type(item), item) klass.Add(item_class) - + if constants: item_class.is_redundant = name not in constants @@ -390,19 +390,19 @@ def describe_class(obj, module_class, module_name, constants): klass.is_redundant = True else: klass.inheritance_diagram = inheritance.InheritanceDiagram([obj], klass) - + module_class.Add(klass) try: source_code = getsource(obj) except (IOError, TypeError): source_code = '' - + if source_code: description = get_constructor(source_code) if '(' not in description and ':' in description: description = description[0:description.index(':')] - + klass.signature = description.strip() klass.number_lines = '%d' % len(source_code.split('\n')) @@ -419,20 +419,20 @@ def describe_module(module, kind, constants=[]): klass = Library(module_name) else: klass = Module(module_name, kind) - + klass.docs = getdoc(module) klass.comments = getcomments(module) - + klass.filename = module.__file__ inheritance_diagram = [] - + count = 0 - + for name in dir(module): - + if name in EXCLUDED_ATTRS: continue - + obj = getattr(module, name) if ismodule(obj): @@ -440,14 +440,14 @@ def describe_module(module, kind, constants=[]): if ismemberdescriptor(obj) or isgetsetdescriptor(obj): continue - + if isclass(obj): count += 1 describe_class(obj, klass, module_name, constants) if obj.__module__ == module.__name__: inheritance_diagram.append(obj) - + elif isbuiltin(obj): count += 1 elif ismethod(obj) or isfunction(obj) or ismethoddescriptor(obj) or \ @@ -469,12 +469,12 @@ def describe_module(module, kind, constants=[]): def Import(init_name, import_name, full_process=True): - + directory, module_name = os.path.split(init_name) dirname = os.path.dirname(directory) - + if not full_process: - path = list(sys.path) + path = list(sys.path) sys.path.insert(0, dirname) try: @@ -485,9 +485,9 @@ def Import(init_name, import_name, full_process=True): if not full_process: sys.path = path[:] - + return - + if not full_process: sys.path = path[:] try: @@ -502,7 +502,7 @@ def Import(init_name, import_name, full_process=True): print(version) return mainmod - + def PrintProgress(name, looped_names): @@ -525,7 +525,7 @@ def FindModuleType(filename): def SubImport(import_string, module, parent_class, ispkg): - + try: submod = importlib.import_module(import_string) except: @@ -542,7 +542,7 @@ def SubImport(import_string, module, parent_class, ispkg): subpath = os.path.dirname(filename) if subpath not in sys.path: sys.path.append(subpath) # *** WHY? - + if ispkg: kind = object_types.PACKAGE else: @@ -562,12 +562,12 @@ def SubImport(import_string, module, parent_class, ispkg): constants.extend([v.strip() for v in c]) else: constants.append(c.strip()) - - module_class, count = describe_module(submod, kind=kind, constants=constants) + + module_class, count = describe_module(submod, kind=kind, constants=constants) parent_class.Add(module_class) return module_class, count - + def ToRest(import_name): @@ -597,12 +597,12 @@ def ModuleHunter(init_name, import_name, version): directory, module_name = os.path.split(init_name) path = list(sys.path) - + mainmod = Import(init_name, import_name) if mainmod is None: return - + message = "Importing main library '%s'..." % import_name print('Message: %s' % message) @@ -615,13 +615,13 @@ def ModuleHunter(init_name, import_name, version): message = "Main library '%s' imported..." % library_class.name print('Message: %s' % message) - - message = "Importing sub-modules and sub-packages...\n" + + message = "Importing sub-modules and sub-packages...\n" print('Message: %s' % message) looped_names = [] ancestors_dict = {import_name: library_class} - + for importer, module_name, ispkg in pkgutil.walk_packages(path=[directory], prefix=import_name+'.', onerror=lambda x: None): @@ -630,15 +630,15 @@ def ModuleHunter(init_name, import_name, version): fromlist = splitted[-1] parent_name = '.'.join(splitted[0:-1]) - + parent_class = ancestors_dict[parent_name] module_class, count = SubImport(import_string, fromlist, parent_class, ispkg) if module_class is None: continue - + looped_names = PrintProgress(module_name, looped_names) - + if module_name not in ancestors_dict: ancestors_dict[module_name] = module_class @@ -659,7 +659,7 @@ def ModuleHunter(init_name, import_name, version): if __name__ == '__main__': argv = sys.argv[1:] - + if len(argv) == 2: init_name, import_name = argv Import(init_name, import_name, full_process=False) @@ -667,6 +667,6 @@ if __name__ == '__main__': init_name, import_name, version, save_dir = argv ModuleHunter(init_name, import_name, version, save_dir) - - - + + + diff --git a/sphinxtools/postprocess.py b/sphinxtools/postprocess.py index a80c63c5..2ebd9738 100644 --- a/sphinxtools/postprocess.py +++ b/sphinxtools/postprocess.py @@ -32,7 +32,7 @@ def makeHeadings(): Generates the "headings.inc" file containing the substitution reference for the small icons used in the Sphinx titles, sub-titles and so on. - The small icons are stored into the ``SPHINX_IMAGES_ROOT`` folder. + The small icons are stored into the ``SPHINX_IMAGES_ROOT`` folder. .. note:: The "headings.inc" file is created in the ``SPHINXROOT`` folder (see `sphinxtools/constants.py`). @@ -40,7 +40,7 @@ def makeHeadings(): images = glob.glob(SPHINX_IMAGES_ROOT + '/*.png') images.sort() - + heading_file = os.path.join(SPHINXROOT, 'headings.inc') text = "" @@ -55,7 +55,7 @@ def makeHeadings(): text += templates.TEMPLATE_HEADINGS % (name, os.path.normpath(rel_path), width) - writeIfChanged(heading_file, text) + writeIfChanged(heading_file, text) # ----------------------------------------------------------------------- # @@ -69,7 +69,7 @@ def genIndexes(sphinxDir): """ pklfiles = glob.glob(sphinxDir + '/*.pkl') - + for file in pklfiles: if file.endswith('functions.pkl'): reformatFunctions(file) @@ -98,9 +98,9 @@ def buildEnumsAndMethods(sphinxDir): pf = PickleFile(os.path.join(sphinxDir, 'class_summary.pkl')) class_summary = pf.read() - + unreferenced_classes = {} - + textfiles = glob.glob(sphinxDir + '/*.txt') enum_files = glob.glob(sphinxDir + '/*.enumeration.txt') @@ -111,10 +111,10 @@ def buildEnumsAndMethods(sphinxDir): for enum in enum_base: enum_dict[':meth:`%s`'%enum] = ':ref:`%s`'%enum - + for input in textfiles: - - fid = textfile_open(input, 'rt') + + fid = textfile_open(input, 'rt') orig_text = text = fid.read() fid.close() @@ -129,7 +129,7 @@ def buildEnumsAndMethods(sphinxDir): lindex = text.index(start) rindex = text.index(end) text = text[0:lindex] + text[rindex:] - + # Replace the "Perl Note" stuff, we don't need it newtext = '' for line in text.splitlines(): @@ -138,10 +138,10 @@ def buildEnumsAndMethods(sphinxDir): newtext += line + '\n' text = newtext - + text = findInherited(input, class_summary, enum_base, text) text, unreferenced_classes = removeUnreferenced(input, class_summary, enum_base, unreferenced_classes, text) - + text = text.replace('non-NULL', 'not ``None``') text = text.replace(',,', ',').replace(', ,', ',') @@ -151,22 +151,22 @@ def buildEnumsAndMethods(sphinxDir): # Replacement for wx.grid stuff text = text.replace(' int *,', ' int,') - + if 'DocstringsGuidelines' not in input: # Leave the DocstringsGuidelines.txt file alone on these ones - text = text.replace(':note:', '.. note::') + text = text.replace(':note:', '.. note::') text = text.replace(':see:', '.. seealso::') - + text = text.replace('`String`&', 'string') text = text.replace('See also\n', '.. seealso:: ') # Avoid Sphinx warnings on wx.TreeCtrl text = text.replace('**( `', '** ( `') - + # Replace EmptyString stuff for item in ['wx.EmptyString', 'EmptyString']: text = text.replace(item, '""') - + # Replace ArrayXXX stuff... for cpp in ['ArrayString()', 'ArrayInt()', 'ArrayDouble()']: text = text.replace(cpp, '[]') @@ -183,7 +183,7 @@ def buildEnumsAndMethods(sphinxDir): text = addSpacesToLinks(text) if text != orig_text: - fid = textfile_open(input, 'wt') + fid = textfile_open(input, 'wt') fid.write(text) fid.close() @@ -202,12 +202,12 @@ def buildEnumsAndMethods(sphinxDir): keys = list(unreferenced_classes.keys()) keys.sort() - fid = textfile_open(os.path.join(SPHINXROOT, 'unreferenced_classes.inc'), 'wt') + fid = textfile_open(os.path.join(SPHINXROOT, 'unreferenced_classes.inc'), 'wt') fid.write('\n') fid.write('='*50 + ' ' + '='*50 + '\n') fid.write('%-50s %-50s\n'%('Reference', 'File Name(s)')) fid.write('='*50 + ' ' + '='*50 + '\n') - + for key in keys: fid.write('%-50s %-50s\n'%(key, ', '.join(unreferenced_classes[key]))) @@ -215,7 +215,7 @@ def buildEnumsAndMethods(sphinxDir): fid.close() print((warn%(len(keys)))) - + # ----------------------------------------------------------------------- # @@ -230,24 +230,24 @@ def findInherited(input, class_summary, enum_base, text): regex = re.findall(r':meth:\S+', text) for regs in regex: - + hasdot = '.' in regs hastilde = '~' in regs if regs.count('`') < 2: continue - + full_name = regs[regs.index('`')+1:regs.rindex('`')] full_name = full_name.replace('~', '') curr_class = dummy = os.path.split(os.path.splitext(input)[0])[1] - + if hasdot: newstr = full_name.split('.') curr_class, meth_name = '.'.join(newstr[0:-1]), newstr[-1] else: meth_name = full_name - + if meth_name == curr_class: newtext = ':ref:`%s`'%meth_name text = text.replace(regs, newtext, 1) @@ -258,15 +258,15 @@ def findInherited(input, class_summary, enum_base, text): ## newtext = ':ref:`%s`'%meth_name ## text = text.replace(regs, newtext, 1) ## continue - + if meth_name in CONSTANT_INSTANCES: text = text.replace(regs, '``%s``'%meth_name, 1) continue - + if curr_class not in class_summary: continue - + methods, bases, short_description = class_summary[curr_class] methods = [m.split('.')[-1] for m in methods] @@ -287,10 +287,10 @@ def findInherited(input, class_summary, enum_base, text): submethods, subbases, subshort = class_summary[cls] short_submethods = [m.split('.')[-1] for m in submethods] - + if meth_name in short_submethods: if not hasdot: - newstr = ':meth:`~%s.%s`'%(cls, meth_name) + newstr = ':meth:`~%s.%s`'%(cls, meth_name) elif not hastilde: newstr = ':meth:`%s.%s <%s.%s>`'%(curr_class, meth_name, cls, meth_name) elif hasdot: @@ -298,12 +298,12 @@ def findInherited(input, class_summary, enum_base, text): else: newstr = ':meth:`%s.%s <%s.%s>`'%(curr_class, meth_name, cls, meth_name) - break + break if newstr: text = text.replace(regs, newstr, 1) - return text + return text # ----------------------------------------------------------------------- # @@ -311,7 +311,7 @@ def findInherited(input, class_summary, enum_base, text): def removeUnreferenced(input, class_summary, enum_base, unreferenced_classes, text): regex = re.findall(':ref:`(.*?)`', text) - + for reg in regex: if reg in class_summary or reg in enum_base: continue @@ -335,10 +335,10 @@ def removeUnreferenced(input, class_summary, enum_base, unreferenced_classes, te split = os.path.split(input)[1] if split not in unreferenced_classes[reg]: unreferenced_classes[reg].append(split) - + text = text.replace(':ref:`%s`'%reg, '`%s` '%reg, 1) - return text, unreferenced_classes + return text, unreferenced_classes # ----------------------------------------------------------------------- # @@ -358,10 +358,10 @@ def reformatFunctions(file): text_file = os.path.splitext(file)[0] + '.txt' local_file = os.path.split(file)[1] - + if not newer(file, text_file): return - + pf = PickleFile(file) functions = pf.read() @@ -404,7 +404,7 @@ def reformatFunctions(file): for fun in names: text += functions[fun] + '\n' - + writeIfChanged(text_file, text) # ----------------------------------------------------------------------- # @@ -448,7 +448,7 @@ def makeModuleIndex(sphinxDir, file): text = '' if module: text += '\n\n.. module:: %s\n\n' % module - + text += templates.TEMPLATE_CLASS_INDEX % (label, module_docstring) text += 80*'=' + ' ' + 80*'=' + '\n' @@ -501,7 +501,7 @@ def makeModuleIndex(sphinxDir, file): toctree += ' %s\n' % item text += templates.TEMPLATE_TOCTREE % toctree - + writeIfChanged(text_file, text) @@ -530,7 +530,7 @@ def genGallery(): for folder in platforms: plat_folder = os.path.join(image_folder, folder) os.chdir(plat_folder) - + image_files[folder] = glob.glob('*.png') os.chdir(pwd) @@ -547,7 +547,7 @@ def genGallery(): keys.sort() text = '' - + for key in keys: possible_png = key html = html_files[possible_png] @@ -566,7 +566,7 @@ def genGallery(): gallery = os.path.join(SPHINXROOT, '_templates', 'gallery.html') writeIfChanged(gallery, templates.TEMPLATE_GALLERY % text) - + # ----------------------------------------------------------------------- # @@ -585,7 +585,7 @@ def addPrettyTable(text): text = text.replace('class="docutils">', othertext) text = text.replace('class="last docutils">', othertext) - + return text @@ -595,13 +595,13 @@ def classToFile(line): if '–' not in line: return line - - if 'href' in line and '
  • ' in line and '(' in line and ')' in line: + + if 'href' in line and '
  • ' in line and '(' in line and ')' in line: indx1 = line.index('href=') if 'title=' in line: indx2 = line.rindex('title=') paramdesc = line[indx1+6:indx2-2] - + if '.html#' in paramdesc: newparamdesc = paramdesc[:] lower = paramdesc.index('#') + 1 @@ -642,9 +642,9 @@ def addJavaScript(text): index = text.rfind('') newtext = text[0:index] + jsCode + text[index:] - return newtext - - + return newtext + + # ----------------------------------------------------------------------- # def postProcess(folder): @@ -661,7 +661,7 @@ def postProcess(folder): for indx, enum in enumerate(enum_base): html_file = os.path.split(enum_files[indx])[1] - base = enum.split('.')[-1] + base = enum.split('.')[-1] new = '(%s)'%(html_file, base, base) enum_dict['(%s)'%enum] = new @@ -671,7 +671,7 @@ def postProcess(folder): continue methods_done = properties_done = False - + fid = open(files, "rt") orig_text = text = fid.read() fid.close() @@ -682,7 +682,7 @@ def postProcess(folder): text = changeSVNRevision(text) else: text = text.replace('class="headerimage"', 'class="headerimage-noshow"') - + text = text.replace('–

    ', '– ') text = text.replace('

    overload

    overloadOverloaded Implementations', 'Overloaded Implementations') @@ -696,30 +696,30 @@ def postProcess(folder): newtext = '' splitted_text = text.splitlines() len_split = len(splitted_text) - + for index, line in enumerate(splitted_text): if '

    ' - + if index < len_split - 1: - if line.strip() == '

    ' or line.strip() == '


    ': + if line.strip() == '

    ' or line.strip() == '


    ': next_line = splitted_text[index+1] stripline = next_line.strip() - + if (stripline == '
    ' or stripline == '
    ' \ or stripline == '
    ') and not methods_done: line = '

    Methods

    ' + '\n' + line methods_done = True - + elif stripline == '
    ' and not properties_done: line = '

    Properties

    ' + '\n' + line properties_done = True if ' ' in line and '–' in line: line = line.replace(' ', '') - - newtext += line + '\n' + + newtext += line + '\n' for old, new in list(enum_dict.items()): newtext = newtext.replace(old, new) @@ -750,12 +750,12 @@ def tooltipsOnInheritance(text, class_summary): graphviz = graphviz[0] original = graphviz[:] - + html_links = re.findall('href="(.*?)"', graphviz) titles = re.findall('title="(.*?)"', graphviz) ReST = ['ref', 'class', 'mod', 'meth', 'attr'] - + for link, title in zip(html_links, titles): if 'http://' in link: # No tooltip for this one @@ -771,7 +771,7 @@ def tooltipsOnInheritance(text, class_summary): if not short_description.strip(): # Leave the default tooltip continue - + replace_string = 'title="%s"'%title description = short_description.replace('\n', ' ').lstrip() @@ -786,4 +786,3 @@ def tooltipsOnInheritance(text, class_summary): return text - \ No newline at end of file diff --git a/sphinxtools/templates.py b/sphinxtools/templates.py index efb857e3..e237f6aa 100644 --- a/sphinxtools/templates.py +++ b/sphinxtools/templates.py @@ -35,7 +35,7 @@ TEMPLATE_INHERITANCE = ''' .. raw:: html
    - + Inheritance diagram for %s %s:
    @@ -63,21 +63,21 @@ TEMPLATE_APPEARANCE = ''' .. figure:: _static/images/widgets/fullsize/wxmsw/%s :alt: wxMSW :figclass: floatleft - + **wxMSW** .. figure:: _static/images/widgets/fullsize/wxmac/%s :alt: wxMAC :figclass: floatright - + **wxMAC** .. figure:: _static/images/widgets/fullsize/wxgtk/%s :alt: wxGTK :figclass: floatcenter - + **wxGTK** @@ -141,7 +141,7 @@ TEMPLATE_PROPERTY_SUMMARY = ''' TEMPLATE_API = ''' |api| Class API =============== - + ''' # Template for the standalone function summary for a module (wx, wx.dataview diff --git a/sphinxtools/utilities.py b/sphinxtools/utilities.py index 2d7041cf..3fbd1027 100644 --- a/sphinxtools/utilities.py +++ b/sphinxtools/utilities.py @@ -45,9 +45,9 @@ class ODict(UserDict): in the dict) is not considered to create a new item, and does not affect the position of that key in the order. However, if an item is deleted, then a new item with the same key is added, this is considered a new item. - + """ - + def __init__(self, dict = None): self._keys = [] UserDict.__init__(self, dict) @@ -147,7 +147,7 @@ def underscore2Capitals(string): :param string `string`: the string to be analyzed. - :rtype: `string` + :rtype: `string` """ items = string.split('_')[1:] @@ -155,7 +155,7 @@ def underscore2Capitals(string): for item in items: newstr += item.capitalize() - + return newstr @@ -199,7 +199,7 @@ def replaceCppItems(line): # Avoid replacing standalone '&&' and similar for cpp in CPP_ITEMS[0:2]: item = item.replace(cpp, '') - + newstr.append(item) newstr = ''.join(newstr) @@ -229,7 +229,7 @@ def pythonizeType(ptype, is_param): ptype = ptype[3:] # *** else: ptype = wx2Sphinx(replaceCppItems(ptype))[1] - + ptype = ptype.replace('::', '.').replace('*&', '') ptype = ptype.replace('int const', 'int') ptype = ptype.replace('Uint32', 'int').replace('**', '').replace('Int32', 'int') @@ -238,15 +238,15 @@ def pythonizeType(ptype, is_param): for item in ['unsignedchar', 'unsignedint', 'unsignedlong', 'unsigned']: ptype = ptype.replace(item, 'int') - - ptype = ptype.strip() + + ptype = ptype.strip() ptype = removeWxPrefix(ptype) if '. wx' in ptype: #*** ptype = ptype.replace('. wx', '.') plower = ptype.lower() - + if plower == 'double': ptype = 'float' @@ -255,13 +255,13 @@ def pythonizeType(ptype, is_param): if plower in ['coord', 'byte', 'fileoffset', 'short', 'time_t', 'intptr', 'uintptr', 'windowid']: ptype = 'int' - + if plower in ['longlong']: ptype = 'long' - + cpp = ['ArrayString', 'ArrayInt', 'ArrayDouble'] python = ['list of strings', 'list of integers', 'list of floats'] - + for c, p in zip(cpp, python): ptype = ptype.replace(c, p) @@ -270,7 +270,7 @@ def pythonizeType(ptype, is_param): if 'FileName' in ptype: ptype = 'string' - + if ptype.endswith('&'): ptype = ptype[0:-1] if ' ' not in ptype: @@ -301,7 +301,7 @@ def convertToPython(text): 3. Uppercase constants (i.e., like ID_ANY, HORIZONTAL and so on) are converted into inline literals (i.e., ``ID_ANY``, ``HORIZONTAL``). 4. The "wx" prefix is removed from all the words in the input `text`. #*** - + :param string `text`: any string. :rtype: `string` @@ -311,7 +311,7 @@ def convertToPython(text): newlines = [] unwanted = ['Include file', '#include'] - + for line in text.splitlines(): newline = [] @@ -324,22 +324,22 @@ def convertToPython(text): spacer = ' '*(len(line) - len(line.lstrip())) line = replaceCppItems(line) - + for word in RE_KEEP_SPACES.split(line): if word == VERSION: newline.append(word) continue - + newword = word for s in PUNCTUATION: newword = newword.replace(s, "") - + if newword in VALUE_MAP: word = word.replace(newword, VALUE_MAP[newword]) newline.append(word) continue - + if newword not in IGNORE and not newword.startswith('wx.'): word = removeWxPrefix(word) newword = removeWxPrefix(newword) @@ -351,7 +351,7 @@ def convertToPython(text): word = "`%s`" % word newline.append(word) continue - + if (newword.upper() == newword and newword not in PUNCTUATION and newword not in IGNORE and len(newword.strip()) > 1 and not isNumeric(newword) and newword not in ['DC', 'GCDC']): @@ -372,7 +372,7 @@ def convertToPython(text): formatted = formatted.replace('\\', '\\\\') return formatted - + # ----------------------------------------------------------------------- # @@ -387,15 +387,15 @@ def findDescendants(element, tag, descendants=None): is the first call to the function. :rtype: `list` - + .. note:: This is a recursive function, and it is only used in the `etgtools.extractors.py` script. """ - + if descendants is None: descendants = [] - + for childElement in element: if childElement.tag == tag: descendants.append(childElement) @@ -403,7 +403,7 @@ def findDescendants(element, tag, descendants=None): descendants = findDescendants(childElement, tag, descendants) return descendants - + # ----------------------------------------------------------------------- # @@ -426,7 +426,7 @@ def findControlImages(elementOrString): :returns: A list of image paths, every element of it representing a screenshot on a different platform. An empty list if returned if no screenshots have been found. - + .. note:: If a screenshot doesn't exist for one (or more) platform but it exists for others, the missing images will be replaced by the "no_appearance.png" file (you can find it inside the ``WIDGETS_IMAGES_ROOT`` folder. @@ -452,30 +452,30 @@ def findControlImages(elementOrString): png_file = class_name + '.png' appearance[sub_folder] = '' - + possible_image = os.path.join(image_folder, sub_folder, png_file) new_path = os.path.join(WIDGETS_IMAGES_ROOT, sub_folder) - py_png_file = py_class_name + '.png' + py_png_file = py_class_name + '.png' new_file = os.path.join(new_path, py_png_file) if os.path.isfile(new_file): appearance[sub_folder] = py_png_file - + elif os.path.isfile(possible_image): if not os.path.isdir(new_path): os.makedirs(new_path) - + if not os.path.isfile(new_file): shutil.copyfile(possible_image, new_file) appearance[sub_folder] = py_png_file - + if not any(list(appearance.values())): return [] - + for sub_folder, image in list(appearance.items()): if not image: appearance[sub_folder] = '../no_appearance.png' @@ -506,8 +506,8 @@ def makeSummary(class_name, item_list, template, kind, add_tilde=True): substr = ':%s:`~%s`'%(kind, method) maxlen = max(maxlen, len(substr)) - maxlen = max(80, maxlen) - + maxlen = max(80, maxlen) + summary = '='*maxlen + ' ' + '='*80 + "\n" format = '%-' + str(maxlen) + 's %s' @@ -531,17 +531,17 @@ def makeSummary(class_name, item_list, template, kind, add_tilde=True): if '===' in new_docs: new_docs = '' - + elif new_docs.rstrip().endswith(':'): # Avoid Sphinx warnings new_docs = new_docs.rstrip(':') - + summary += format%(substr, new_docs) + '\n' summary += '='*maxlen + ' ' + '='*80 + "\n" return template % summary - + # ----------------------------------------------------------------------- # @@ -590,16 +590,16 @@ def chopDescription(text): """ description = '' - + for line in text.splitlines(): line = line.strip() - + if not line or line.startswith('..') or line.startswith('|'): continue description = line break - + return description @@ -650,7 +650,7 @@ def pickleItem(description, current_module, name, kind): :param string `name`: the function/class name. :param string `kind`: can be `function` or `class`. """ - + if kind == 'function': pickle_file = os.path.join(SPHINXROOT, current_module + 'functions.pkl') else: @@ -724,7 +724,7 @@ def wx2Sphinx(name): imm = ItemModuleMap() if lookup in imm: fullname = imm[lookup] + lookup + remainder - + return newname, fullname @@ -771,7 +771,7 @@ def formatContributedSnippets(kind, contrib_snippets): text = TEMPLATE_CONTRIB else: text = '\n' + spacer + '|contributed| **Contributed Examples:**\n\n' - + for indx, snippet in enumerate(contrib_snippets): with open(snippet, 'rt') as fid: lines = fid.readlines() @@ -791,7 +791,7 @@ def formatContributedSnippets(kind, contrib_snippets): text += RAW_2%(spacer, spacer) text += '\n\n%s|\n\n'%spacer - + return text @@ -809,7 +809,7 @@ def formatExternalLink(fullname, inheritance=False): i.e. `exceptions.Exception` or `threading.Thread`; :param bool `inheritance`: ``True`` if the call is coming from :mod:`inheritance`, ``False`` otherwise. - """ + """ if fullname.count('.') == 0: if not inheritance: @@ -819,7 +819,7 @@ def formatExternalLink(fullname, inheritance=False): parts = fullname.split('.') possible_external = parts[-2] + '.' real_name = '.'.join(parts[-2:]) - + if possible_external.startswith('_'): # funny ctypes... possible_external = possible_external[1:] @@ -830,7 +830,7 @@ def formatExternalLink(fullname, inheritance=False): return ':class:`%s`'%fullname return '' - + base_address = EXTERN_INHERITANCE[possible_external] if 'numpy' in real_name: @@ -849,5 +849,5 @@ def formatExternalLink(fullname, inheritance=False): def isPython3(): """ Returns ``True`` if we are using Python 3.x. """ - return sys.version_info >= (3, ) + return sys.version_info >= (3, )