Repository navigation
Proposal to add const-ness type hints #242
Description
Motivation - Python does not have a concept or notion of object const-ness. The const-ness is normally conveyed via doc strings which explain the usage contracts of the frameworks involved. However, this does not provide the necessary formalism required for static analysis tools (like pytype) to flag const-ness contract violations. Hence, we propose to add const-ness type hints to PEP-484 which can be used by static analysis tools to flag const-ness contract violations.
The Proposal
We propose adding two constructs:
The @constmethod decorator
This decorator can only be used to decorate instance methods. It describes methods which do not modify the instances on which they are invoked. That is, a method decorated with this decorator a) should not modify the fields on the object, b) should not call other methods which modify the fields of the object, c) and it should not pass non-primitive fields of the object to other callables which modify them.
Normally, this decorator would be used on getters. For example:
from typing import constmethod
class MyClass(object):
...
@constmethod
def get_something(self) -> int: ...
The protocol type-hint Const
This type-hint is used to describe function arguments and return values. When used to describe a function argument, it indicates that the function argument will not be modified by the function. It should only be used for non-primitive types. Example:
from typing import Const
def my_function(alist: Const[List[SomeClass]]) -> int: ...
The above indicates that the list argument alist will not be modified by my_function. Note that it does not indicate that the elements of the list are also not modified. If it is desired to indicate that even the elements are not modified, then one should use:
def my_function(alist: Const[List[Const[SomeClass]]]) -> int: ...
When Const is used as a type-hint on return values, it indicates that the value returned should not be modified by the caller. Example:
def my_function() -> Const[List[SomeClass]]: ...
This indicates that the returned list object should not be modified by the caller. As before, it does not indicate that the elements of the returned list should also not be modified. If even element const-ness is desired, then one should use:
def my_function() -> Const[List[Const[SomeClass]]]: ...
Activity
gvanrossum commentedon Jul 11, 2016
I shudder at the thought of having to annotate any significant piece of code with this.
I recommend that you try to implement a proof-of-concept prototype as a modification of mypy first and then see what it would take to productionize this, before we formally add this to PEP 484.
Final names and attributes (#5522)
vnmabus commentedon Sep 2, 2022
I also think that the protocol type-hint
Constwould be very useful. In particular, I think NumPy arrays are currently invariant with respect to their dtype, and I would want them to be contravariant in a function that don't modify them (similar to the proposal in numpy/numpy#16955, but without having to create and maintain a parallel const type).