On Mon, Sep 27, 2021 at 3:45 PM Brett Cannon <brett@python.org> wrote:
I was chatting with Guido about how there isn't an easy way to signal that something is a singleton. Concrete example:

```Python

_NOTHING = object()

class list(builtins.list):
    def __init__(self, iterable: Iterable | object = _NOTHING, /) -> None:
        if iterable is not _NOTHING:
            for item in iterable: ...  # Fails to type check.
```
Even if I define a class just for this use-case, it still won't type check since the class that is instantiated once will still not be an iterable.

```Python
class _NothingType:
    pass

_NOTHING = _NothingType()
```

I'm not sure how best to handle this case. But while chatting with Guido he suggested one possibility might be to somehow use `Final` to signify that an object is acting as a singleton. Maybe something like:
```Python
_NOTHING: Final[object] = object()
```

Then type checkers would know that `_NOTHING` is a singleton.

Basically I want a way to write the following without a type failure:
```Python
class list(builtins.list):
    def __init__(self, iterable: Iterable | _NOTHING = _NOTHING, /) -> None:
        if iterable is not _NOTHING:
            for item in iterable: ...
```

To be clear, I was advocating to use `Literal[_NOTHING]` in the union branch, *in addition* to `_NOTHING: Final = object()`. So the example would become

```py
_NOTHING: Final[object] = object()

class list(builtins.list):
    def __init__(self, iterable: Iterable | Literal[_NOTHING] = _NOTHING, /) -> None:
        if iterable is not _NOTHING:
            for item in iterable: ...
```

(And no, there's no reason we're using `class list` as the example except that's what prompted Brett to bring this up.)

--
--Guido van Rossum (python.org/~guido)