diff --git a/pymunk/constraints.py b/pymunk/constraints.py index 0aafa1b1..6a35448c 100644 --- a/pymunk/constraints.py +++ b/pymunk/constraints.py @@ -311,6 +311,8 @@ class PinJoint(Constraint): _pickle_attrs_init = Constraint._pickle_attrs_init + ["anchor_a", "anchor_b"] + _pickle_attrs_general = Constraint._pickle_attrs_general + ["distance"] + def __init__( self, a: "Body", @@ -828,6 +830,8 @@ class RatchetJoint(Constraint): _pickle_attrs_init = Constraint._pickle_attrs_init + ["phase", "ratchet"] + _pickle_attrs_general = Constraint._pickle_attrs_general + ["angle"] + def __init__(self, a: "Body", b: "Body", phase: float, ratchet: float) -> None: """Works like a socket wrench. diff --git a/pymunk/tests/test_constraint.py b/pymunk/tests/test_constraint.py index 9c4873f4..7f40fb24 100644 --- a/pymunk/tests/test_constraint.py +++ b/pymunk/tests/test_constraint.py @@ -1,3 +1,4 @@ +import copy import gc import pickle import unittest @@ -233,6 +234,7 @@ def test_distane(self) -> None: def test_pickle(self) -> None: a, b = p.Body(10, 10), p.Body(20, 20) j = PinJoint(a, b, (1, 2), (3, 4)) + j.distance = 8 s = pickle.dumps(j) j2 = pickle.loads(s) @@ -243,6 +245,18 @@ def test_pickle(self) -> None: self.assertEqual(j.a.mass, j2.a.mass) self.assertEqual(j.b.mass, j2.b.mass) + def test_copy_distance(self) -> None: + a, b = p.Body(10, 10), p.Body(20, 20) + b.position = (3, 4) + j = PinJoint(a, b) + j.distance = 8 + for clone in (j.copy, lambda: copy.deepcopy(j)): + with self.subTest(clone=clone): + j2 = clone() + self.assertEqual(j2.distance, 8) + self.assertIsNot(j2.a, a) + self.assertIsNot(j2.b, b) + class UnitTestSlideJoint(unittest.TestCase): def test_anchor(self) -> None: @@ -532,15 +546,29 @@ def test_ratchet(self) -> None: def test_pickle(self) -> None: a, b = p.Body(10, 10), p.Body(20, 20) j = RatchetJoint(a, b, 1, 2) + j.angle = 3 s = pickle.dumps(j) j2 = pickle.loads(s) + self.assertEqual(j.angle, j2.angle) self.assertEqual(j.phase, j2.phase) self.assertEqual(j.ratchet, j2.ratchet) self.assertEqual(j.a.mass, j2.a.mass) self.assertEqual(j.b.mass, j2.b.mass) + def test_copy_angle(self) -> None: + a, b = p.Body(10, 10), p.Body(20, 20) + b.angle = 0.25 + j = RatchetJoint(a, b, 0, 0.5) + j.angle = 1.5 + for clone in (j.copy, lambda: copy.deepcopy(j)): + with self.subTest(clone=clone): + j2 = clone() + self.assertEqual(j2.angle, 1.5) + self.assertIsNot(j2.a, a) + self.assertIsNot(j2.b, b) + class UnitTestGearJoint(unittest.TestCase): def test_phase(self) -> None: