Opened 7 years ago

Last modified 5 years ago

#14743 needs_work defect

SymbolicFunction gives errors when using unbounded methods

Reported by: nvcleemp Owned by: burcin
Priority: major Milestone: sage-6.4
Component: symbolics Keywords:
Cc: Merged in:
Authors: Nico Van Cleemput Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description

before this patch:

sage: function('radius', var('G'), evalf_func=Graph.radius)                             
radius(G)
sage: function('wiener_index', var('G'), evalf_func=Graph.wiener_index)
Exception AttributeError: "'builtin_function_or_method' object has no attribute 'func_code'" in 'sage.symbolic.function.SymbolicFunction._hash_' ignored
Exception AttributeError: "'builtin_function_or_method' object has no attribute 'func_code'" in 'sage.symbolic.function.SymbolicFunction._hash_' ignored
wiener_index(G)

After this patch:

sage: function('radius', var('G'), evalf_func=Graph.radius)
radius(G)
sage: function('wiener_index', var('G'), evalf_func=Graph.wiener_index)
wiener_index(G)

Attachments (1)

trac_14743_symbolic_function.patch (852 bytes) - added by nvcleemp 7 years ago.

Download all attachments as: .zip

Change History (11)

Changed 7 years ago by nvcleemp

comment:1 Changed 7 years ago by nvcleemp

  • Status changed from new to needs_review

The test from the description should probably also be added to this patch, but I didn't know where to add it. Any suggestions?

comment:2 Changed 7 years ago by burcin

  • Status changed from needs_review to needs_work

Can you give an example of where this would be useful? Are you trying to construct symbolic functions where the custom methods are compiled (hence have no func_code attribute)?

This patch causes problems in the way we detect if a new symbolic function is being created:

sage: f = function('f', evalf_func=Graph.wiener_index)
sage: f(5)
f(5)
sage: f(5).n()
TypeError: unbound method wiener_index() must be called with Graph instance as first argument (got ComplexNumber instance instead)
sage: f = function('f', evalf_func=Expression.is_one) 
sage: f(5).n()                                       
TypeError: unbound method wiener_index() must be called with Graph instance as first argument (got ComplexNumber instance instead)

Note that the second error message still refers to wiener_index().

The documentation for SymbolicFunction states:

    This is the basis for user defined symbolic functions. We try to pickle or
    hash the custom methods, so subclasses must be defined in Python not Cython.

So using compiled (Cython) methods for the custom evaluation methods is not supported. If you describe your application we can think about a different solution.

comment:3 Changed 7 years ago by nvcleemp

Well, it's not really my application. :-) I was trying to find a fix for this issue: https://github.com/IndependenceNumberProject/inp/issues/10

This issue is about this file: https://github.com/IndependenceNumberProject/inp/blob/master/conjecture.py

Last edited 7 years ago by nvcleemp (previous) (diff)

comment:4 Changed 7 years ago by nbruin

I suspect that if people try to define a symbolic function that gets evaluated via an unbound method, they are doing the wrong thing: An unbound method expects a "self" argument and expects that to be of a very particular type (and usually not a "symbolic expression"). Symbolic functions, on the other hand only get symbolic expressions as arguments, and need to be extremely tolerant (or at least careful) in handling the different types of objects that might come wrapped in such a package. Symbolic functions are only for calculus-type applications. For most other situations one should use python functions/methods straight away.

I would say that the proper fix is to check that the documentation contains information along these lines, not to make it easier to use the wrong tool for the job.

comment:5 Changed 7 years ago by nvcleemp

Hmm, OK, then there should indeed be some more documentation documenting this. The author of inp and I discussed this a bit and we both agreed that the symbolics stuff was rather obscure, but it never occurred to us, that we might be doing something that is not meant to work.

comment:6 Changed 6 years ago by jdemeyer

  • Milestone changed from sage-5.11 to sage-5.12

comment:7 Changed 6 years ago by vbraun_spam

  • Milestone changed from sage-6.1 to sage-6.2

comment:8 Changed 6 years ago by vbraun_spam

  • Milestone changed from sage-6.2 to sage-6.3

comment:9 Changed 5 years ago by vbraun_spam

  • Milestone changed from sage-6.3 to sage-6.4

comment:10 Changed 5 years ago by rws

There could be done more than docs improvement to prevent this. It should be possible to list the superclasses of the evalf_f method's class using inspect.getmro, and then through inspect.getfile their source files, where the ".so" ending points to non-Python code. See also the code for sage_getfile. Maybe there is even a direct method recognizing subclasses of Cython extensions.

Note: See TracTickets for help on using tickets.