Skip to content

Commit

Permalink
gh-37866: LPDictionary: Make it safe to copy dictionaries
Browse files Browse the repository at this point in the history
    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes #12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes #12345". -->

Dictionaries are mutable, and copying them using `copy` results in
dictionaries that share internal objects, which causes unwelcome
surprises.

- rebased from #31308

Author: @mkoeppe, @ComboProblem

Fixes #31308.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [ ] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - #12345: short description why this is a dependency -->
<!-- - #34567: ... -->
    
URL: #37866
Reported by: Matthias Köppe
Reviewer(s): Kwankyu Lee, Matthias Köppe
  • Loading branch information
Release Manager committed May 31, 2024
2 parents 2d5477e + 2e80f9a commit 5af1f8a
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/sage/numerical/interactive_simplex_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -3910,8 +3910,36 @@ def __init__(self, A, b, c, objective_value,
c = copy(c)
B = vector(basic_variables)
N = vector(nonbasic_variables)
# Issue #29101: vector does not guarantee that the result is freshly allocated
# if the input was already a vector
if B is basic_variables:
B = copy(B)
if N is nonbasic_variables:
N = copy(N)
self._AbcvBNz = [A, b, c, objective_value, B, N, polygen(ZZ, objective_name)]

def __copy__(self):
r"""
TESTS:
Test that copies do not share state with the original::
sage: A = ([1, 1], [3, 1])
sage: b = (1000, 1500)
sage: c = (10, 5)
sage: P = InteractiveLPProblemStandardForm(A, b, c)
sage: D = P.initial_dictionary()
sage: D_2 = copy(D)
sage: D is D_2
False
sage: D.enter('x1')
sage: D.leave('x3')
sage: D.update()
sage: D_2 == D
False
"""
return type(self)(*self._AbcvBNz)

@staticmethod
def random_element(m, n, bound=5, special_probability=0.2):
r"""
Expand Down

0 comments on commit 5af1f8a

Please sign in to comment.