Skip to content

Proposal to add const-ness type hints #242

Closed
python/mypy
#5522

Description

@sivachandra

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

  1. gvanrossum commented on Jul 11, 2016

    @gvanrossum
    Member

    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.

  2. added a commit that references this issue on Sep 11, 2018
  3. vnmabus commented on Sep 2, 2022

    @vnmabus

    I also think that the protocol type-hint Const would 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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions