Coverage for python/lsst/utils/ellipsis.py: 78%
9 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-01 02:29 -0700
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-01 02:29 -0700
1# This file is part of utils.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12"""
13A type-annotation workaround for ``...`` not having an exposed type in Python.
15This module provides ``Ellipsis`` and ``EllipsisType`` symbols that are
16conditionally defined to point to the built-in "``...``" singleton and its type
17(respectively) at runtime, and an enum class and instance if
18`typing.TYPE_CHECKING` is `True` (an approach first suggested
19`here <https://github.com/python/typing/issues/684#issuecomment-548203158>`_).
20Type checkers should recognize enum literals as singletons, making this pair
21behave as expected under ``is`` comparisons and type-narrowing expressions,
22such as::
24 v: EllipsisType | int
25 if v is not Ellipsis:
26 v += 2 # type checker should now see v as a pure int
28This works best when there is a clear boundary between code that needs to be
29type-checked and can use ``Ellipsis`` instead of a literal "``...``", and
30calling code that is either not type-checked or uses `typing.Any` to accept
31literal "``...``" values.
32"""
34from __future__ import annotations
36__all__ = ("Ellipsis", "EllipsisType")
38from typing import TYPE_CHECKING
40if TYPE_CHECKING:
41 from enum import Enum
43 class EllipsisType(Enum):
44 Ellipsis = "..."
46 Ellipsis = EllipsisType.Ellipsis
48else:
49 try:
50 # Present in Python >= 3.10
51 from types import EllipsisType
52 except ImportError:
53 EllipsisType = type(Ellipsis)
54 Ellipsis = Ellipsis