Opened 4 years ago

Last modified 4 years ago

## #23670 new defect

# rest_index_of_methods does not work in pyx files

Reported by: | rws | Owned by: | |
---|---|---|---|

Priority: | major | Milestone: | sage-8.1 |

Component: | documentation | Keywords: | |

Cc: | Merged in: | ||

Authors: | Reviewers: | ||

Report Upstream: | N/A | Work issues: | |

Branch: | Commit: | ||

Dependencies: | Stopgaps: |

### Description

When adding the following to a source file:

`{INDEX_OF_METHODS}`

in the doc head`from sage.misc.rest_index_of_methods import doc_index, gen_thematic_rest_table_index`

to imports`from sage.misc.decorators import rename_keyword`

to imports`@doc_index("xyz")`

as decorator to a method of class X`__doc__ = __doc__.replace("{INDEX_OF_METHODS}",gen_thematic_rest_table_index(X))`

at the bottom of the file

it will pass `make`

if the file is a `.py`

file but give an error like the following if it's a `.pyx`

file:

(example complex_double.pyx with the decorator at line 2288) ... [dochtml] File "sage/rings/complex_double.pyx", line 2288, in init sage.rings.complex_double [dochtml] File "/home/ralf/sage/local/lib/python2.7/site-packages/sage/misc/rest_index_of_methods.py", line 318, in hey [dochtml] setattr(f,"doc_index",name) [dochtml] AttributeError: 'method_descriptor' object has no attribute 'doc_index' Makefile:985: recipe for target 'doc-html' failed

### Change History (13)

### comment:1 Changed 4 years ago by

### comment:2 in reply to: ↑ description Changed 4 years ago by

### comment:3 Changed 4 years ago by

From a simple stand-alone experiment I just did, this should work with `@cython.binding(True)`

### comment:4 follow-up: ↓ 7 Changed 4 years ago by

So what am I doing wrong here:

diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index be609678cf..e4b08d0e05 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -12,6 +12,9 @@ following the expression with a period ``.`` followed by the member function call, as it is usual in Python. The member functions can be grouped in the following categories: + +{INDEX_OF_METHODS} + - algebraic operations: :func:`~Expression.coefficient`, :func:`~Expression.coefficients`, :func:`~Expression.content`, :func:`~Expression.default_variable`, :func:`~Expression.degree`, @@ -202,6 +205,7 @@ from sage.misc.derivative import multi_derivative from sage.misc.superseded import deprecated_function_alias, deprecation from sage.rings.infinity import AnInfinity, infinity, minus_infinity, unsigned_infinity from sage.misc.decorators import rename_keyword +from sage.misc.rest_index_of_methods import doc_index, gen_thematic_rest_table_index from sage.structure.dynamic_class import dynamic_class from sage.symbolic.operators import FDerivativeOperator, add_vararg, mul_vararg from sage.arith.numerical_approx cimport digits_to_bits @@ -2337,6 +2341,8 @@ cdef class Expression(CommutativeRingElement): cdef Expression symbol0 = self.coerce_in(var) return self._gobj.is_polynomial(symbol0._gobj) + @cython.binding(True) + @doc_index("xyz") cpdef bint is_relational(self): """ Return True if self is a relational expression. @@ -12800,3 +12806,5 @@ cdef operators compatible_relation(operators lop, operators rop) except <operato return greater else: raise TypeError("incompatible relations") + +__doc__ = __doc__.replace("{INDEX_OF_METHODS}",gen_thematic_rest_table_index(Expression))

I get:

`sage/symbolic/expression.pyx:2344:4: Cdef functions/classes cannot take arbitrary decorators.`

### comment:5 Changed 4 years ago by

Ah that is on top #23657 and may not apply cleanly to develop.

### comment:6 Changed 4 years ago by

Did you forget `cimport cython`

?

### comment:7 in reply to: ↑ 4 Changed 4 years ago by

Replying to rws:

`sage/symbolic/expression.pyx:2344:4: Cdef functions/classes cannot take arbitrary decorators.`

I see. The problem is that this is a `cpdef`

method.

### comment:8 Changed 4 years ago by

With `binding(True)`

, it is possible to have a working `doc_index`

for `cpdef`

methods, just not using the decorator syntax.

### comment:9 Changed 4 years ago by

The problem even with `def`

members is that, while it compiles, the doc will not build. The error given in the ticket description is still there.

### comment:10 follow-up: ↓ 11 Changed 4 years ago by

Not only doc building crashes, Sage itself crashes already at startup. I placed the decorator on `def is_exact`

:

/home/ralf/sage/local/lib/python2.7/site-packages/sage/misc/rest_index_of_methods.pyc in hey(f=<unbound method Expression.is_exact>) 303 INPUT: 304 305 - ``name`` -- a string, which will become the title of the index in which 306 this function/method will appear. 307 308 EXAMPLES:: 309 310 sage: from sage.misc.rest_index_of_methods import doc_index 311 sage: @doc_index("Wouhouuuuu") 312 ....: def a(): 313 ....: print("Hey") 314 sage: a.doc_index 315 'Wouhouuuuu' 316 """ 317 def hey(f): --> 318 setattr(f,"doc_index",name) global setattr = undefined f = <unbound method Expression.is_exact> global name = undefined 319 return f 320 return hey 321 322 __doc__ = __doc__.format(INDEX_OF_FUNCTIONS=gen_rest_table_index([gen_rest_table_index])) AttributeError: 'instancemethod' object has no attribute 'doc_index'

