Opened 8 years ago
Closed 8 years ago
#15321 closed defect (invalid)
Function changes behaviour, related to polynomial rings
Reported by: | gagern | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | sage-duplicate/invalid/wontfix |
Component: | algebra | Keywords: | |
Cc: | Merged in: | ||
Authors: | Reviewers: | Nils Bruin | |
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description (last modified by )
I've just observed the following strange behaviour in sage 5.12:
sage: PR1 = PolynomialRing(QQ, ["t" + str(i) for i in range(10)]) sage: t = PR1.gens() sage: def L(r, j): ... return (t[r] - t[r + j])/t[r + j] ... sage: PR2 = PolynomialRing(PR1.fraction_field(), ["p" + str(i) for i in range(5)]) sage: p = PR2.gens() sage: def D(r): ... return sum(L(r, j)*p[r-4+j] for j in range(3)) ... sage: D(4) ((t4 - t5)/t5)*p1 + ((t4 - t6)/t6)*p2 sage: myc = list(D(4)) # here the command works all right sage: D(4) # reproducing the call still works fine here ((t4 - t5)/t5)*p1 + ((t4 - t6)/t6)*p2 sage: [c for c, p in myc] # THIS LINE APPEARS TO BREAK THINGS! [(t4 - t5)/t5, (t4 - t6)/t6] sage: D(4) # now the result is wrong, no error reported 0 sage: myc = list(D(4)) # and this throws, probably due to the zero result Traceback (most recent call last): ... TypeError: 'sage.rings.fraction_field_element.FractionFieldElement' object is not iterable
So it seems that repeated execution of the same function can yield different (and sometimes wrong!) results if some result was iterated over in a certain way. No clue why.
Change History (5)
comment:1 Changed 8 years ago by
- Description modified (diff)
comment:2 follow-up: ↓ 3 Changed 8 years ago by
- Milestone changed from sage-5.13 to sage-duplicate/invalid/wontfix
- Status changed from new to needs_review
comment:3 in reply to: ↑ 2 Changed 8 years ago by
Replying to nbruin:
This is not a problem in Sage, but a documented "feature" of Python2. […] List comprehensions leak their variables, so the value of your global variable p […] gets overwritten.
Thanks for clarifying this.
I seem to have a knack for reporting things in the wrong place: I tend to ask questions on Ask Sage which turn out to be bugs, and now I asked here about what felt like a sure bug, and it turns out to be “a feature” or at least not Sage's bug, so it might have been more appropriate to use that Q&A forum instead.
comment:4 Changed 8 years ago by
- Reviewers set to Nils Bruin
- Status changed from needs_review to positive_review
comment:5 Changed 8 years ago by
- Resolution set to invalid
- Status changed from positive_review to closed
This is not a problem in Sage, but a documented "feature" of Python2. It was realized to be a wart and fixed in Python3. The problem is indeed the line you mark:
List comprehensions leak their variables, so the value of your global variable p (which gets used in your function
D
) gets overwritten. This problem does not with happen if you writebecause iterators do not leak their variables. In Python3, list comprehensions share the same semantics as iterators.
It's a wart, but as long as we stick with Python2 we'll have to live with it. Ways to mitigate the problem:
PR2
as one of its parameters).list(...)
rather than[...]
if you don't want to leak variables into scope.Polynomials are indexable and iterable (for better or for worse), but fraction field elements are not. Thus, you have: