-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathtest_circular.py
More file actions
96 lines (72 loc) · 2.55 KB
/
test_circular.py
File metadata and controls
96 lines (72 loc) · 2.55 KB
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
# -*- coding: utf-8 -*-
# :Project: python-rapidjson -- Circular references tests
# :Author: John Anderson <sontek@gmail.com>
# :License: MIT License
# :Copyright: © 2015 John Anderson
# :Copyright: © 2017, 2018, 2020, 2023, 2024 Lele Gaifax
#
import sys
import pytest
def test_circular_dict(dumps):
dct = {}
dct['a'] = dct
with pytest.raises(RecursionError):
dumps(dct)
def test_circular_list(dumps):
lst = []
lst.append(lst)
with pytest.raises(RecursionError):
dumps(lst)
def test_circular_composite(dumps):
dct2 = {}
dct2['a'] = []
dct2['a'].append(dct2)
with pytest.raises(RecursionError):
dumps(dct2)
if sys.version_info < (3, 12):
# In Python 3.12 and beyond builtin functions are not affected by the recursion limit.
#
# See the issue https://github.com/python/cpython/issues/107263 and the question
# that originated it, then the NEWS introduced by this commit
# https://github.com/python/cpython/commit/fa45958450aa3489607daf9855ca0474a2a20878:
#
# The recursion limit [that is sys.setrecursionlimit() and sys.getrecursionlimit()]
# now applies only to Python code. Builtin functions do not use the recursion
# limit, but are protected by a different mechanism that prevents recursion from
# causing a virtual machine crash.
def test_max_recursion_depth(dumps):
root = child = {}
for i in range(500):
nephew = {'value': i}
child['child'] = nephew
child = nephew
dumps(root)
rl = sys.getrecursionlimit()
if hasattr(sys, "pyston_version_info"):
# In Pyston setrecursionlimit() sets a lower bound on the number of frames,
# not an exact count. So set the limit lower:
sys.setrecursionlimit(100)
else:
# Otherwise set it to the exact value:
sys.setrecursionlimit(500)
try:
with pytest.raises(RecursionError):
dumps(root)
finally:
sys.setrecursionlimit(rl)
def test_parse_respects_recursion_limit(loads):
rl = sys.getrecursionlimit()
deep_array = '[' * rl + ']' * rl
deep_obj = '{}'
for depth in range(rl-1):
deep_obj = '{"obj": ' + deep_obj + '}'
loads(deep_array)
loads(deep_obj)
sys.setrecursionlimit(rl // 2)
try:
with pytest.raises(RecursionError):
loads(deep_array)
with pytest.raises(RecursionError):
loads(deep_obj)
finally:
sys.setrecursionlimit(rl)