Skip to content

Commit

Permalink
Trac #16309: Determine argspec of static methods with defaults in Cyt…
Browse files Browse the repository at this point in the history
…hon files

Fix this:
{{{
sage: cython("""
....: class Bla:
....:     @staticmethod
....:     def join(categories, bint as_list = False, tuple
ignore_axioms=(), tuple axioms=()):
....:         pass
....: """)
sage: from sage.misc.sageinspect import sage_getargspec
sage: sage_getargspec(Bla.join)
  File "<string>", line unknown
SyntaxError: Unexpected EOF while parsing argument list

}}}
This does not happen if `join` is a bound or unbound (not static)
method.

Since this will affect building the docs (see #16296), I'd say the
component is "documentation".

URL: http://trac.sagemath.org/16309
Reported by: SimonKing
Ticket author(s): Simon King
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager authored and vbraun committed Jul 24, 2014
2 parents 6937389 + 143b567 commit 1d01b1d
Showing 1 changed file with 87 additions and 15 deletions.
102 changes: 87 additions & 15 deletions src/sage/misc/sageinspect.py
Expand Up @@ -787,6 +787,13 @@ def _split_syntactical_unit(s):
sage: _split_syntactical_unit('123')
('1', '23')
TEST:
The following was fixed in :trac:`16309`::
sage: _split_syntactical_unit('()): pass')
('()', '): pass')
"""
s = s.strip()
if not s:
Expand Down Expand Up @@ -862,11 +869,11 @@ def split_string(s, quot):
tmp_group, s = _split_syntactical_unit(s)
out.append(tmp_group)
s = s.strip()
if s.startswith(stop):
if tmp_group==stop:
return ''.join(out), s
elif s.startswith(stop):
out.append(stop)
return ''.join(out), s[1:].strip()
elif tmp_group==stop:
return ''.join(out), s
raise SyntaxError("Syntactical group starting with %s did not end with %s"%(repr(start),repr(stop)))

def _sage_getargspec_from_ast(source):
Expand Down Expand Up @@ -1142,6 +1149,17 @@ def sage_getfile(obj):
sage: sage_getfile(P)
'...sage/rings/polynomial/multi_polynomial_libsingular.pyx'
A problem fixed in :trac:`16309`::
sage: cython('''
....: class Bar: pass
....: cdef class Foo: pass
....: ''')
sage: sage_getfile(Bar)
'...pyx'
sage: sage_getfile(Foo)
'...pyx'
AUTHORS:
- Nick Alexander
Expand All @@ -1162,7 +1180,10 @@ def sage_getfile(obj):
return sage_getfile(obj.__class__) #inspect.getabsfile(obj.__class__)

# No go? fall back to inspect.
return inspect.getabsfile(obj)
sourcefile = inspect.getabsfile(obj)
if sourcefile.endswith(os.path.extsep+'so'):
return sourcefile[:-3]+os.path.extsep+'pyx'
return sourcefile

def sage_getargspec(obj):
r"""
Expand Down Expand Up @@ -1287,6 +1308,24 @@ def foo(x, a='\')"', b={not (2+1==3):'bar'}): return
sage: sage.misc.sageinspect.sage_getargspec(r.lm)
The following was fixed in :trac:`16309`::
sage: cython('''
....: class Foo:
....: @staticmethod
....: def join(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass
....: cdef class Bar:
....: @staticmethod
....: def join(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass
....: cpdef meet(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass
....: ''')
sage: sage_getargspec(Foo.join)
ArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, keywords=None, defaults=(False, (), ()))
sage: sage_getargspec(Bar.join)
ArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, keywords=None, defaults=(False, (), ()))
sage: sage_getargspec(Bar.meet)
ArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, keywords=None, defaults=(False, (), ()))
AUTHORS:
- William Stein: a modified version of inspect.getargspec from the
Expand All @@ -1305,10 +1344,12 @@ def foo(x, a='\')"', b={not (2+1==3):'bar'}): return
return inspect.ArgSpec(*obj._sage_argspec_())
except (AttributeError, TypeError):
pass
if inspect.isfunction(obj):
func_obj = obj
elif inspect.ismethod(obj):
func_obj = obj.__func__
if hasattr(obj, 'func_code'):
try:
args, varargs, varkw = inspect.getargs(obj.func_code)
return inspect.ArgSpec(args, varargs, varkw, obj.func_defaults)
except (TypeError, AttributeError):
pass
elif isclassinstance(obj):
if hasattr(obj,'_sage_src_'): #it may be a decorator!
source = sage_getsource(obj)
Expand Down Expand Up @@ -1590,12 +1631,43 @@ class ParentMethods:
Returns the Lie bracket `[x, y] = x y - y x` of `x` and `y`.
...
TESTS:
The following was fixed in :trac:`16309`::
sage: cython('''
....: class A:
....: def __init__(self):
....: "some init doc"
....: pass
....: class B:
....: "some class doc"
....: class A(A):
....: pass
....: ''')
sage: B.A.__name__
'A'
sage: B.A.__qualname__
'B.A'
sage: sage_getsource(B.A)
' class A(A):\n pass\n\n'
Note that for this example to work, it is essential that the class ``B``
has a docstring. Otherwise, the code of ``B`` could not be found (Cython
inserts embedding information into the docstring) and thus the code of
``B.A`` couldn't be found either.
AUTHOR:
- Simon King (2011-09)
"""
# First, split the name:
splitted_name = object.__name__.split('.')
if '.' in object.__name__:
splitted_name = object.__name__.split('.')
elif hasattr(object,'__qualname__'):
splitted_name = object.__qualname__.split('.')
else:
splitted_name = object.__name__
path = object.__module__.split('.')+splitted_name[:-1]
name = splitted_name[-1]
try:
Expand Down Expand Up @@ -1817,17 +1889,17 @@ class Element:
d = inspect.getdoc(obj)
pos = _extract_embedded_position(d)
if pos is None:
if (not hasattr(obj, '__class__')) or hasattr(obj,'__metaclass__'):
# That hapens for ParentMethods
# of categories
if '.' in obj.__name__ or '.' in getattr(obj,'__qualname__',''):
return _sage_getsourcelines_name_with_dot(obj)
d = _sage_getdoc_unformatted(obj)
pos = _extract_embedded_position(d)
if pos is None:
try:
return inspect.getsourcelines(obj)
except IOError:
if (not hasattr(obj, '__class__')) or hasattr(obj,'__metaclass__'):
# That hapens for ParentMethods
# of categories
if '.' in obj.__name__:
return _sage_getsourcelines_name_with_dot(obj)
except (IOError, TypeError):
if inspect.isclass(obj):
try:
B = obj.__base__
Expand Down

0 comments on commit 1d01b1d

Please sign in to comment.