Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove monkey patching of inspect.isfunction in sage.__init__ #32479

Closed
mkoeppe opened this issue Sep 5, 2021 · 43 comments
Closed

Remove monkey patching of inspect.isfunction in sage.__init__ #32479

mkoeppe opened this issue Sep 5, 2021 · 43 comments

Comments

@mkoeppe
Copy link
Member

mkoeppe commented Sep 5, 2021

"Monkey-patch inspect.isfunction() to support Cython functions."

Introduced in 2018 (8.3.beta2) in #25373 (for #24994).

However, this change has been rejected by upstream (https://bugs.python.org/issue30071, https://www.python.org/dev/peps/pep-0575/, https://www.python.org/dev/peps/pep-0580/).

In this ticket:

  • we remove the monkey-patching

  • replace unnecessary uses of inspect in ordinary Sage library code by other solutions

  • replace remaining uses of inspect.isfunction by the new name of our monkey-patched variant: sage.misc.sageinspect.is_function_or_cython_function

(To be checked whether https://www.python.org/dev/peps/pep-0590, superseding some of the above rejected PEPs, offers help; see also the informational PEP https://www.python.org/dev/peps/pep-0579/)

Related:

Depends on #31420

CC: @fchapoton @kwankyu @jhpalmieri @orlitzky

Component: refactoring

Author: Matthias Koeppe

Branch/Commit: 2ba4c43

Reviewer: Michael Orlitzky

Issue created by migration from https://trac.sagemath.org/ticket/32479

@mkoeppe mkoeppe added this to the sage-9.5 milestone Sep 5, 2021
@mkoeppe

This comment has been minimized.

@mkoeppe

This comment has been minimized.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 6, 2021

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 6, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

903c6d4src/sage/algebras/steenrod/steenrod_algebra_misc.py: Use callable(...) instead of inspect.isfunction(...)

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 6, 2021

Commit: 903c6d4

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 6, 2021

Changed commit from 903c6d4 to 1ac057d

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 6, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

1ac057dsage.modules.{free_module_homspace,vector_space_homspace,vector_space_morphism}: Use callable(...) instead of inspect.isfunction(...)

@mkoeppe

This comment has been minimized.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 6, 2021

Changed commit from 1ac057d to dcce32d

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 6, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

e123a92sage.calculus.integration.monte_carlo_integral: Remove use of inspect.isfunction
dcce32dsage.symbolic.expression.get_dynamic_class_for_function: Use callable(...) instead of inspect.isfunction(...)

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 6, 2021

comment:8

Setting to "needs review" so that the patchbot runs

@mkoeppe

This comment has been minimized.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 6, 2021

Author: Matthias Koeppe, ...

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 7, 2021

comment:9
sage -t --long --random-seed=0 src/sage/misc/sagedoc.py  # 8 doctests failed
sage -t --long --random-seed=0 src/sage/misc/rest_index_of_methods.py  # 1 doctest failed
sage -t --long --random-seed=0 src/sage/docs/conf.py  # 1 doctest failed

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 7, 2021

Changed commit from dcce32d to 3bc20b8

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 7, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

3bc20b8sage.misc.sageinspect.is_function_or_cython_function: New, use it instead of relying on monkey patching of inspect.isfunction

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 7, 2021

Changed commit from 3bc20b8 to b5dd567

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 7, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

b5dd567src/sage/misc/sageinspect.py: Fixup doctest

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 7, 2021

comment:14

There are a few uses of inspect.isfunction in sage_docbuild. I don't know if these should be replaced by sage.misc.sageinspect.is_function_or_cython_function

src/sage_docbuild/ext/sage_autodoc.py:        return (inspect.isfunction(member) or inspect.isbuiltin(member)
src/sage_docbuild/ext/sage_autodoc.py:                not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)):
src/sage_docbuild/ext/sage_autodoc.py:        return inspect.isfunction(obj) or inspect.isbuiltin(obj) or inspect.ismethod(obj)

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 7, 2021

comment:15

I would also like to get rid of these uses of inspect.isfunction in plotting code.

src/sage/plot/plot3d/plot3d.py:    if inspect.isfunction(func):
src/sage/plot/plot_field.py:    if isfunction(f):
src/sage/plot/streamline_plot.py:        if isfunction(f_g):

Help on this would be welcome

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 9, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

9675b69src/sage_docbuild/ext/sage_autodoc.py: Use sage.misc.sageinspect.is_function_or_cython_function instead of inspect.isfunction

@mkoeppe

This comment has been minimized.

@orlitzky
Copy link
Contributor

orlitzky commented Sep 9, 2021

comment:20

What's an example of a cython function that isn't callable()?

@orlitzky
Copy link
Contributor

orlitzky commented Sep 9, 2021

comment:21

Replying to @orlitzky:

What's an example of a cython function that isn't callable()?

In other words, what goes wrong if you change the plot/sagedoc code to use callable() too? The only difference I see is that methods are callable() but the new is_function_or_cython_function() will return False on them. I don't see a moral problem with plotting a class method, though. And the sagedoc code is also checking for methods.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 9, 2021

comment:22

Note that

sage: type(x)                                                                                                                                                 
<class 'sage.symbolic.expression.Expression'>
sage: callable(x)                                                                                                                                             
True
sage: import inspect                                                                                                                                          
sage: inspect.isfunction(x)                                                                                                                                   
False
sage: from sage.misc.sageinspect import is_function_or_cython_function                                                                                        
sage: is_function_or_cython_function(x)                                                                                                                       
False

... so callable would not be the right replacement for the uses in sage.plot.

Regarding sagedoc I really don't have an idea about the code (in particular I look at the formatted documentation too rarely to be sure that changes don't break anything). Hence this safe replacement.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 9, 2021

