File: test_literal_values.py

package info (click to toggle)
python-typing-inspection 0.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 384 kB
  • sloc: python: 1,120; makefile: 33; sh: 6
file content (79 lines) | stat: -rw-r--r-- 3,034 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import sys
import typing as t
from textwrap import dedent
from typing import Any

import pytest
import typing_extensions as t_e

from typing_inspection import typing_objects
from typing_inspection.introspection import get_literal_values

TypingAlias = t_e.TypeAliasType('TypingAlias', t.Literal[1, 'a'])


@pytest.mark.parametrize(
    ['annotation', 'expected'],
    [
        (t.Literal[1, 'a'], [1, 'a']),
        (t.Literal[1, 'a'], [1, 'a']),
        (t.Literal[1, TypingAlias], [1, TypingAlias]),
    ],
)
def test_literal_values_skip_aliases_no_type_check(annotation: Any, expected: list[Any]) -> None:
    result = get_literal_values(annotation, type_check=False, unpack_type_aliases='skip')
    assert list(result) == expected


def test_literal_values_skip_aliases_type_check() -> None:
    with pytest.raises(TypeError):
        list(get_literal_values(t.Literal[1, TypingAlias], type_check=True, unpack_type_aliases='skip'))


def test_literal_values_type_check() -> None:
    literal = t.Literal[1, True, False, b'', '', None, typing_objects.NoneType]
    expected = [1, True, False, b'', '', None]
    assert list(get_literal_values(literal, type_check=True, unpack_type_aliases='skip')) == expected
    assert list(get_literal_values(literal, type_check=True, unpack_type_aliases='eager')) == expected

    with pytest.raises(TypeError):
        list(get_literal_values(t.Literal[1.0], type_check=True, unpack_type_aliases='skip'))

    with pytest.raises(TypeError):
        list(get_literal_values(t.Literal[1.0], type_check=True, unpack_type_aliases='eager'))


def test_literal_values_unpack_type_aliases() -> None:
    TestType0 = t_e.TypeAliasType('TestType0', t_e.Literal['a'])
    TestType1 = t_e.TypeAliasType('TestType1', t_e.Literal[TestType0, 'b'])
    TestType2 = t_e.TypeAliasType('TestType2', t.Literal[TestType1, 'c'])

    expected = ['a', 'b', 'c', 'd']

    assert list(get_literal_values(t.Literal[TestType2, 'd'], unpack_type_aliases='eager')) == expected


@pytest.mark.skipif(sys.version_info < (3, 12), reason='Requires new `type` statement syntax.')
def test_literal_values_unpack_type_aliases_undefined(create_module) -> None:
    code = dedent("""
    from typing import Literal

    type TestType0 = Literal[Undefined, 'a']
    type TestType1 = Literal[TestType0, 'b']
    """)

    module = create_module(code)
    expected = [module.TestType0, 'b', 'c']

    assert list(get_literal_values(t.Literal[module.TestType1, 'c'], unpack_type_aliases='lenient')) == expected

    with pytest.raises(NameError):
        list(get_literal_values(t.Literal[module.TestType1, 'c'], unpack_type_aliases='eager'))

    with pytest.raises(TypeError):
        # As `TestType0` can't be unpacked, it isn't a valid literal value:
        list(get_literal_values(t.Literal[module.TestType1, 'c'], type_check=True, unpack_type_aliases='lenient'))


def test_literal_values_unhashable_type() -> None:
    assert list(get_literal_values(t_e.Literal[[1, 'a'], [1, 'a']])) == [[1, 'a'], [1, 'a']]  # noqa: PYI062