# Amend PEP 586 to make \`enum\` values subtypes of \`Literal\`

**URL:** <https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456>\
**Category:** Typing\
**Tags:** typing\
**Created:** [July 29, 2024, 3:40pm UTC](https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456 "2024-07-29T15:40:42Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![Jelle](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jelle/32/1049_2.png) [@Jelle](https://discuss.python.org/u/Jelle)\
**Post date:** [June 6, 2025, 2:01pm UTC](https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456/4 "2025-06-06T14:01:00Z")

</div>

I don’t think this should be allowed. We should instead say clearly that `Literal[X]` means that the object is exactly that value, i.e. `Literal[1]` is only the instance of int, not a subclass.

Allowing subclasses of ints to inhabit Literal[1] would break a lot of assumptions that type checkers use and that make Literals convenient to use. For example, type checkers may use `x == 1` to narrow a type to `Literal[1]`; or `if x` to narrow `Literal[0]` out of a type; or they may support mathematical operations on literals. All of those become unsafe if the object may be a subclass of int.

Here’s a sample of unsound behaviors in pyright due to this feature:

```python
from enum import IntEnum
from typing import Literal

class X(IntEnum):
    a = 1

    def __add__ (self, value: int, /) -> int:
        return self.value + value + 42

    def __eq__ (self, other: object):
        return False

    def __bool__ (self) -> bool:
        return False

def f(x: Literal[1]):
    print(reveal_type(x + 1)) # 44 at runtime, 2 according to pyright

def g(x: Literal[1, 2]):
    if x == 1: # false for X.a
        reveal_type(x) # Literal[1]
    else:
        reveal_type(x) # Literal[2]

def h(x: Literal[0, 1]):
    if x: # false for X.a
        reveal_type(x) # Literal[1]
    else:
        reveal_type(x) # Literal[0]

f(X.a)
g(X.a)
h(X.a)

```

---

_[View the full topic](https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456)._