### comment:11 in reply to: ↑ 10 ; follow-up: ↓ 12 Changed 4 years ago by

### comment:12 in reply to: ↑ 11 Changed 4 years ago by

Replying to jdemeyer:

Replying to rws:

I placed the decorator on

`def is_exact`

:What is your exact diff here?

On top of develop:

diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 45f73f0851..75327bc1b5 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -2,6 +2,8 @@ """ Symbolic Expressions +{INDEX_OF_METHODS} + RELATIONAL EXPRESSIONS: We create a relational expression:: @@ -136,7 +138,7 @@ Test if :trac:`9947` is fixed:: # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function, absolute_import - +cimport cython from cysignals.signals cimport sig_on, sig_off from inspect import ismethod @@ -157,6 +159,7 @@ from sage.misc.derivative import multi_derivative from sage.misc.superseded import deprecated_function_alias, deprecation from sage.rings.infinity import AnInfinity, infinity, minus_infinity, unsigned_infinity from sage.misc.decorators import rename_keyword +from sage.misc.rest_index_of_methods import doc_index, gen_thematic_rest_table_index from sage.structure.dynamic_class import dynamic_class from sage.symbolic.operators import FDerivativeOperator, add_vararg, mul_vararg from sage.arith.numerical_approx cimport digits_to_bits @@ -2307,6 +2310,8 @@ cdef class Expression(CommutativeRingElement): """ return is_a_relational(self._gobj) + @cython.binding(True) + @doc_index("xyz") def is_exact(self): """ Return True if this expression only contains exact numerical coefficients. @@ -12755,3 +12760,5 @@ cdef operators compatible_relation(operators lop, operators rop) except <operato return greater else: raise TypeError("incompatible relations") + +__doc__ = __doc__.replace("{INDEX_OF_METHODS}",gen_thematic_rest_table_index(Expression))

### comment:13 Changed 4 years ago by

Right, I see. In my "stand-alone experiment", I didn't actually use a decorator. I just tried to see if it would work conceptually.

This works:

cimport cython from sage.misc.rest_index_of_methods import doc_index cdef class X: @cython.binding(True) def meth(self): return doc_index("foo")(X.__dict__["meth"])

But with a decorator, it does *not* work:

cimport cython from sage.misc.rest_index_of_methods import doc_index cdef class X: @doc_index("foo") @cython.binding(True) def meth(self): return

I would say that this is a Cython bug.

**Note:**See TracTickets for help on using tickets.

This may well be unsolvable. Opinions?