mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Improve error handling.
This commit is contained in:
parent
f4cff4371e
commit
3d4963ae02
@ -14,7 +14,7 @@ import time
|
||||
from os import path
|
||||
|
||||
from sphinx.pycode import pytree
|
||||
from sphinx.pycode.pgen2 import driver, token
|
||||
from sphinx.pycode.pgen2 import driver, token, parse
|
||||
|
||||
|
||||
# load the Python grammar
|
||||
@ -78,6 +78,14 @@ class ClassAttrVisitor(pytree.NodeVisitor):
|
||||
return
|
||||
|
||||
|
||||
class PycodeError(Exception):
|
||||
def __str__(self):
|
||||
res = self.args[0]
|
||||
if len(self.args) > 1:
|
||||
res += ' (exception was: %r)' % self.args[1]
|
||||
return res
|
||||
|
||||
|
||||
class ModuleAnalyzer(object):
|
||||
|
||||
def __init__(self, tree, modname, srcname):
|
||||
@ -91,48 +99,55 @@ class ModuleAnalyzer(object):
|
||||
|
||||
@classmethod
|
||||
def for_file(cls, filename, modname):
|
||||
# XXX if raises
|
||||
try:
|
||||
fileobj = open(filename, 'r')
|
||||
except Exception, err:
|
||||
raise PycodeError('error opening %r' % filename, err)
|
||||
try:
|
||||
try:
|
||||
return cls(pydriver.parse_stream(fileobj), modname, filename)
|
||||
except parse.ParseError, err:
|
||||
raise PycodeError('error parsing %r' % filename, err)
|
||||
finally:
|
||||
fileobj.close()
|
||||
|
||||
@classmethod
|
||||
def for_module(cls, modname):
|
||||
if modname not in sys.modules:
|
||||
# XXX
|
||||
try:
|
||||
__import__(modname)
|
||||
except ImportError, err:
|
||||
raise PycodeError('error importing %r' % modname, err)
|
||||
mod = sys.modules[modname]
|
||||
if hasattr(mod, '__loader__'):
|
||||
# XXX raises
|
||||
try:
|
||||
source = mod.__loader__.get_source(modname)
|
||||
except Exception, err:
|
||||
raise PycodeError('error getting source for %r' % modname, err)
|
||||
return cls.for_string(source, modname)
|
||||
filename = getattr(mod, '__file__', None)
|
||||
if filename is None:
|
||||
# XXX
|
||||
raise RuntimeError('no source found')
|
||||
raise PycodeError('no source found for module %r' % modname)
|
||||
if filename.lower().endswith('.pyo') or \
|
||||
filename.lower().endswith('.pyc'):
|
||||
filename = filename[:-1]
|
||||
elif not filename.lower().endswith('.py'):
|
||||
raise RuntimeError('not a .py file')
|
||||
raise PycodeError('source is not a .py file: %r' % filename)
|
||||
if not path.isfile(filename):
|
||||
# XXX
|
||||
raise RuntimeError('source not present')
|
||||
raise PycodeError('source file is not present: %r' % filename)
|
||||
return cls.for_file(filename, modname)
|
||||
|
||||
def find_defs(self):
|
||||
def find_attrs(self):
|
||||
attr_visitor = ClassAttrVisitor(number2name, '')
|
||||
attr_visitor.visit(self.tree)
|
||||
for name, doc in attr_visitor.collected:
|
||||
print '>>', name
|
||||
print doc
|
||||
return attr_visitor.collected
|
||||
|
||||
|
||||
x0 = time.time()
|
||||
ma = ModuleAnalyzer.for_module('sphinx.builders.html')
|
||||
x1 = time.time()
|
||||
ma.find_defs()
|
||||
for name, doc in ma.find_attrs():
|
||||
print '>>', name
|
||||
print doc
|
||||
x2 = time.time()
|
||||
print "parsing %.4f, finding %.4f" % (x1-x0, x2-x1)
|
||||
|
Loading…
Reference in New Issue
Block a user