ilovewt
ilovewt

Reputation: 1023

List is invariant because it violates LSP?

Python's type system says that list is invariant, and that List[int] is not a subtype of List[float].

Here's the Python code snippet:

def append_pi(lst: List[float]) -> None:
    lst += [3.14]

my_list = [1, 3, 5]  # type: List[int]
append_pi(my_list)   # Expected to be safe, but it's not
my_list[-1] << 5     # This operation fails because the last element is no longer an int

In PEP 483, Guido explained the following:

Let us also consider a tricky example: If List[int] denotes the type formed by all lists containing only integer numbers, then it is not a subtype of List[float], formed by all lists that contain only real numbers. The first condition of subtyping holds, but appending a real number only works with List[float] so that the second condition fails.

I assumed that the second condition refers to the second criterion as per the subsumption criterion, where a type S is a subtype of T if it obeys function applicability. More specifically:

My question focuses on the apparent behavioral or semantic violation implicated in the operation of appending a float to a List[int], which to me does not contravene the first part of the second criterion of function applicability (since both List[int] and List[float] support the same set of methods). I'm grappling with understanding how this specific operation, which effectively introduces a float into a list expected exclusively to contain integers, results in a failure to adhere to the LSP by altering the List[int]'s presumed type integrity. This seems to suggest a deeper, perhaps semantic, aspect of type safety and method applicability under Python's type system that I might be missing. I would appreciate help on laying concretely and rigorously on why is Guido's claim on violating the second condition true.

Upvotes: 1

Views: 222

Answers (0)

Related Questions