Coverage for python/lsst/utils/ellipsis.py: 82%
11 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-20 10:50 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-20 10:50 +0000
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
14prior to version 3.10.
16This module provides ``Ellipsis`` and ``EllipsisType`` symbols that are
17conditionally defined to point to the built-in "``...``" singleton and its type
18(respectively) at runtime, and an enum class and instance if
19`typing.TYPE_CHECKING` is `True` (an approach first suggested
20`here <https://github.com/python/typing/issues/684#issuecomment-548203158>`_).
21Type checkers should recognize enum literals as singletons, making this pair
22behave as expected under ``is`` comparisons and type-narrowing expressions,
23such as::
25 v: EllipsisType | int
26 if v is not Ellipsis:
27 v += 2 # type checker should now see v as a pure int
29This works best when there is a clear boundary between code that needs to be
30type-checked and can use ``Ellipsis`` instead of a literal "``...``", and
31calling code that is either not type-checked or uses `typing.Any` to accept
32literal "``...``" values.
33"""
35from __future__ import annotations
37__all__ = ("Ellipsis", "EllipsisType")
39import warnings
40from typing import TYPE_CHECKING
42if TYPE_CHECKING:
43 from enum import Enum
45 class EllipsisType(Enum):
46 """The type associated with an `...`"""
48 Ellipsis = "..."
50 Ellipsis = EllipsisType.Ellipsis
52else:
53 try:
54 # Present in Python >= 3.10
55 from types import EllipsisType
57 # If EllipsisType is defined then produce a deprecation warning.
58 warnings.warn(
59 f"Module {__name__} is deprecated for Python 3.10 or later, native type `types.EllipsisType` "
60 "should be used instead.",
61 DeprecationWarning,
62 stacklevel=2,
63 )
64 except ImportError:
65 EllipsisType = type(Ellipsis)
66 Ellipsis = Ellipsis