summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2008-12-29 20:47:32 +0100
committerGeorg Brandl <georg@python.org>2008-12-29 20:47:32 +0100
commitfb41d84eca01e3a622780dbd15b6c7606b0bbc4f (patch)
tree4d2d7a6adc0fab855768d43a6a8dcd9f5fc3767c
parentd59cb5c2dfeae2282b804459b76a4ef5f9243ccf (diff)
downloadsphinx-fb41d84eca01e3a622780dbd15b6c7606b0bbc4f.tar.gz
Improve error handling.
-rw-r--r--sphinx/pycode/__init__.py51
1 files changed, 33 insertions, 18 deletions
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index 26d3579d..0ebf683c 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -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
- fileobj = open(filename, 'r')
try:
- return cls(pydriver.parse_stream(fileobj), modname, filename)
+ 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
- __import__(modname)
+ try:
+ __import__(modname)
+ except ImportError, err:
+ raise PycodeError('error importing %r' % modname, err)
mod = sys.modules[modname]
if hasattr(mod, '__loader__'):
- # XXX raises
- source = mod.__loader__.get_source(modname)
+ 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)