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