Open cojmeister opened 9 months ago
There's also this existing discussion on the Python Discourse: https://discuss.python.org/t/extend-the-typing-final-type-qualifier-to-support-function-arguments/41916
I personally don't think Final
is a good equivalent for the absence of Rust's mut
. They actually mean quite different things and an Immutable
modifier would be difficult to support from a type checker's perspective unless you treat all method calls as mutations by default and then also add an @idempotent
decorator to mark methods that are fine to call on Immutable
references to objects.
Also you are using str
in your example which is an immutable type in Python, so your example never modifies changeable
or unchangeable
regardless, it will always create new str
instances, even for +=
.
I agree. I was just passing it as an example, rust comes easier to me than cpp. As for the string, it was there for the simplicity of the example. Imagine using a dataclass and a struct in cpp/rust instead of a string. The idea is to type something as final and getting warned if it is changed in the method, or being able to know when calling a function if something is going to be changed or not. On 2 Jan 2024 at 12:40 -0300, David Salvisberg @.***>, wrote:
There's also this existing discussion on the Python Discourse: https://discuss.python.org/t/extend-the-typing-final-type-qualifier-to-support-function-arguments/41916 I personally don't think Final is a good equivalent for Rust's mut. They actually mean quite different things and an Immutable modifier would be difficult to support from a type checker's perspective unless you treat all method calls as mutations by default and then also add an @idempotent decorator to mark methods that are fine to call on Immutable references to objects. Also you are using str in your example which is an immutable type in Python, so your example never modifies changeable or unchangeable regardless, it will always create new str instances, even for +=. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
Yes, but that's not what Final
means. Final
is closer to const
, i.e. you can't reassign the name to something else, but it doesn't prevent mutations.
x: Final[dict[str, int]] = {}
x["five"] = 5 # this is allowed
x.clear() # this is also allowed
x = {} # but this is forbidden
But tracking mutations statically in Python is tricky if not impossible (especially in pyi files), hence the additional need for telling the type checker which methods will cause an object to be mutated. So this is a massive change and will require a PEP, it's not as simple as allowing Final
in function signatures.
Ooh Now I’ve understood. Thanks for explaining On 2 Jan 2024 at 13:59 -0300, David Salvisberg @.***>, wrote:
Yes, but that's not what Final means. Final is closer to const, i.e. you can't reassign the name to something else, but it doesn't prevent mutations. x: Final[dict[str, int]] = {} x["five"] = 5 # this is allowed x.clear() # this is also allowed x = {} # but this is forbidden But tracking mutations statically in Python is tricky if not impossible (especially in pyi files), hence the additional need for telling the type checker which methods will cause an object to be mutated. So this is a massive change and will require a PEP, it's not as simple as allowing Final in function signatures. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>
Proposal: The idea is to be able to pass variables as constants, mimicking c++ or rust behaviour such as. And have this be solely as part of the typings ecosystem. It's extremely helpful when reviewing code, or starting to use new codebases.
Issue opened in cpython repo: #113654
In python I suggest the following: