Skip to content

tuple & AlwaysFalsy should simplify to tuple[()] #215

@AlexWaygood

Description

@AlexWaygood

Here's what these types represent:

  • tuple: the set of all possible runtime instances of the class tuple (including instances of tuple subclasses)
  • AlwaysFalsy: the set of all possible runtime objects whose truthiness can be statically determined to always be false
  • tuple[()]: the set of all possible zero-length tuples (including zero-length instances of tuple subclasses)
  • tuple & AlwaysFalsy: the set of all possible runtime instances of the class tuple (including instances of tuple subclasses) whose truthiness can be statically determined to always be false

Tuple instances (and instances of any tuple subclass, assuming the subclass conforms to the Liskov principle) are only ever falsy if they are 0-length, so the set of possible objects represented by tuple & AlwaysFalsy is exactly the same as the set of possible objects represented by tuple[()]. By the same token, tuple & ~AlwaysTruthy should also simplify to tuple[()].

The same can not be said for things like bytes & AlwaysFalsy (this does not simplify to Literal[b""]), because bytes can be subclassed, and instances of bytes subclasses can also be falsy if they are empty bytestrings, but for a type to inhabit a literal bytes type its __class__ must be exactly bytes, not a subclass of bytes. Heterogeneous tuple types are different from Literal types in this way, in that they can be inhabited by subclasses of tuple as well as literal tuples.

We should adapt the logic in InnerIntersectionBuilder to eagerly perform this simplification when we see the intersection tuple & AlwaysFalsy.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingset-theoretic typesunions, intersections and moretype propertiessubtyping, assignability, equivalence, and more

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions