File: test_utils.py

package info (click to toggle)
python-pure-eval 0.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 164 kB
  • sloc: python: 1,305; sh: 22; makefile: 3
file content (145 lines) | stat: -rw-r--r-- 4,525 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import ast
import inspect
import io
import os
import re
import sys
import typing
from itertools import islice

import pytest

from pure_eval import CannotEval
from pure_eval.utils import (
    copy_ast_without_context,
    safe_name_types,
    safe_name_samples,
    safe_name,
    typing_annotation_samples,
    is_standard_types,
    ensure_dict,
)


def sys_modules_sources():
    for module in sys.modules.values():
        try:
            filename = inspect.getsourcefile(module)
        except TypeError:
            continue

        if not filename:
            continue

        filename = os.path.abspath(filename)
        try:
            with io.open(filename) as f:
                source = f.read()
        except OSError:
            continue

        tree = ast.parse(source)
        yield filename, source, tree


def test_sys_modules():
    modules = sys_modules_sources()
    if not os.environ.get('PURE_EVAL_SLOW_TESTS'):
        modules = islice(modules, 0, 3)

    for filename, source, tree in modules:
        print(filename)
        if not filename.endswith("ast.py"):
            check_copy_ast_without_context(tree)


def check_copy_ast_without_context(tree):
    tree2 = copy_ast_without_context(tree)
    dump1 = ast.dump(tree)
    dump2 = ast.dump(tree2)
    normalised_dump1 = re.sub(
        # Two possible matches:
        # - first one like ", ctx=…" where ", " should be removed
        # - second one like "(ctx=…" where "(" should be kept
        (
            r"("
                r", ctx=(Load|Store|Del)\(\)"
            r"|"
                r"(?<=\()ctx=(Load|Store|Del)\(\)"
            r")"
        ),
        "",
        dump1
    )
    assert normalised_dump1 == dump2


def test_repr_cannot_eval():
    assert repr(CannotEval()) == "CannotEval"


def test_safe_name_types():
    for f in safe_name_types:
        with pytest.raises(TypeError):
            f.__name__ = lambda: 0


def test_safe_name_samples():
    for name, f in {**safe_name_samples, **typing_annotation_samples}.items():
        assert name == safe_name(f)


def test_safe_name_direct():
    assert safe_name(list) == "list"
    assert safe_name(typing.List) == "List"
    assert safe_name(typing.Union) == "Union"
    assert safe_name(typing.Optional) == "Optional"
    assert safe_name(3) is None


def test_is_standard_types():
    assert is_standard_types(0, check_dict_values=True, deep=True)
    assert is_standard_types("0", check_dict_values=True, deep=True)
    assert is_standard_types([0], check_dict_values=True, deep=True)
    assert is_standard_types({0}, check_dict_values=True, deep=True)
    assert is_standard_types({0: "0"}, check_dict_values=True, deep=True)
    assert not is_standard_types(is_standard_types, check_dict_values=True, deep=True)
    assert not is_standard_types([is_standard_types], check_dict_values=True, deep=True)
    assert is_standard_types([is_standard_types], check_dict_values=True, deep=False)
    assert is_standard_types({is_standard_types}, check_dict_values=True, deep=False)
    assert is_standard_types(
        {is_standard_types: is_standard_types}, check_dict_values=True, deep=False
    )
    assert not is_standard_types(
        {is_standard_types: is_standard_types}, check_dict_values=True, deep=True
    )
    assert not is_standard_types(
        {0: is_standard_types}, check_dict_values=True, deep=True
    )
    assert is_standard_types({0: is_standard_types}, check_dict_values=False, deep=True)
    assert is_standard_types([[[[[[[{(0,)}]]]]]]], deep=True, check_dict_values=True)
    assert not is_standard_types(
        [[[[[[[{(is_standard_types,)}]]]]]]], deep=True, check_dict_values=True
    )

    lst = []
    lst.append(lst)
    assert is_standard_types(lst, deep=False, check_dict_values=True)
    assert not is_standard_types(lst, deep=True, check_dict_values=True)

    lst = [0] * 1000000
    assert is_standard_types(lst, deep=False, check_dict_values=True)
    assert is_standard_types(lst[0], deep=True, check_dict_values=True)
    assert not is_standard_types(lst, deep=True, check_dict_values=True)

    lst = [[0] * 1000] * 1000
    assert is_standard_types(lst, deep=False, check_dict_values=True)
    assert is_standard_types(lst[0], deep=True, check_dict_values=True)
    assert not is_standard_types(lst, deep=True, check_dict_values=True)


def test_ensure_dict():
    assert ensure_dict({}) == {}
    assert ensure_dict([]) == {}
    assert ensure_dict('foo') == {}
    assert ensure_dict({'a': 1}) == {'a': 1}