Skip to content

Commit

Permalink
sagemathgh-39499: Improve sage_getfile by looking at __init__
Browse files Browse the repository at this point in the history
    
Otherwise it will fail with meson editable install on objects like `x`
of type `Expression`, where the class does not have a docstring but
`__init__` method have.

The strategy is similar to `sage_getsourcelines` where `__init__` method
is looked in.

I choose to implement this instead of the more complex workaround (see
the comment below).

This fixes the test that fails in meson editable mode:

```
2025-02-11T20:13:36.4801998Z
**********************************************************************
2025-02-11T20:13:36.4803076Z File "src/sage/misc/sageinspect.py", line
1363, in sage.misc.sageinspect.sage_getfile_relative
2025-02-11T20:13:36.4804104Z Failed example:
2025-02-11T20:13:36.4804750Z     sage_getfile_relative(x)
# needs sage.symbolic
2025-02-11T20:13:36.4808395Z Expected:
2025-02-11T20:13:36.4813350Z     'sage/symbolic/expression.pyx'
2025-02-11T20:13:36.4814244Z Got:
2025-02-11T20:13:36.4815714Z
'/home/runner/work/sage/sage/builddir/src/sage/symbolic/expression.pyx'
2025-02-11T20:13:44.3128543Z
**********************************************************************
```

This may still fail in another case where neither class nor `__init__`
method has a docstring (in that case `?` will fail to get the file in
meson editable mode), but that's not in scope I guess. (I left a comment
there to explain)

See also sagemath#39369

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview. (change should be invisible to users not using meson editable
so…)

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#39499
Reported by: user202729
Reviewer(s):
  • Loading branch information
Release Manager committed Feb 17, 2025
2 parents 44df4ed + 6aee498 commit 721c44c
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/sage/misc/sageinspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,12 @@ def sage_getfile(obj):
if isinstance(obj, functools.partial):
return sage_getfile(obj.func)
return sage_getfile(obj.__class__) # inspect.getabsfile(obj.__class__)
else:
if hasattr(obj, '__init__'):
pos = _extract_embedded_position(_sage_getdoc_unformatted(obj.__init__))
if pos is not None:
(_, filename, _) = pos
return filename

# No go? fall back to inspect.
try:
Expand All @@ -1336,6 +1342,11 @@ def sage_getfile(obj):
return ''
for suffix in import_machinery.EXTENSION_SUFFIXES:
if sourcefile.endswith(suffix):
# TODO: the following is incorrect in meson editable install
# because the build is out-of-tree,
# but as long as either the class or its __init__ method has a
# docstring, _sage_getdoc_unformatted should return correct result
# see https://github.com/mesonbuild/meson-python/issues/723
return sourcefile.removesuffix(suffix)+os.path.extsep+'pyx'
return sourcefile

Expand Down Expand Up @@ -2356,12 +2367,8 @@ class Element:
try:
return inspect.getsourcelines(obj)
except (OSError, TypeError) as err:
try:
objinit = obj.__init__
except AttributeError:
pass
else:
d = _sage_getdoc_unformatted(objinit)
if hasattr(obj, '__init__'):
d = _sage_getdoc_unformatted(obj.__init__)
pos = _extract_embedded_position(d)
if pos is None:
if inspect.isclass(obj):
Expand Down

0 comments on commit 721c44c

Please sign in to comment.