python / typing

Python static typing home. Hosts the documentation and a user help forum.
https://typing.readthedocs.io/
Other
1.59k stars 234 forks source link

Pass variable as final #1557

Open cojmeister opened 9 months ago

cojmeister commented 9 months ago

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

fn my_function(mut changeable: &String, unchangeable: &String) {}

In python I suggest the following:

def my_function(changeable: str, unchangeable: Final[str])-> None:
    arguments_that_changes += "world!"
    return arguments_that_changes + argument_that_stays_constant
Daverball commented 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 +=.

cojmeister commented 9 months ago

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: @.***>

Daverball commented 9 months ago

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.

cojmeister commented 9 months ago

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: @.***>