diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index af341a2c849..a5ad98e0364 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -420,8 +420,7 @@ cdef extern from "methodobject.h": cdef int PyCFunction_GetFlags(object op) except -1 import os -from os.path import relpath, normpath, commonprefix -from sage.misc.sageinspect import sage_getfile, sage_getsourcelines, sage_getargspec +from sage.misc.sageinspect import sage_getfile_relative, sage_getsourcelines, sage_getargspec from inspect import isfunction from sage.misc.weak_dict cimport CachedWeakValueDictionary @@ -875,24 +874,7 @@ cdef class CachedFunction(): if not doc or _extract_embedded_position(doc) is None: try: sourcelines = sage_getsourcelines(f) - filename = sage_getfile(f) - - def directories(): - try: - from sage.env import SAGE_SRC - except ImportError: - pass - else: - if SAGE_SRC: - yield normpath(os.path.join(SAGE_SRC, 'sage')) - import sage - yield from sage.__path__ - - for directory in directories(): - if commonprefix([filename, directory]) == directory: - filename = os.path.join('sage', relpath(filename, directory)) - break - + filename = sage_getfile_relative(f) #this is a rather expensive way of getting the line number, because #retrieving the source requires reading the source file and in many #cases this is not required (in cython it's embedded in the docstring, diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 4930601efad..f09a3a225ae 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -1413,6 +1413,52 @@ def sage_getfile(obj): return sourcefile +def sage_getfile_relative(obj): + r""" + Get the file name associated to ``obj`` as a string. + + This is the same as :func:`sage_getfile`, but + if the source file is part of the ``sage.*`` namespace, it + makes the file name relative so that it starts with ``sage/``. + + INPUT: ``obj``, a Sage object, module, etc. + + EXAMPLES:: + + sage: from sage.misc.sageinspect import sage_getfile_relative + sage: sage_getfile_relative(sage.rings.rational) + 'sage/rings/rational.pyx' + sage: sage_getfile_relative(Sq) + 'sage/algebras/steenrod/steenrod_algebra.py' + sage: sage_getfile_relative(x) + 'sage/symbolic/expression.pyx' + sage: sage_getfile_relative(range) + '' + """ + filename = sage_getfile(obj) + if not filename: + return filename + + from os.path import relpath, normpath, commonprefix + + def directories(): + try: + from sage.env import SAGE_SRC + except ImportError: + pass + else: + if SAGE_SRC: + yield normpath(os.path.join(SAGE_SRC, 'sage')) + import sage + yield from sage.__path__ + + for directory in directories(): + if commonprefix([filename, directory]) == directory: + return os.path.join('sage', relpath(filename, directory)) + + return filename + + def sage_getargspec(obj): r""" Return the names and default values of a function's arguments. diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index af32a3be56a..735ec7d3448 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -464,37 +464,15 @@ def _instancedoc_(self): Calls the PARI "isprime" function. """ # Duplicates sage.misc.cachefunc.CachedFunction._instancedoc_ - from sage.misc.sageinspect import sage_getsourcelines, sage_getfile, _extract_embedded_position + from sage.misc.sageinspect import sage_getsourcelines, sage_getfile_relative, _extract_embedded_position f = self.f doc = f.__doc__ or '' if _extract_embedded_position(doc) is None: try: - from os.path import normpath, commonprefix sourcelines = sage_getsourcelines(f) - filename = sage_getfile(f) - - # The following is a heuristics to get - # the file name of the cached function - # or method - - def directories(): - try: - from sage.env import SAGE_SRC - except ImportError: - pass - else: - if SAGE_SRC: - yield normpath(os.path.join(SAGE_SRC, 'sage')) - import sage - yield from sage.__path__ - - for directory in directories(): - if commonprefix([filename, directory]) == directory: - filename = os.path.join('sage', relpath(filename, directory)) - break - - file_info = "File: %s (starting at line %d)\n"%(filename,sourcelines[1]) - doc = file_info+doc + filename = sage_getfile_relative(f) + file_info = "File: %s (starting at line %d)\n" % (filename, sourcelines[1]) + doc = file_info + doc except IOError: pass return doc