comment:23

(All Cython functions are callable but not all objects that are callable satisfy is_function_or_cython_function.)

@orlitzky
Copy link
Contributor

orlitzky commented Sep 9, 2021

comment:24

Ok, let's just merge the easy part then (I don't really want to look at plots either).

This bit in integration.pyx would be cleaner/faster with hasattr() I think:

try:
    vars = func.arguments()
except AttributeError:
    try:
        vars = func.variables()
    except AttributeError:
        vars = sage_getargspec(func)[0]

Mismatched parentheses in docstring:

"""
Think twice before using this function (or any function from the
``inspect`` or ``sage.misc.sageinspect`` modules.  Most uses of
``isfunction`` in ordinary library code can be replaced by ``callable``.
"""

You could also use Sphinx cross-module references there. Finally,

"""
Verify that ipywidgets can correctly determine signatures of Cython
functions::

    sage: from ipywidgets.widgets.interaction import signature
    sage: from sage.dynamics.complex_dynamics.mandel_julia_helper import fast_mandelbrot_plot
    sage: signature(fast_mandelbrot_plot)  # random
    <IPython.utils._signatures.Signature object at 0x7f3ec8274e10>
"""

I think that should go under a new TESTS:: block, since it's verifying some internal detail that a user reading the reference manual won't care about.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 9, 2021

comment:25

Replying to @orlitzky:

Ok, let's just merge the easy part then (I don't really want to look at plots either).

This bit in integration.pyx would be cleaner/faster with hasattr()

I haven't timed this particular one in Cython but at least in plain Python try: except: is faster than doing the attribute access a second time.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 9, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

f9154a9sage.misc.sageinspect.is_function_or_cython_function: Improve docstring markup

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 9, 2021

Changed commit from a03c459 to f9154a9

@orlitzky
Copy link
Contributor

orlitzky commented Sep 9, 2021

Reviewer: Michael Orlitzky

@orlitzky
Copy link
Contributor

orlitzky commented Sep 9, 2021

comment:27

Ok then.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 9, 2021

comment:28

Thanks for reviewing!

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 9, 2021

Branch pushed to git repo; I updated commit sha1 and set ticket back to needs_review. New commits:

91ec0f2src/sage/__init__.py: Remove __all__
949d787src/sage/__init__.py: Remove __version__
f77a98esrc/sage/__init__.py: Move 'import zlib' to src/sage/cpython/__init__.py
2e9ea56src/sage/__init__.py: Move monkey-patch of ExtensionFileLoader to src/sage/cpython/__init__.py
ad587cfsrc/sage/__init__.py [Cygwin]: Move monkey-patch of sqlite to src/sage/cpython/__init__.py
af6642fsrc/sage/cpython/__init__.py: Clean up sage.cpython module
2ba4c43Merge #31420

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 9, 2021

Changed commit from f9154a9 to 2ba4c43

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 9, 2021

comment:30

Merged #31420 to remove the trivial merge conflict in src/sage/__init__.py.

@mkoeppe
Copy link
Member Author

mkoeppe commented Sep 9, 2021

Dependencies: #31420

@vbraun
Copy link
Member

vbraun commented Sep 19, 2021

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants