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

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. 

11 

12""" 

13A type-annotation workaround for ``...`` not having an exposed type in Python 

14prior to version 3.10. 

15 

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:: 

24 

25 v: EllipsisType | int 

26 if v is not Ellipsis: 

27 v += 2 # type checker should now see v as a pure int 

28 

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""" 

34 

35from __future__ import annotations 

36 

37__all__ = ("Ellipsis", "EllipsisType") 

38 

39import warnings 

40from typing import TYPE_CHECKING 

41 

42if TYPE_CHECKING: 

43 from enum import Enum 

44 

45 class EllipsisType(Enum): 

46 """The type associated with an `...`""" 

47 

48 Ellipsis = "..." 

49 

50 Ellipsis = EllipsisType.Ellipsis 

51 

52else: 

53 try: 

54 # Present in Python >= 3.10 

55 from types import EllipsisType 

56 

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