Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
sage.misc.sageinspect.sage_getfile_relative: New, use it in sage.misc…
Browse files Browse the repository at this point in the history
….cachefunc, sage.sets.set_from_iterator.Decorator
  • Loading branch information
Matthias Koeppe committed Jun 25, 2022
1 parent 53154b3 commit 748d9fb
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 46 deletions.
22 changes: 2 additions & 20 deletions src/sage/misc/cachefunc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
46 changes: 46 additions & 0 deletions src/sage/misc/sageinspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
30 changes: 4 additions & 26 deletions src/sage/sets/set_from_iterator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 748d9fb

Please sign in to comment.