You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Trac #21322: coerce_binop has dangerous behaviour wrt additional arguments
`@coerce_binop` is an important decorator used on binary operators to
automagically apply the coercion framework on its arguments. It's widely
used on e.g. `gcd` operations (`_add_`, `_sub_` etc. have coercion
handled with another mechanism).
The current `@coerce_binop` has the following dangerous behaviour,
where, if the decorated method is given an extra unnamed argument, the
`self`-argument is swallowed:
{{{
sage: P.<x> = GF(5)[]
sage: f = x^2
sage: g = x
sage: f.gcd(g)
x
sage: f.gcd(g, 1)
1
}}}
The reason is that `@coerce_binop` included a hack to allow calls such
as
`Polynomial.gcd(f,g)` where `f` and `g` are polynomials and the `gcd`
method is
decorated with `@coerce_binop`. The reason that this required a hack at
all is that `@coerce_binop` was implemented as a class: it seems that
creating decorators as classes implies a very unfortunate behaviour:
{{{
class MyDec:
def __init__(self, f):
self.f = f
def __call__(self, x):
print "decorated: ", self , x
self.f(x)
mydec = MyDec
class A:
def __init__(self, a):
self.a = a
@mydec
def met(self, x):
print "x:", x
myA = A(1)
myA.met(5)
}}}
the above prints something like
{{{
decorated: <__main__.MyDec instance at 0x7f63c5ab6c20> 5
}}}
and then crashes with
{{{
AttributeError: MyDec instance has no attribute 'a'
}}}
This is because the `self` in `__call__` of `MyDec` becomes the `MyDec`
instance
-- the `A` instance is never passed to the decorating class instance!
The solution here is to rewrite `coerce_binop` as a function. At the
same time, we can use `@sage_wraps` which ensures proper documentation
(e.g. source file and line which was not retained in the previous
`coerce_binop`).
URL: https://trac.sagemath.org/21322
Reported by: jsrn
Ticket author(s): Johan Rosenkilde, Xavier Caruso
Reviewer(s): Miguel Marco
Copy file name to clipboardExpand all lines: src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py
+1-2Lines changed: 1 addition & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -1139,8 +1139,7 @@ def xgcd(self, right):
1139
1139
fromsage.misc.stopgapimportstopgap
1140
1140
stopgap("Extended gcd computations over p-adic fields are performed using the standard Euclidean algorithm which might produce mathematically incorrect results in some cases.", 13439)
0 commit comments