FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
cpython/Tools/scripts/find_recursionlimit.py at 3.9 · python-emscripten/cpython · GitHub
python-emscripten
cpython
Repository navigation
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
cpython
/
Tools
/
scripts
/
find_recursionlimit.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
executable file
·
128 lines (105 loc) · 3.9 KB
Breadcrumbs
cpython
/
Tools
/
scripts
/
find_recursionlimit.py
Copy path
File metadata and controls
executable file
·
128 lines (105 loc) · 3.9 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
#! /usr/bin/env python3
"""Find the maximum recursion limit that prevents interpreter termination.
This script finds the maximum safe recursion limit on a particular
platform. If you need to change the recursion limit on your system,
this script will tell you a safe upper bound. To use the new limit,
call sys.setrecursionlimit().
This module implements several ways to create infinite recursion in
Python. Different implementations end up pushing different numbers of
C stack frames, depending on how many calls through Python's abstract
C API occur.
After each round of tests, it prints a message:
"Limit of NNNN is fine".
The highest printed value of "NNNN" is therefore the highest potentially
safe limit for your system (which depends on the OS, architecture, but also
the compilation flags). Please note that it is practically impossible to
test all possible recursion paths in the interpreter, so the results of
this test should not be trusted blindly -- although they give a good hint
of which values are reasonable.
NOTE: When the C stack space allocated by your system is exceeded due
to excessive recursion, exact behaviour depends on the platform, although
the interpreter will always fail in a likely brutal way: either a
segmentation fault, a MemoryError, or just a silent abort.
NB: A program that does not use __methods__ can set a higher limit.
"""
import
sys
import
itertools
class
RecursiveBlowup1
:
def
__init__
(
self
):
self
.
__init__
()
def
test_init
():
return
RecursiveBlowup1
()
class
RecursiveBlowup2
:
def
__repr__
(
self
):
return
repr
(
self
)
def
test_repr
():
return
repr
(
RecursiveBlowup2
())
class
RecursiveBlowup4
:
def
__add__
(
self
,
x
):
return
x
+
self
def
test_add
():
return
RecursiveBlowup4
()
+
RecursiveBlowup4
()
class
RecursiveBlowup5
:
def
__getattr__
(
self
,
attr
):
return
getattr
(
self
,
attr
)
def
test_getattr
():
return
RecursiveBlowup5
().
attr
class
RecursiveBlowup6
:
def
__getitem__
(
self
,
item
):
return
self
[
item
-
2
]
+
self
[
item
-
1
]
def
test_getitem
():
return
RecursiveBlowup6
()[
5
]
def
test_recurse
():
return
test_recurse
()
def
test_cpickle
(
_cache
=
{}):
import
io
try
:
import
_pickle
except
ImportError
:
print
(
"cannot import _pickle, skipped!"
)
return
k
,
l
=
None
,
None
for
n
in
itertools
.
count
():
try
:
l
=
_cache
[
n
]
continue
# Already tried and it works, let's save some time
except
KeyError
:
for
i
in
range
(
100
):
l
=
[
k
,
l
]
k
=
{
i
:
l
}
_pickle
.
Pickler
(
io
.
BytesIO
(),
protocol
=
-
1
).
dump
(
l
)
_cache
[
n
]
=
l
def
test_compiler_recursion
():
# The compiler uses a scaling factor to support additional levels
# of recursion. This is a sanity check of that scaling to ensure
# it still raises RecursionError even at higher recursion limits
compile
(
"()"
*
(
10
*
sys
.
getrecursionlimit
()),
"<single>"
,
"single"
)
def
check_limit
(
n
,
test_func_name
):
sys
.
setrecursionlimit
(
n
)
if
test_func_name
.
startswith
(
"test_"
):
print
(
test_func_name
[
5
:])
else
:
print
(
test_func_name
)
test_func
=
globals
()[
test_func_name
]
try
:
test_func
()
# AttributeError can be raised because of the way e.g. PyDict_GetItem()
# silences all exceptions and returns NULL, which is usually interpreted
# as "missing attribute".
except
(
RecursionError
,
AttributeError
):
pass
else
:
print
(
"Yikes!"
)
if
__name__
==
'__main__'
:
limit
=
1000
while
1
:
check_limit
(
limit
,
"test_recurse"
)
check_limit
(
limit
,
"test_add"
)
check_limit
(
limit
,
"test_repr"
)
check_limit
(
limit
,
"test_init"
)
check_limit
(
limit
,
"test_getattr"
)
check_limit
(
limit
,
"test_getitem"
)
check_limit
(
limit
,
"test_cpickle"
)
check_limit
(
limit
,
"test_compiler_recursion"
)
print
(
"Limit of %d is fine"
%
limit
)
limit
=
limit
+
100
Back
|
FazBrowse Home
|
New Git URL