提交 6c10d75d authored 作者: James Bergstra's avatar James Bergstra

added RoutineDoc thing to ./epydoc

上级 4f4bcdb2
...@@ -5,19 +5,58 @@ ...@@ -5,19 +5,58 @@
# Make sure that we don't get confused between an epydoc.py script and # Make sure that we don't get confused between an epydoc.py script and
# the real epydoc package. # the real epydoc package.
import sys, os.path import sys, os.path, inspect
if os.path.exists(os.path.join(sys.path[0], 'epydoc.py')): if os.path.exists(os.path.join(sys.path[0], 'epydoc.py')):
del sys.path[0] del sys.path[0]
from epydoc import docintrospecter from epydoc import docintrospecter
from epydoc.apidoc import RoutineDoc from epydoc.apidoc import RoutineDoc
def specialize_to_RoutineDoc(value, value_doc, module_name): def Op_to_RoutineDoc(op, routine_doc, module_name=None):
value_doc.specialize_to(RoutineDoc) routine_doc.specialize_to(RoutineDoc)
#NB: this code is lifted from
# /u/bergstrj/pub/prefix/x86_64-unknown-linux-gnu-Fedora_release_7__Moonshine_/lib/python2.5/site-packages/epydoc
# /u/bergstrj/pub/prefix/x86_64-unknown-linux-gnu-Fedora_release_7__Moonshine_/lib/python2.5/site-packages/epydoc/docintrospecter.py
# op should be an op instance
assert hasattr(op, 'perform')
# Record the function's docstring.
routine_doc.docstring = getattr(op, '__doc__', '')
# Record the function's signature.
func = op.__epydoc_asRoutine
if isinstance(func, type(Op_to_RoutineDoc)):
(args, vararg, kwarg, defaults) = inspect.getargspec(func)
# Add the arguments.
routine_doc.posargs = args
routine_doc.vararg = vararg
routine_doc.kwarg = kwarg
# Set default values for positional arguments.
routine_doc.posarg_defaults = [None]*len(args)
# Set the routine's line number.
if hasattr(func, 'func_code'):
routine_doc.lineno = func.func_code.co_firstlineno
else:
# [XX] I should probably use UNKNOWN here??
# dvarrazzo: if '...' is to be changed, also check that
# `docstringparser.process_arg_field()` works correctly.
# See SF bug #1556024.
routine_doc.posargs = ['...']
routine_doc.posarg_defaults = [None]
routine_doc.kwarg = None
routine_doc.vararg = None
return routine_doc
docintrospecter.register_introspecter( docintrospecter.register_introspecter(
lambda value: getattr(value, '__epydoc_asRoutine', False), lambda value: getattr(value, '__epydoc_asRoutine', False),
specialize_to_RoutineDoc, Op_to_RoutineDoc,
priority=-1) priority=-1)
from epydoc.cli import cli from epydoc.cli import cli
......
...@@ -508,8 +508,17 @@ def _elemwise(scalar_op, name, doc_prefix=''): ...@@ -508,8 +508,17 @@ def _elemwise(scalar_op, name, doc_prefix=''):
return straight, inplace return straight, inplace
def _epydoc_cheat(real_symbol_value): def _redefine(real_symbol_value):
"""Replace the value associated with a function symbol""" """Replace the value associated with a function symbol.
This is useful to trick epydoc into doing what we want. It's a hack.
"""
def decorator(f):
return real_symbol_value
return decorator
def _redefine_asRoutine(real_symbol_value):
real_symbol_value.__epydoc_asRoutine = True
def decorator(f): def decorator(f):
return real_symbol_value return real_symbol_value
return decorator return decorator
...@@ -532,7 +541,7 @@ def _scal_elemwise(symbol): ...@@ -532,7 +541,7 @@ def _scal_elemwise(symbol):
#for the meaning of this see the ./epydoc script #for the meaning of this see the ./epydoc script
# it makes epydoc display rval as if it were a function, not an object # it makes epydoc display rval as if it were a function, not an object
rval.__epydoc_asRoutine = True rval.__epydoc_asRoutine = symbol
return rval return rval
...@@ -580,13 +589,14 @@ def cast(t, dtype): ...@@ -580,13 +589,14 @@ def cast(t, dtype):
'complex128': convert_to_complex128} 'complex128': convert_to_complex128}
return mapping[dtype](t) return mapping[dtype](t)
def _conversion(f): def _conversion(real_value):
f.__module__ = 'tensor' def decorator(f):
return f return real_value
return decorator
convert_to_int8 = _conversion(elemwise.Elemwise(scal.Identity(scal.specific_out(scal.int8)))) convert_to_int8 = _conversion(elemwise.Elemwise(scal.Identity(scal.specific_out(scal.int8))))
"""Cast to 8-bit integer""" """Cast to 8-bit integer"""
convert_to_int16 = _conversion(elemwise.Elemwise(scal.Identity(scal.specific_out(scal.int16)))) convert_to_int16 = _conversion(elemwise.Elemwise(scal.Identity(scal.specific_out(scal.int16))))
"""Cast to 16-bit integer""" """Cast to 16-bit integer"""
...@@ -627,7 +637,9 @@ class Shape(Op): ...@@ -627,7 +637,9 @@ class Shape(Op):
out[0] = numpy.asarray(x.shape) out[0] = numpy.asarray(x.shape)
def grad(self, (x,), (gz,)): def grad(self, (x,), (gz,)):
return [None] return [None]
shape = Shape() @_redefine_asRoutine(Shape())
def shape(a):
pass
class MaxAndArgmax(Op): class MaxAndArgmax(Op):
"""Calculate the max and argmax over a given axis""" """Calculate the max and argmax over a given axis"""
...@@ -660,8 +672,9 @@ class MaxAndArgmax(Op): ...@@ -660,8 +672,9 @@ class MaxAndArgmax(Op):
assert axis.data == 0 assert axis.data == 0
g_x = eq(max(x, axis), x) * g_max g_x = eq(max(x, axis), x) * g_max
return g_x, None return g_x, None
max_and_argmax = MaxAndArgmax() @_redefine_asRoutine(MaxAndArgmax())
def max_and_argmax(a):
pass
@constructor @constructor
...@@ -781,24 +794,24 @@ def _invert_inplace(a): ...@@ -781,24 +794,24 @@ def _invert_inplace(a):
########################## ##########################
@_scal_elemwise @_scal_elemwise
def _abs(*a): def _abs(a):
"""|a| """|`a`|
_abs has a leading underscore because abs() is a builtin. TensorResult overloads the _abs has a leading underscore because abs() is a builtin. TensorResult overloads the
__abs__ operator so that this function is called when you type abs(a). `TensorResult.__abs__` operator so that this function is called when you type abs(a).
""" """
@_scal_elemwise @_scal_elemwise
def __abs_inplace(a): def __abs_inplace(a):
"""|a| (inplace on a)""" """|`a`| (inplace on `a`)"""
@_scal_elemwise @_scal_elemwise
def exp(a): def exp(a):
"""e^a""" """e^`a`"""
@_scal_elemwise @_scal_elemwise
def _exp_inplace(a): def _exp_inplace(a):
"""e^a (inplace on a)""" """e^`a` (inplace on `a`)"""
@_scal_elemwise @_scal_elemwise
def neg(a): def neg(a):
...@@ -973,11 +986,11 @@ def one(): ...@@ -973,11 +986,11 @@ def one():
return Ones(0)([]) return Ones(0)([])
@_epydoc_cheat(elemwise.Elemwise(scal.identity)) @_redefine(elemwise.Elemwise(scal.identity))
def tensor_copy(a): def tensor_copy(a):
"""Create a duplicate of `a` (with duplicated storage)""" """Create a duplicate of `a` (with duplicated storage)"""
@_epydoc_cheat(elemwise.Elemwise(scal.identity, inplace_pattern = {0: [0]})) @_redefine(elemwise.Elemwise(scal.identity, inplace_pattern = {0: [0]}))
def view(a): def view(a):
"""Create a duplicate of `a` (with shared storage)""" """Create a duplicate of `a` (with shared storage)"""
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论