-
-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vector2.__new__ violates its interface contract #146
Conversation
@astronouth7303 Assigning this to you because I do not know well-enough the internals of the Python object model :3 |
According to >>> import copy
>>> copy.copy(Vector2(0, 0))
---------------------------------------------------------------------------
FrozenInstanceError Traceback (most recent call last)
<ipython-input-6-7fbabe237cc4> in <module>
----> 1 copy.copy(Vector2(0, 0))
/usr/lib/python3.7/copy.py in copy(x)
104 if isinstance(rv, str):
105 return x
--> 106 return _reconstruct(x, None, *rv)
107
108
/usr/lib/python3.7/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
290 if slotstate is not None:
291 for key, value in slotstate.items():
--> 292 setattr(y, key, value)
293
294 if listiter is not None:
<string> in __setattr__(self, name, value)
FrozenInstanceError: cannot assign to field 'x' Clearly something is still broken, though. I checked, and regular dataclasses are copyable without issue: >>> from dataclasses import dataclass
>>> @dataclass(frozen=True)
>>> class Foo:
>>> bar: str
>>> weight: float
>>> copy.copy(Foo("blah", 0.5))
Foo(bar='blah', weight=0.5) |
pings @astronouth7303 I ended up merging this branch into #144, because I ended up running into some of the issues fixed here, but I'd prefer to get this reviewed and merged first. The specific issue with |
Rebased to deal with a merge conflict. |
I'm just not buying that an argumentless |
How come that I guess I should split this into several PRs, and only keep the controversial |
This fixes a violation of the [protocol] for object construction: > If __new__ returns an instance of cls, then the new instance’s __init__() > method will be invoked like __init__(self[, ...]), where self is the new > instance and the remaining arguments are the same as were passed to __new__. [protocol]: https://docs.python.org/3/reference/datamodel.html#object.__new__
$157 was extracted from ppb#146, but this branch still depends on it.
It appears that when a custom This is fine for many standard Python classes (eg, the engine, systems, scenes, and sprites), this assumption falls apart for a slots-based immutable class. Keep in mind that pickle is standard library, not core interpreter. It's doing a lot of magic, but is making some assumptions while doing so. |
157: Vector.__reduce__: Do not invoke __new__ directly r=astronouth7303 a=nbraud This fixes a violation of the [protocol] for object construction: > If `__new__` returns an instance of `cls`, then the new instance’s `__init__()` method will be invoked like `__init__(self[, ...])`, where `self` is the new instance and the remaining arguments are the same as were passed to `__new__`. [protocol]: https://docs.python.org/3/reference/datamodel.html#object.__new__ @astronouth7303 seems [in agreement](#146 (comment)) Co-authored-by: Nicolas Braud-Santoni <nicolas@braud-santoni.eu>
Going to close this. |
While working on #144, I discovered that instances of
Vector2
cannot be copied (usingcopy.{copy,deepcopy}
), and I believe this is because we are violating the interface contract for__new__