From cfed6ce4df33bce7b659e5fe4b446d5d8a5cdbc4 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 7 Jun 2016 16:43:04 -0700 Subject: [PATCH] Various updates to use fullnames in wx.lib, fix links back to the compiled modules, various source cleanup, etc. --- TODO.rst | 1 - sphinxtools/librarydescription.py | 57 ++++++++----------------- sphinxtools/modulehunter.py | 71 +++++++++++++++---------------- sphinxtools/utilities.py | 4 +- 4 files changed, 54 insertions(+), 79 deletions(-) diff --git a/TODO.rst b/TODO.rst index 318eebcb..087a01cf 100644 --- a/TODO.rst +++ b/TODO.rst @@ -98,7 +98,6 @@ to be untangled: docs, but IMO is a bit annoying in other situations. Maybe just make it a smaller font, or move it somewhere less noticeable? - * Use fullnames on the inheritance hierarchy diagrams diff --git a/sphinxtools/librarydescription.py b/sphinxtools/librarydescription.py index 2fb4c526..8fe97ffb 100644 --- a/sphinxtools/librarydescription.py +++ b/sphinxtools/librarydescription.py @@ -1,13 +1,10 @@ import sys import os -import operator import re if sys.version_info < (3,): - import cPickle as pickle from StringIO import StringIO else: - import pickle from io import StringIO from inspect import getmro, getclasstree, getdoc, getcomments @@ -56,7 +53,7 @@ def generic_summary(libraryItem, stream): templ = [templates.TEMPLATE_STD_FUNCTION_SUMMARY, templates.TEMPLATE_STD_CLASS_SUMMARY] refs = ['func', 'ref'] - add_tilde = [True, False] + add_tilde = [True, True] elif libraryItem.kind == object_types.KLASS: write_toc = False @@ -98,17 +95,11 @@ def generic_summary(libraryItem, stream): def makeSphinxFile(name): - return os.path.join(os.getcwd(), 'docs', 'sphinx', '%s.txt'%name) + return os.path.join(os.getcwd(), 'docs', 'sphinx', '%s.txt' % name) def replaceWxDot(text): - # Double ticks with 'wx.' in them - text = re.sub(r'``wx\.(.*?)``', r'``\1`` ', text) - - # Signle ticks with 'wx.' in them... try and referencing them - text = re.sub(r'`wx\.(.*?)`', r'`\1` ', text) - # Masked is funny... text = text.replace('', '') @@ -121,7 +112,7 @@ def replaceWxDot(text): if new in [':keyword', ':param']: if not space_added: space_added = True - new_with_newline = '\n%s'%new + new_with_newline = '\n%s' % new text = text.replace(old, new_with_newline, 1) text = text.replace(old, new) @@ -235,16 +226,14 @@ def killEpydoc(klass, newtext): newlink = regex[start+1:end] if 'wx.' in regex or 'wx' in regex: - newlink = newlink.replace('wx.', '') - newlink = newlink.replace('wx', '') - newlink = ':class:`%s`'%newlink.strip() + newlink = ':class:`%s`' % newlink.strip() else: - newlink = '`%s`'%newlink + newlink = '`%s`' % newlink elif 'I{' in regex: # It's an inclined text newlink = regex[start+1:end] - newlink = ' `%s` '%newlink + newlink = ' `%s` ' % newlink elif 'L{' in regex: # Some kind of link, but we can't figure it out @@ -253,7 +242,7 @@ def killEpydoc(klass, newtext): if newlink.upper() == newlink: # Use double backticks - newlink = '``%s``'%newlink + newlink = '``%s``' % newlink else: # Try and reference it bestlink = findBestLink(klass, newlink) @@ -483,7 +472,7 @@ class Library(ParentBase): def ToRest(self, class_summary): - print(('\n\nReST-ifying %s...\n\n'%self.base_name)) + print('\n\nReST-ifying %s...\n\n' % self.base_name) stream = StringIO() header = templates.TEMPLATE_DESCRIPTION%(self.base_name, self.base_name) @@ -559,18 +548,18 @@ class Module(ParentBase): if self.is_redundant: return - + stream = StringIO() label = 'Module' if self.kind == object_types.PACKAGE: label = 'Package' - stream.write('.. module:: %s\n\n'%self.name) - #stream.write('.. currentmodule:: %s\n\n'%self.name) + 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, '%s'%self.GetShortName()) + header = templates.TEMPLATE_DESCRIPTION % (self.name, self.name) stream.write(header) @@ -594,7 +583,7 @@ class Module(ParentBase): image_desc = templates.TEMPLATE_INHERITANCE % ('module', short_name, png, short_name, map) stream.write(image_desc) else: - print(('%s - %s (package)'%(spacer, self.name))) + print('%s - %s (package)' % (spacer, self.name)) generic_summary(self, stream) @@ -649,11 +638,7 @@ class Class(ParentBase): if ' at ' in sup: sup = sup[0:sup.index(' at ')].strip() - if 'wx._' in sup: - name_parts = sup.split('.') - sup = name_parts[-1] - - sortedSupClasses.append(sup.replace('wx.', '')) + sortedSupClasses.append(sup) sortedSupClasses.sort() @@ -667,11 +652,7 @@ class Class(ParentBase): else: cls = s - if 'wx._' in cls: - name_parts = cls.split('.') - cls = name_parts[-1] - - sortedSubClasses.append(cls.replace('wx.', '')) + sortedSubClasses.append(cls) sortedSubClasses.sort() @@ -704,13 +685,13 @@ class Class(ParentBase): parts = self.name.split('.') current_module = '.'.join(parts[0:-1]) - #stream.write('.. currentmodule:: %s\n\n'%current_module) + stream.write('.. currentmodule:: %s\n\n' % current_module) stream.write('.. highlight:: python\n\n') class_docs = replaceWxDot(self.docs) class_docs = killEpydoc(self, class_docs) - header = templates.TEMPLATE_DESCRIPTION%(self.name, self.GetShortName()) + header = templates.TEMPLATE_DESCRIPTION % (self.name, self.name) stream.write(header) stream.write(class_docs + '\n\n') @@ -776,7 +757,7 @@ class Class(ParentBase): init = self.children.pop(pop) self.children.insert(0, init) - self.signature = self.signature.replace('wx.', '') + #self.signature = self.signature.replace('wx.', '') self.signature = self.signature.rstrip(':').lstrip('class ') if ' def __init__' in self.signature: @@ -892,8 +873,6 @@ class Method(ChildrenBase): newargs.append((name, repr_val, eval_val)) self.arguments = newargs - - self.signature = self.signature.replace('wx.', '') self.signature = self.signature.rstrip(':').lstrip() if self.signature.startswith('def '): diff --git a/sphinxtools/modulehunter.py b/sphinxtools/modulehunter.py index c571d76c..0881fac1 100644 --- a/sphinxtools/modulehunter.py +++ b/sphinxtools/modulehunter.py @@ -6,18 +6,12 @@ import os import sys -import glob import types -import imp +import importlib import traceback import pkgutil -if sys.version_info < (3,): - import cPickle as pickle -else: - import pickle - from buildtools.config import phoenixDir from inspect import getargspec, ismodule, getdoc, getmodule, getcomments, isfunction @@ -127,7 +121,8 @@ def analyze_params(obj, signature): try: arginfo = getargspec(obj) - except TypeError: + # TODO: Switch to getfullargspec + except (TypeError, ValueError): arginfo = None pevals = {} @@ -254,7 +249,11 @@ def describe_func(obj, parent_class, module_name): comments = getcomments(obj) if isfunction(obj): - method = object_types.FUNCTION + # in Py3 unbound methods have same type as functions. + if isinstance(parent_class, Class): + method = object_types.METHOD + else: + method = object_types.FUNCTION elif ismethod(obj): method = object_types.METHOD elif ismethoddescriptor(obj): @@ -277,12 +276,13 @@ 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')) + klass.number_lines = '%d' % len(source_code.split('\n')) if isinstance(obj, staticmethod): klass.method = method = object_types.STATIC_METHOD try: + code = None if method in [object_types.METHOD, object_types.METHOD_DESCRIPTOR, object_types.INSTANCE_METHOD]: if isPython3(): code = obj.__func__.__code__ @@ -295,14 +295,14 @@ def describe_func(obj, parent_class, module_name): code = obj.im_func.func_code else: if isPython3(): - obj.__code__ + code = obj.__code__ else: code = obj.func_code except AttributeError: code = None if code is not None: - klass.firstlineno = '%d'%code.co_firstlineno + klass.firstlineno = '%d' % code.co_firstlineno parent_class.Add(klass) @@ -318,6 +318,9 @@ def describe_class(obj, module_class, module_name, constants): if class_name == 'object': return + if 'GenBitmapButton' in class_name: + print('GenBitmapButton') + class_name = module_class.name + '.' + class_name docs = getdoc(obj) @@ -404,7 +407,7 @@ def describe_class(obj, module_class, module_name, constants): description = description[0:description.index(':')] klass.signature = description.strip() - klass.number_lines = '%d'%len(source_code.split('\n')) + klass.number_lines = '%d' % len(source_code.split('\n')) def describe_module(module, kind, constants=[]): @@ -477,26 +480,17 @@ def Import(init_name, import_name, full_process=True): path = list(sys.path) sys.path.insert(0, dirname) - f = None - try: - - f, filename, description = imp.find_module(import_name, [dirname]) - mainmod = imp.load_module(import_name, f, filename, description) - + mainmod = importlib.import_module(import_name) except (ImportError, NameError): - message = format_traceback() - print(('Error: %s'%message)) + print('Error: %s' % message) if not full_process: sys.path = path[:] return - if f: - f.close() - if not full_process: sys.path = path[:] try: @@ -536,7 +530,7 @@ def FindModuleType(filename): def SubImport(import_string, module, parent_class, ispkg): try: - submod = __import__(import_string, fromlist=[module]) + submod = importlib.import_module(import_string) except: # pubsub and Editra can be funny sometimes... message = "Unable to import module/package '%s.%s'.\n Exception was: %s"%(import_string, module, format_traceback()) @@ -550,7 +544,7 @@ def SubImport(import_string, module, parent_class, ispkg): subpath = os.path.dirname(filename) if subpath not in sys.path: - sys.path.append(subpath) + sys.path.append(subpath) # *** WHY? if ispkg: kind = object_types.PACKAGE @@ -561,8 +555,9 @@ def SubImport(import_string, module, parent_class, ispkg): if kind in [object_types.PY_MODULE, object_types.PACKAGE]: - contents = open(filename, 'rt').read() - consts = CONSTANT_RE.findall(contents) + with open(filename, 'rt') as f: + contents = f.read() + consts = CONSTANT_RE.findall(contents) for c in consts: if ',' in c: @@ -580,7 +575,7 @@ def SubImport(import_string, module, parent_class, ispkg): def ToRest(import_name): sphinxDir = os.path.join(phoenixDir(), 'docs', 'sphinx') - pickle_file = os.path.join(sphinxDir, 'wx%s.pkl'%import_name) + pickle_file = os.path.join(sphinxDir, '%s.pkl' % import_name) pf = PickleFile(pickle_file) library_class = pf.read() @@ -594,8 +589,11 @@ def ToRest(import_name): def ModuleHunter(init_name, import_name, version): sphinxDir = os.path.join(phoenixDir(), 'docs', 'sphinx') - pickle_file = os.path.join(sphinxDir, 'wx%s.pkl'%import_name) - + pickle_file = os.path.join(sphinxDir, '%s.pkl' % import_name) + + # TODO: instead of just skipping to generating the ReST files, do some + # dependency checking and rescan those files that are newer than the + # pickle file. if os.path.isfile(pickle_file): ToRest(import_name) return @@ -608,8 +606,8 @@ def ModuleHunter(init_name, import_name, version): if mainmod is None: return - message = "Importing main library '%s'..."%import_name - print(('Message: %s'%message)) + message = "Importing main library '%s'..." % import_name + print('Message: %s' % message) module_name = os.path.splitext(getfile(mainmod))[0] + '.py' contents = open(module_name, 'rt').read() @@ -618,11 +616,11 @@ def ModuleHunter(init_name, import_name, version): library_class, count = describe_module(mainmod, kind=object_types.LIBRARY, constants=constants) library_class.name = '%s-%s'%(import_name, version) - message = "Main library '%s' imported..."%library_class.name - print(('Message: %s'%message)) + message = "Main library '%s' imported..." % library_class.name + print('Message: %s' % message) message = "Importing sub-modules and sub-packages...\n" - print(('Message: %s'%message)) + print('Message: %s' % message) looped_names = [] ancestors_dict = {import_name: library_class} @@ -630,7 +628,6 @@ def ModuleHunter(init_name, import_name, version): for importer, module_name, ispkg in pkgutil.walk_packages(path=[directory], prefix=import_name+'.', onerror=lambda x: None): - import_string = module_name splitted = module_name.split('.') diff --git a/sphinxtools/utilities.py b/sphinxtools/utilities.py index e19099be..9477271e 100644 --- a/sphinxtools/utilities.py +++ b/sphinxtools/utilities.py @@ -26,7 +26,6 @@ else: string_base = str # Phoenix-specific imports -from etgtools.item_module_map import ItemModuleMap from .templates import TEMPLATE_CONTRIB from .constants import IGNORE, PUNCTUATION, MODULENAME_REPLACE from .constants import CPP_ITEMS, VERSION, VALUE_MAP @@ -304,6 +303,7 @@ def convertToPython(text): :rtype: `string` """ from etgtools.tweaker_tools import removeWxPrefix + from etgtools.item_module_map import ItemModuleMap newlines = [] unwanted = ['Include file', '#include'] @@ -699,7 +699,7 @@ def wx2Sphinx(name): if '.' in newname and len(newname) > 3: lookup, remainder = newname.split('.') - remainder = '.%s'%remainder + remainder = '.%s' % remainder else: lookup = newname remainder = ''