This module extends parts of Python’s inspect module to Cython objects.
AUTHORS:
EXAMPLES:
sage: from sagenb.misc.sageinspect import *
Test introspection of modules defined in Python and Cython files:
Cython modules:
sage: sage_getfile(sage.rings.rational)
'.../rational.pyx'
sage: sage_getdoc(sage.rings.rational).lstrip()
'Rational Numbers...'
sage: sage_getsource(sage.rings.rational)[5:]
'Rational Numbers...'
Python modules:
sage: import sagenb.misc.sageinspect
sage: sage_getfile(sagenb.misc.sageinspect)
'.../sageinspect.py'
sage: print sage_getdoc(sagenb.misc.sageinspect).lstrip()[:40]
Inspect Python, Sage, and Cython objects
sage: sage_getsource(sagenb.misc.sageinspect).lstrip()[5:-1]
'...Inspect Python, Sage, and Cython objects...'
Test introspection of classes defined in Python and Cython files:
Cython classes:
sage: sage_getfile(sage.rings.rational.Rational)
'.../rational.pyx'
sage: sage_getdoc(sage.rings.rational.Rational).lstrip()
'A Rational number...'
sage: sage_getsource(sage.rings.rational.Rational)
'cdef class Rational...'
Python classes:
sage: import sage.misc.attach
sage: sage_getfile(sage.misc.attach.Attach)
'.../attach.py'
sage: sage_getdoc(sage.misc.attach.Attach).lstrip()
'Attach a file to a running instance of Sage...'
sage: sage_getsource(sage.misc.attach.Attach)
'class Attach:...'
Python classes with no docstring, but an __init__ docstring:
sage: class Foo:
... def __init__(self):
... 'docstring'
... pass
...
sage: sage_getdoc(Foo)
'docstring\n'
Test introspection of functions defined in Python and Cython files:
Cython functions:
sage: sage_getdef(sage.rings.rational.make_rational, obj_name='mr')
'mr(s)'
sage: sage_getfile(sage.rings.rational.make_rational)
'.../rational.pyx'
sage: sage_getdoc(sage.rings.rational.make_rational).lstrip()
"Make a rational number ..."
sage: sage_getsource(sage.rings.rational.make_rational, True)[4:]
'make_rational(s):...'
Python functions:
sage: sage_getdef(sagenb.misc.sageinspect.sage_getfile, obj_name='sage_getfile')
'sage_getfile(obj)'
sage: sage_getfile(sagenb.misc.sageinspect.sage_getfile)
'.../sageinspect.py'
sage: sage_getdoc(sagenb.misc.sageinspect.sage_getfile).lstrip()
"Get the full file name associated to ``obj`` as a string..."
sage: sage_getsource(sagenb.misc.sageinspect.sage_getfile)[4:]
'sage_getfile(obj):...'
Unfortunately, there is no argspec extractable from builtins:
sage: sage_getdef(''.find, 'find')
'find( [noargspec] )'
sage: sage_getdef(str.find, 'find')
'find( [noargspec] )'
Provide a tokeneater() method to detect the end of a code block.
This is the Python library’s inspect.BlockFinder modified to recognize Cython definitions.
Bases: ast.NodeVisitor
A simple visitor class that walks an abstract-syntax tree (AST) for a Python function’s argspec. It returns the contents of nodes representing the basic Python types: None, booleans, numbers, strings, lists, tuples, and dictionaries. We use this class in _sage_getargspec_from_ast() to extract an argspec from a function’s or method’s source code.
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: visitor.visit(ast.parse('[1,2,3]').body[0].value)
[1, 2, 3]
sage: visitor.visit(ast.parse("{'a':('e',2,[None,({False:True},'pi')]), 37.0:'temp'}").body[0].value)
{'a': ('e', 2, [None, ({False: True}, 'pi')]), 37.0: 'temp'}
sage: v = ast.parse("jc = ['veni', 'vidi', 'vici']").body[0]; v
<_ast.Assign object at ...>
sage: [x for x in dir(v) if not x.startswith('__')]
['_attributes', '_fields', 'col_offset', 'lineno', 'targets', 'value']
sage: visitor.visit(v.targets[0])
'jc'
sage: visitor.visit(v.value)
['veni', 'vidi', 'vici']
Visit a Python AST ast.Dict node.
INPUT:
OUTPUT:
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: vis = lambda x: visitor.visit_Dict(ast.parse(x).body[0].value)
sage: [vis(d) for d in ['{}', "{1:one, 'two':2, other:bother}"]]
[{}, {1: 'one', 'other': 'bother', 'two': 2}]
Visit a Python AST ast.List node.
INPUT:
OUTPUT:
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: vis = lambda x: visitor.visit_List(ast.parse(x).body[0].value)
sage: [vis(l) for l in ['[]', "['s', 't', 'u']", '[[e], [], [pi]]']]
[[], ['s', 't', 'u'], [['e'], [], ['pi']]]
Visit a Python AST ast.Name node.
INPUT:
OUTPUT:
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: vis = lambda x: visitor.visit_Name(ast.parse(x).body[0].value)
sage: [vis(n) for n in ['True', 'False', 'None', 'foo', 'bar']]
[True, False, None, 'foo', 'bar']
sage: [type(vis(n)) for n in ['True', 'False', 'None', 'foo', 'bar']]
[<type 'bool'>, <type 'bool'>, <type 'NoneType'>, <type 'str'>, <type 'str'>]
Visit a Python AST ast.Num node.
INPUT:
OUTPUT:
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: vis = lambda x: visitor.visit_Num(ast.parse(x).body[0].value)
sage: [vis(n) for n in ['123', '0.0', str(-pi.n())]]
[123, 0.0, -3.14159265358979]
Visit a Python AST ast.Str node.
INPUT:
OUTPUT:
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: vis = lambda x: visitor.visit_Str(ast.parse(x).body[0].value)
sage: [vis(s) for s in ['"abstract"', "u'syntax'", '''r"tr\ee"''']]
['abstract', u'syntax', 'tr\\ee']
Visit a Python AST ast.Tuple node.
INPUT:
OUTPUT:
EXAMPLES:
sage: import ast, sagenb.misc.sageinspect as sms
sage: visitor = sms.SageArgSpecVisitor()
sage: vis = lambda x: visitor.visit_Tuple(ast.parse(x).body[0].value)
sage: [vis(t) for t in ['()', '(x,y)', '("Au", "Al", "Cu")']]
[(), ('x', 'y'), ('Au', 'Al', 'Cu')]
Checks if argument is instance of non built-in class
INPUT: obj - object
EXAMPLES:
sage: from sagenb.misc.sageinspect import isclassinstance
sage: isclassinstance(int)
False
sage: isclassinstance(FreeModule)
True
sage: isclassinstance(SteenrodAlgebra)
True
sage: class myclass: pass
sage: isclassinstance(myclass)
False
sage: class mymetaclass(type): pass
sage: class myclass2:
... __metaclass__ = mymetaclass
sage: isclassinstance(myclass2)
False
Return the names and default values of a function’s arguments.
INPUT: obj, a function
OUTPUT: A tuple of four things is returned: (args, varargs, varkw, defaults). args is a list of the argument names (it may contain nested lists). varargs and varkw are the names of the * and ** arguments or None. defaults is an n-tuple of the default values of the last n arguments.
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getargspec
sage: sage_getargspec(identity_matrix)
(['ring', 'n', 'sparse'], None, None, (0, False))
sage: sage_getargspec(Poset)
(['data', 'element_labels', 'cover_relations'], None, None, (None, None, False))
sage: sage_getargspec(factor)
(['n', 'proof', 'int_', 'algorithm', 'verbose'],
None,
'kwds',
(None, False, 'pari', 0))
AUTHORS:
Return the definition header for any callable object.
INPUT:
obj_name is prepended to the output.
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getdef
sage: sage_getdef(identity_matrix)
'(ring, n=0, sparse=False)'
sage: sage_getdef(identity_matrix, 'identity_matrix')
'identity_matrix(ring, n=0, sparse=False)'
Check that trac ticket #6848 has been fixed:
sage: sage_getdef(RDF.random_element)
'(min=-1, max=1)'
If an exception is generated, None is returned instead and the exception is suppressed.
AUTHORS:
Return the docstring associated to obj as a string.
INPUT: obj, a function, module, etc.: something with a docstring.
If obj is a Cython object with an embedded position in its docstring, the embedded position is stripped.
If optional argument embedded_override is False (its default value), then the string is formatted according to the value of EMBEDDED_MODE. If this argument is True, then it is formatted as if EMBEDDED_MODE were True.
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getdoc
sage: sage_getdoc(identity_matrix)[3:39]
'Return the n x n identity matrix ove'
AUTHORS:
Get the full file name associated to obj as a string.
INPUT: obj, a Sage object, module, etc.
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getfile
sage: sage_getfile(sage.rings.rational)[-23:]
'sage/rings/rational.pyx'
sage: sage_getfile(Sq)[-41:]
'sage/algebras/steenrod_algebra_element.py'
AUTHOR: - Nick Alexander
Return the source code associated to obj as a string, or None.
INPUT:
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getsource
sage: sage_getsource(identity_matrix, True)[4:45]
'identity_matrix(ring, n=0, sparse=False):'
sage: sage_getsource(identity_matrix, False)[4:45]
'identity_matrix(ring, n=0, sparse=False):'
AUTHORS:
Return a pair ([source_lines], starting line number) of the source code associated to obj, or None.
INPUT:
OUTPUT: (source_lines, lineno) or None: source_lines is a list of strings, and lineno is an integer.
At this time we ignore is_binary in favour of a ‘do our best’ strategy.
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getsourcelines
sage: sage_getsourcelines(matrix, True)[1]
34
sage: sage_getsourcelines(matrix, False)[0][0][4:]
'matrix(*args, **kwds):\n'
AUTHORS:
Attempt to get the name of a Sage object.
INPUT:
If the user has assigned an object obj to a variable name, then return that variable name. If several variables point to obj, return a list of those names. If omit_underscore_names is True (the default) then omit names starting with an underscore “_”.
This is a modified version of code taken from http://pythonic.pocoo.org/2009/5/30/finding-objects-names, written by Georg Brandl.
EXAMPLES:
sage: from sagenb.misc.sageinspect import sage_getvariablename
sage: A = random_matrix(ZZ, 100)
sage: sage_getvariablename(A)
'A'
sage: B = A
sage: sage_getvariablename(A)
['A', 'B']
If an object is not assigned to a variable, an empty list is returned:
sage: sage_getvariablename(random_matrix(ZZ, 60))
[]