Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
b843cdb9
Commit
b843cdb9
authored
Feb 26, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit '26453' into refcounting
parents
3bedca63
2645311f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
11 additions
and
635 deletions
+11
-635
from_cpython/Lib/test/test_ast.py
from_cpython/Lib/test/test_ast.py
+0
-1
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+9
-5
src/core/options.cpp
src/core/options.cpp
+1
-1
src/jit.cpp
src/jit.cpp
+1
-1
test/CPYTHON_TEST_NOTES.md
test/CPYTHON_TEST_NOTES.md
+0
-1
test/tests/test_ast.expected
test/tests/test_ast.expected
+0
-32
test/tests/test_ast.py
test/tests/test_ast.py
+0
-594
No files found.
from_cpython/Lib/test/test_ast.py
View file @
b843cdb9
# expected: fail
import
sys
,
itertools
,
unittest
from
test
import
test_support
import
ast
...
...
src/codegen/irgen/hooks.cpp
View file @
b843cdb9
...
...
@@ -497,9 +497,10 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
AST
*
parsed
;
mod_ty
mod
;
ArenaWrapper
arena
;
if
(
PyAST_Check
(
source
))
{
int
mode
;
ArenaWrapper
arena
;
if
(
type_str
->
s
()
==
"exec"
)
mode
=
0
;
else
if
(
type_str
->
s
()
==
"eval"
)
...
...
@@ -509,10 +510,12 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
else
{
raiseExcHelper
(
ValueError
,
"compile() arg 3 must be 'exec', 'eval' or 'single'"
);
}
if
(
only_ast
)
// nothing to do
return
source
;
mod
=
PyAST_obj2mod
(
source
,
arena
,
mode
);
if
(
PyErr_Occurred
())
throwCAPIException
();
parsed
=
cpythonToPystonAST
(
mod
,
filename_str
->
c_str
());
}
else
{
RELEASE_ASSERT
(
PyString_Check
(
source
),
""
);
int
mode
;
...
...
@@ -528,15 +531,12 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
PyCompilerFlags
cf
;
cf
.
cf_flags
=
future_flags
;
ArenaWrapper
arena
;
const
char
*
code
=
static_cast
<
BoxedString
*>
(
source
)
->
s
().
data
();
assert
(
arena
);
const
char
*
fn
=
filename_str
->
c_str
();
mod
=
PyParser_ASTFromString
(
code
,
fn
,
mode
,
&
cf
,
arena
);
if
(
!
mod
)
throwCAPIException
();
parsed
=
cpythonToPystonAST
(
mod
,
filename_str
->
c_str
());
}
if
(
only_ast
)
{
...
...
@@ -547,6 +547,10 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
return
result
;
}
// be careful when moving around this function: it does also do some additional syntax checking (=raises exception),
// which we should not do when in AST only mode.
parsed
=
cpythonToPystonAST
(
mod
,
filename_str
->
c_str
());
PyCompilerFlags
pcf
;
pcf
.
cf_flags
=
future_flags
;
...
...
src/core/options.cpp
View file @
b843cdb9
...
...
@@ -38,7 +38,7 @@ bool USE_STRIPPED_STDLIB = true; // always true
bool
ENABLE_INTERPRETER
=
false
;
// XXX
bool
ENABLE_BASELINEJIT
=
false
;
// XXX
bool
ENABLE_PYPA_PARSER
=
true
;
bool
ENABLE_CPYTHON_PARSER
=
fals
e
;
bool
ENABLE_CPYTHON_PARSER
=
tru
e
;
bool
USE_REGALLOC_BASIC
=
false
;
bool
PAUSE_AT_ABORT
=
false
;
bool
ENABLE_TRACEBACKS
=
true
;
...
...
src/jit.cpp
View file @
b843cdb9
...
...
@@ -220,7 +220,7 @@ int handleArg(char code) {
}
else
if
(
code
==
'x'
)
{
ENABLE_PYPA_PARSER
=
false
;
}
else
if
(
code
==
'X'
)
{
ENABLE_CPYTHON_PARSER
=
tru
e
;
ENABLE_CPYTHON_PARSER
=
fals
e
;
}
else
if
(
code
==
'E'
)
{
Py_IgnoreEnvironmentFlag
=
1
;
}
else
if
(
code
==
'P'
)
{
...
...
test/CPYTHON_TEST_NOTES.md
View file @
b843cdb9
...
...
@@ -24,7 +24,6 @@ test_al No module named al
test_applesingle Not really a failure, but it tries to skip itself and we don't support that
test_argparse [unknown]
test_ascii_formatd segfault in ctypes (but only on CI)
test_ast mismatch of parser error checks. remove test/tests/test_ast.py when the orig test passes
test_asynchat [unknown]
test_asyncore [unknown]
test_atexit [unknown]
...
...
test/tests/test_ast.expected
deleted
100644 → 0
View file @
3bedca63
test_AST_objects (__main__.AST_Tests) ... ok
test_arguments (__main__.AST_Tests) ... ok
test_base_classes (__main__.AST_Tests) ... ok
test_classattrs (__main__.AST_Tests) ... ok
test_field_attr_existence (__main__.AST_Tests) ... ok
test_field_attr_writable (__main__.AST_Tests) ... ok
test_from_import (__main__.AST_Tests) ... ok
test_invalid_identitifer (__main__.AST_Tests) ... ok
test_invalid_string (__main__.AST_Tests) ... ok
test_module (__main__.AST_Tests) ... ok
test_no_fields (__main__.AST_Tests) ... ok
test_nodeclasses (__main__.AST_Tests) ... ok
test_non_interned_future_from_ast (__main__.AST_Tests) ... ok
test_pickling (__main__.AST_Tests) ... skipped 'parse error'
test_slice (__main__.AST_Tests) ... ok
test_snippets (__main__.AST_Tests) ... skipped 'parse error'
test_copy_location (__main__.ASTHelpers_Test) ... ok
test_dump (__main__.ASTHelpers_Test) ... ok
test_fix_missing_locations (__main__.ASTHelpers_Test) ... ok
test_get_docstring (__main__.ASTHelpers_Test) ... ok
test_increment_lineno (__main__.ASTHelpers_Test) ... ok
test_iter_child_nodes (__main__.ASTHelpers_Test) ... ok
test_iter_fields (__main__.ASTHelpers_Test) ... ok
test_literal_eval (__main__.ASTHelpers_Test) ... ok
test_literal_eval_issue4907 (__main__.ASTHelpers_Test) ... ok
test_parse (__main__.ASTHelpers_Test) ... ok
----------------------------------------------------------------------
Ran 26 tests in TIME
OK (skipped=2)
test/tests/test_ast.py
deleted
100644 → 0
View file @
3bedca63
# This is a copy of cpythons test with two tests disabled
# remove this test when we can pass cpythons test
import
sys
,
itertools
,
unittest
from
test
import
test_support
import
ast
def
to_tuple
(
t
):
if
t
is
None
or
isinstance
(
t
,
(
basestring
,
int
,
long
,
complex
)):
return
t
elif
isinstance
(
t
,
list
):
return
[
to_tuple
(
e
)
for
e
in
t
]
result
=
[
t
.
__class__
.
__name__
]
if
hasattr
(
t
,
'lineno'
)
and
hasattr
(
t
,
'col_offset'
):
result
.
append
((
t
.
lineno
,
t
.
col_offset
))
if
t
.
_fields
is
None
:
return
tuple
(
result
)
for
f
in
t
.
_fields
:
result
.
append
(
to_tuple
(
getattr
(
t
,
f
)))
return
tuple
(
result
)
# These tests are compiled through "exec"
# There should be at least one test per statement
exec_tests
=
[
# None
"None"
,
# FunctionDef
"def f(): pass"
,
# FunctionDef with arg
"def f(a): pass"
,
# FunctionDef with arg and default value
"def f(a=0): pass"
,
# FunctionDef with varargs
"def f(*args): pass"
,
# FunctionDef with kwargs
"def f(**kwargs): pass"
,
# FunctionDef with all kind of args
"def f(a, b=1, c=None, d=[], e={}, *args, **kwargs): pass"
,
# ClassDef
"class C:pass"
,
# ClassDef, new style class
"class C(object): pass"
,
# Return
"def f():return 1"
,
# Delete
"del v"
,
# Assign
"v = 1"
,
# AugAssign
"v += 1"
,
# Print
"print >>f, 1, "
,
# For
"for v in v:pass"
,
# While
"while v:pass"
,
# If
"if v:pass"
,
# Raise
"raise Exception, 'string'"
,
# TryExcept
"try:
\
n
pass
\
n
except Exception:
\
n
pass"
,
# TryFinally
"try:
\
n
pass
\
n
finally:
\
n
pass"
,
# Assert
"assert v"
,
# Import
"import sys"
,
# ImportFrom
"from sys import v"
,
# Exec
"exec 'v'"
,
# Global
"global v"
,
# Expr
"1"
,
# Pass,
"pass"
,
# Break
"break"
,
# Continue
"continue"
,
# for statements with naked tuples (see http://bugs.python.org/issue6704)
"for a,b in c: pass"
,
"[(a,b) for a,b in c]"
,
"((a,b) for a,b in c)"
,
"((a,b) for (a,b) in c)"
,
# Multiline generator expression (test for .lineno & .col_offset)
"""(
(
Aa
,
Bb
)
for
Aa
,
Bb in Cc
)"""
,
# dictcomp
"{a : b for w in x for m in p if g}"
,
# dictcomp with naked tuple
"{a : b for v,w in x}"
,
# setcomp
"{r for l in x if g}"
,
# setcomp with naked tuple
"{r for l,m in x}"
,
]
# These are compiled through "single"
# because of overlap with "eval", it just tests what
# can't be tested with "eval"
single_tests
=
[
"1+2"
]
# These are compiled through "eval"
# It should test all expressions
eval_tests
=
[
# None
"None"
,
# BoolOp
"a and b"
,
# BinOp
"a + b"
,
# UnaryOp
"not v"
,
# Lambda
"lambda:None"
,
# Dict
"{ 1:2 }"
,
# Empty dict
"{}"
,
# Set
"{None,}"
,
# Multiline dict (test for .lineno & .col_offset)
"""{
1
:
2
}"""
,
# ListComp
"[a for b in c if d]"
,
# GeneratorExp
"(a for b in c if d)"
,
# Yield - yield expressions can't work outside a function
#
# Compare
"1 < 2 < 3"
,
# Call
"f(1,2,c=3,*d,**e)"
,
# Repr
"`v`"
,
# Num
"10L"
,
# Str
"'string'"
,
# Attribute
"a.b"
,
# Subscript
"a[b:c]"
,
# Name
"v"
,
# List
"[1,2,3]"
,
# Empty list
"[]"
,
# Tuple
"1,2,3"
,
# Tuple
"(1,2,3)"
,
# Empty tuple
"()"
,
# Combination
"a.b.c.d(a.b[1:2])"
,
]
# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
# excepthandler, arguments, keywords, alias
class
AST_Tests
(
unittest
.
TestCase
):
def
_assertTrueorder
(
self
,
ast_node
,
parent_pos
):
if
not
isinstance
(
ast_node
,
ast
.
AST
)
or
ast_node
.
_fields
is
None
:
return
if
isinstance
(
ast_node
,
(
ast
.
expr
,
ast
.
stmt
,
ast
.
excepthandler
)):
node_pos
=
(
ast_node
.
lineno
,
ast_node
.
col_offset
)
self
.
assertTrue
(
node_pos
>=
parent_pos
)
parent_pos
=
(
ast_node
.
lineno
,
ast_node
.
col_offset
)
for
name
in
ast_node
.
_fields
:
value
=
getattr
(
ast_node
,
name
)
if
isinstance
(
value
,
list
):
for
child
in
value
:
self
.
_assertTrueorder
(
child
,
parent_pos
)
elif
value
is
not
None
:
self
.
_assertTrueorder
(
value
,
parent_pos
)
def
test_AST_objects
(
self
):
x
=
ast
.
AST
()
self
.
assertEqual
(
x
.
_fields
,
())
with
self
.
assertRaises
(
AttributeError
):
x
.
vararg
with
self
.
assertRaises
(
AttributeError
):
x
.
foobar
=
21
with
self
.
assertRaises
(
AttributeError
):
ast
.
AST
(
lineno
=
2
)
with
self
.
assertRaises
(
TypeError
):
# "_ast.AST constructor takes 0 positional arguments"
ast
.
AST
(
2
)
# Pyston change: skip this test for now
@
unittest
.
skip
(
"parse error"
)
def
test_snippets
(
self
):
for
input
,
output
,
kind
in
((
exec_tests
,
exec_results
,
"exec"
),
(
single_tests
,
single_results
,
"single"
),
(
eval_tests
,
eval_results
,
"eval"
)):
for
i
,
o
in
itertools
.
izip
(
input
,
output
):
ast_tree
=
compile
(
i
,
"?"
,
kind
,
ast
.
PyCF_ONLY_AST
)
self
.
assertEqual
(
to_tuple
(
ast_tree
),
o
)
self
.
_assertTrueorder
(
ast_tree
,
(
0
,
0
))
def
test_slice
(
self
):
slc
=
ast
.
parse
(
"x[::]"
).
body
[
0
].
value
.
slice
self
.
assertIsNone
(
slc
.
upper
)
self
.
assertIsNone
(
slc
.
lower
)
self
.
assertIsInstance
(
slc
.
step
,
ast
.
Name
)
self
.
assertEqual
(
slc
.
step
.
id
,
"None"
)
def
test_from_import
(
self
):
im
=
ast
.
parse
(
"from . import y"
).
body
[
0
]
self
.
assertIsNone
(
im
.
module
)
def
test_non_interned_future_from_ast
(
self
):
mod
=
ast
.
parse
(
"from __future__ import division"
)
self
.
assertIsInstance
(
mod
.
body
[
0
],
ast
.
ImportFrom
)
mod
.
body
[
0
].
module
=
" __future__ "
.
strip
()
compile
(
mod
,
"<test>"
,
"exec"
)
def
test_base_classes
(
self
):
self
.
assertTrue
(
issubclass
(
ast
.
For
,
ast
.
stmt
))
self
.
assertTrue
(
issubclass
(
ast
.
Name
,
ast
.
expr
))
self
.
assertTrue
(
issubclass
(
ast
.
stmt
,
ast
.
AST
))
self
.
assertTrue
(
issubclass
(
ast
.
expr
,
ast
.
AST
))
self
.
assertTrue
(
issubclass
(
ast
.
comprehension
,
ast
.
AST
))
self
.
assertTrue
(
issubclass
(
ast
.
Gt
,
ast
.
AST
))
def
test_field_attr_existence
(
self
):
for
name
,
item
in
ast
.
__dict__
.
iteritems
():
if
isinstance
(
item
,
type
)
and
name
!=
'AST'
and
name
[
0
].
isupper
():
x
=
item
()
if
isinstance
(
x
,
ast
.
AST
):
self
.
assertEqual
(
type
(
x
.
_fields
),
tuple
)
def
test_arguments
(
self
):
x
=
ast
.
arguments
()
self
.
assertEqual
(
x
.
_fields
,
(
'args'
,
'vararg'
,
'kwarg'
,
'defaults'
))
with
self
.
assertRaises
(
AttributeError
):
x
.
vararg
x
=
ast
.
arguments
(
1
,
2
,
3
,
4
)
self
.
assertEqual
(
x
.
vararg
,
2
)
def
test_field_attr_writable
(
self
):
x
=
ast
.
Num
()
# We can assign to _fields
x
.
_fields
=
666
self
.
assertEqual
(
x
.
_fields
,
666
)
def
test_classattrs
(
self
):
x
=
ast
.
Num
()
self
.
assertEqual
(
x
.
_fields
,
(
'n'
,))
with
self
.
assertRaises
(
AttributeError
):
x
.
n
x
=
ast
.
Num
(
42
)
self
.
assertEqual
(
x
.
n
,
42
)
with
self
.
assertRaises
(
AttributeError
):
x
.
lineno
with
self
.
assertRaises
(
AttributeError
):
x
.
foobar
x
=
ast
.
Num
(
lineno
=
2
)
self
.
assertEqual
(
x
.
lineno
,
2
)
x
=
ast
.
Num
(
42
,
lineno
=
0
)
self
.
assertEqual
(
x
.
lineno
,
0
)
self
.
assertEqual
(
x
.
_fields
,
(
'n'
,))
self
.
assertEqual
(
x
.
n
,
42
)
self
.
assertRaises
(
TypeError
,
ast
.
Num
,
1
,
2
)
self
.
assertRaises
(
TypeError
,
ast
.
Num
,
1
,
2
,
lineno
=
0
)
def
test_module
(
self
):
body
=
[
ast
.
Num
(
42
)]
x
=
ast
.
Module
(
body
)
self
.
assertEqual
(
x
.
body
,
body
)
def
test_nodeclasses
(
self
):
# Zero arguments constructor explicitely allowed
x
=
ast
.
BinOp
()
self
.
assertEqual
(
x
.
_fields
,
(
'left'
,
'op'
,
'right'
))
# Random attribute allowed too
x
.
foobarbaz
=
5
self
.
assertEqual
(
x
.
foobarbaz
,
5
)
n1
=
ast
.
Num
(
1
)
n3
=
ast
.
Num
(
3
)
addop
=
ast
.
Add
()
x
=
ast
.
BinOp
(
n1
,
addop
,
n3
)
self
.
assertEqual
(
x
.
left
,
n1
)
self
.
assertEqual
(
x
.
op
,
addop
)
self
.
assertEqual
(
x
.
right
,
n3
)
x
=
ast
.
BinOp
(
1
,
2
,
3
)
self
.
assertEqual
(
x
.
left
,
1
)
self
.
assertEqual
(
x
.
op
,
2
)
self
.
assertEqual
(
x
.
right
,
3
)
x
=
ast
.
BinOp
(
1
,
2
,
3
,
lineno
=
0
)
self
.
assertEqual
(
x
.
left
,
1
)
self
.
assertEqual
(
x
.
op
,
2
)
self
.
assertEqual
(
x
.
right
,
3
)
self
.
assertEqual
(
x
.
lineno
,
0
)
# node raises exception when not given enough arguments
self
.
assertRaises
(
TypeError
,
ast
.
BinOp
,
1
,
2
)
# node raises exception when given too many arguments
self
.
assertRaises
(
TypeError
,
ast
.
BinOp
,
1
,
2
,
3
,
4
)
# node raises exception when not given enough arguments
self
.
assertRaises
(
TypeError
,
ast
.
BinOp
,
1
,
2
,
lineno
=
0
)
# node raises exception when given too many arguments
self
.
assertRaises
(
TypeError
,
ast
.
BinOp
,
1
,
2
,
3
,
4
,
lineno
=
0
)
# can set attributes through kwargs too
x
=
ast
.
BinOp
(
left
=
1
,
op
=
2
,
right
=
3
,
lineno
=
0
)
self
.
assertEqual
(
x
.
left
,
1
)
self
.
assertEqual
(
x
.
op
,
2
)
self
.
assertEqual
(
x
.
right
,
3
)
self
.
assertEqual
(
x
.
lineno
,
0
)
# Random kwargs also allowed
x
=
ast
.
BinOp
(
1
,
2
,
3
,
foobarbaz
=
42
)
self
.
assertEqual
(
x
.
foobarbaz
,
42
)
def
test_no_fields
(
self
):
# this used to fail because Sub._fields was None
x
=
ast
.
Sub
()
self
.
assertEqual
(
x
.
_fields
,
())
# Pyston change: skip this test for now
@
unittest
.
skip
(
"parse error"
)
def
test_pickling
(
self
):
import
pickle
mods
=
[
pickle
]
try
:
import
cPickle
mods
.
append
(
cPickle
)
except
ImportError
:
pass
protocols
=
[
0
,
1
,
2
]
for
mod
in
mods
:
for
protocol
in
protocols
:
for
ast
in
(
compile
(
i
,
"?"
,
"exec"
,
0x400
)
for
i
in
exec_tests
):
ast2
=
mod
.
loads
(
mod
.
dumps
(
ast
,
protocol
))
self
.
assertEqual
(
to_tuple
(
ast2
),
to_tuple
(
ast
))
def
test_invalid_identitifer
(
self
):
m
=
ast
.
Module
([
ast
.
Expr
(
ast
.
Name
(
u"x"
,
ast
.
Load
()))])
ast
.
fix_missing_locations
(
m
)
with
self
.
assertRaises
(
TypeError
)
as
cm
:
compile
(
m
,
"<test>"
,
"exec"
)
self
.
assertIn
(
"identifier must be of type str"
,
str
(
cm
.
exception
))
def
test_invalid_string
(
self
):
m
=
ast
.
Module
([
ast
.
Expr
(
ast
.
Str
(
43
))])
ast
.
fix_missing_locations
(
m
)
with
self
.
assertRaises
(
TypeError
)
as
cm
:
compile
(
m
,
"<test>"
,
"exec"
)
self
.
assertIn
(
"string must be of type str or uni"
,
str
(
cm
.
exception
))
class
ASTHelpers_Test
(
unittest
.
TestCase
):
def
test_parse
(
self
):
a
=
ast
.
parse
(
'foo(1 + 1)'
)
b
=
compile
(
'foo(1 + 1)'
,
'<unknown>'
,
'exec'
,
ast
.
PyCF_ONLY_AST
)
self
.
assertEqual
(
ast
.
dump
(
a
),
ast
.
dump
(
b
))
def
test_dump
(
self
):
node
=
ast
.
parse
(
'spam(eggs, "and cheese")'
)
self
.
assertEqual
(
ast
.
dump
(
node
),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
"args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
"keywords=[], starargs=None, kwargs=None))])"
)
self
.
assertEqual
(
ast
.
dump
(
node
,
annotate_fields
=
False
),
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
"Str('and cheese')], [], None, None))])"
)
self
.
assertEqual
(
ast
.
dump
(
node
,
include_attributes
=
True
),
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
"lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
"lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
"col_offset=11)], keywords=[], starargs=None, kwargs=None, "
"lineno=1, col_offset=0), lineno=1, col_offset=0)])"
)
def
test_copy_location
(
self
):
src
=
ast
.
parse
(
'1 + 1'
,
mode
=
'eval'
)
src
.
body
.
right
=
ast
.
copy_location
(
ast
.
Num
(
2
),
src
.
body
.
right
)
self
.
assertEqual
(
ast
.
dump
(
src
,
include_attributes
=
True
),
'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
'col_offset=0))'
)
def
test_fix_missing_locations
(
self
):
src
=
ast
.
parse
(
'write("spam")'
)
src
.
body
.
append
(
ast
.
Expr
(
ast
.
Call
(
ast
.
Name
(
'spam'
,
ast
.
Load
()),
[
ast
.
Str
(
'eggs'
)],
[],
None
,
None
)))
self
.
assertEqual
(
src
,
ast
.
fix_missing_locations
(
src
))
self
.
assertEqual
(
ast
.
dump
(
src
,
include_attributes
=
True
),
"Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
"lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, "
"col_offset=6)], keywords=[], starargs=None, kwargs=None, "
"lineno=1, col_offset=0), lineno=1, col_offset=0), "
"Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, "
"col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], "
"keywords=[], starargs=None, kwargs=None, lineno=1, "
"col_offset=0), lineno=1, col_offset=0)])"
)
def
test_increment_lineno
(
self
):
src
=
ast
.
parse
(
'1 + 1'
,
mode
=
'eval'
)
self
.
assertEqual
(
ast
.
increment_lineno
(
src
,
n
=
3
),
src
)
self
.
assertEqual
(
ast
.
dump
(
src
,
include_attributes
=
True
),
'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), '
'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
'col_offset=0))'
)
# issue10869: do not increment lineno of root twice
src
=
ast
.
parse
(
'1 + 1'
,
mode
=
'eval'
)
self
.
assertEqual
(
ast
.
increment_lineno
(
src
.
body
,
n
=
3
),
src
.
body
)
self
.
assertEqual
(
ast
.
dump
(
src
,
include_attributes
=
True
),
'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), '
'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
'col_offset=0))'
)
def
test_iter_fields
(
self
):
node
=
ast
.
parse
(
'foo()'
,
mode
=
'eval'
)
d
=
dict
(
ast
.
iter_fields
(
node
.
body
))
self
.
assertEqual
(
d
.
pop
(
'func'
).
id
,
'foo'
)
self
.
assertEqual
(
d
,
{
'keywords'
:
[],
'kwargs'
:
None
,
'args'
:
[],
'starargs'
:
None
})
def
test_iter_child_nodes
(
self
):
node
=
ast
.
parse
(
"spam(23, 42, eggs='leek')"
,
mode
=
'eval'
)
self
.
assertEqual
(
len
(
list
(
ast
.
iter_child_nodes
(
node
.
body
))),
4
)
iterator
=
ast
.
iter_child_nodes
(
node
.
body
)
self
.
assertEqual
(
next
(
iterator
).
id
,
'spam'
)
self
.
assertEqual
(
next
(
iterator
).
n
,
23
)
self
.
assertEqual
(
next
(
iterator
).
n
,
42
)
self
.
assertEqual
(
ast
.
dump
(
next
(
iterator
)),
"keyword(arg='eggs', value=Str(s='leek'))"
)
def
test_get_docstring
(
self
):
node
=
ast
.
parse
(
'def foo():
\
n
"""line one
\
n
line two"""'
)
self
.
assertEqual
(
ast
.
get_docstring
(
node
.
body
[
0
]),
'line one
\
n
line two'
)
def
test_literal_eval
(
self
):
self
.
assertEqual
(
ast
.
literal_eval
(
'[1, 2, 3]'
),
[
1
,
2
,
3
])
self
.
assertEqual
(
ast
.
literal_eval
(
'{"foo": 42}'
),
{
"foo"
:
42
})
self
.
assertEqual
(
ast
.
literal_eval
(
'(True, False, None)'
),
(
True
,
False
,
None
))
self
.
assertRaises
(
ValueError
,
ast
.
literal_eval
,
'foo()'
)
def
test_literal_eval_issue4907
(
self
):
self
.
assertEqual
(
ast
.
literal_eval
(
'2j'
),
2j
)
self
.
assertEqual
(
ast
.
literal_eval
(
'10 + 2j'
),
10
+
2j
)
self
.
assertEqual
(
ast
.
literal_eval
(
'1.5 - 2j'
),
1.5
-
2j
)
self
.
assertRaises
(
ValueError
,
ast
.
literal_eval
,
'2 + (3 + 4j)'
)
def
test_main
():
with
test_support
.
check_py3k_warnings
((
"backquote not supported"
,
SyntaxWarning
)):
test_support
.
run_unittest
(
AST_Tests
,
ASTHelpers_Test
)
def
main
():
if
__name__
!=
'__main__'
:
return
if
sys
.
argv
[
1
:]
==
[
'-g'
]:
for
statements
,
kind
in
((
exec_tests
,
"exec"
),
(
single_tests
,
"single"
),
(
eval_tests
,
"eval"
)):
print
kind
+
"_results = ["
for
s
in
statements
:
print
repr
(
to_tuple
(
compile
(
s
,
"?"
,
kind
,
0x400
)))
+
","
print
"]"
print
"main()"
raise
SystemExit
# pyston change: remove duration in test output
# test_main()
import
StringIO
,
re
orig_stdout
=
sys
.
stdout
out
=
StringIO
.
StringIO
()
sys
.
stdout
=
out
test_main
()
sys
.
stdout
=
orig_stdout
print
re
.
sub
(
" [.0-9]+s"
,
" TIME"
,
out
.
getvalue
())
#### EVERYTHING BELOW IS GENERATED #####
exec_results
=
[
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'None'
,
(
'Load'
,)))]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[]),
[(
'Pass'
,
(
1
,
9
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'Name'
,
(
1
,
6
),
'a'
,
(
'Param'
,))],
None
,
None
,
[]),
[(
'Pass'
,
(
1
,
10
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'Name'
,
(
1
,
6
),
'a'
,
(
'Param'
,))],
None
,
None
,
[(
'Num'
,
(
1
,
8
),
0
)]),
[(
'Pass'
,
(
1
,
12
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
'args'
,
None
,
[]),
[(
'Pass'
,
(
1
,
14
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
'kwargs'
,
[]),
[(
'Pass'
,
(
1
,
17
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[(
'Name'
,
(
1
,
6
),
'a'
,
(
'Param'
,)),
(
'Name'
,
(
1
,
9
),
'b'
,
(
'Param'
,)),
(
'Name'
,
(
1
,
14
),
'c'
,
(
'Param'
,)),
(
'Name'
,
(
1
,
22
),
'd'
,
(
'Param'
,)),
(
'Name'
,
(
1
,
28
),
'e'
,
(
'Param'
,))],
'args'
,
'kwargs'
,
[(
'Num'
,
(
1
,
11
),
1
),
(
'Name'
,
(
1
,
16
),
'None'
,
(
'Load'
,)),
(
'List'
,
(
1
,
24
),
[],
(
'Load'
,)),
(
'Dict'
,
(
1
,
30
),
[],
[])]),
[(
'Pass'
,
(
1
,
52
))],
[])]),
(
'Module'
,
[(
'ClassDef'
,
(
1
,
0
),
'C'
,
[],
[(
'Pass'
,
(
1
,
8
))],
[])]),
(
'Module'
,
[(
'ClassDef'
,
(
1
,
0
),
'C'
,
[(
'Name'
,
(
1
,
8
),
'object'
,
(
'Load'
,))],
[(
'Pass'
,
(
1
,
17
))],
[])]),
(
'Module'
,
[(
'FunctionDef'
,
(
1
,
0
),
'f'
,
(
'arguments'
,
[],
None
,
None
,
[]),
[(
'Return'
,
(
1
,
8
),
(
'Num'
,
(
1
,
15
),
1
))],
[])]),
(
'Module'
,
[(
'Delete'
,
(
1
,
0
),
[(
'Name'
,
(
1
,
4
),
'v'
,
(
'Del'
,))])]),
(
'Module'
,
[(
'Assign'
,
(
1
,
0
),
[(
'Name'
,
(
1
,
0
),
'v'
,
(
'Store'
,))],
(
'Num'
,
(
1
,
4
),
1
))]),
(
'Module'
,
[(
'AugAssign'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'v'
,
(
'Store'
,)),
(
'Add'
,),
(
'Num'
,
(
1
,
5
),
1
))]),
(
'Module'
,
[(
'Print'
,
(
1
,
0
),
(
'Name'
,
(
1
,
8
),
'f'
,
(
'Load'
,)),
[(
'Num'
,
(
1
,
11
),
1
)],
False
)]),
(
'Module'
,
[(
'For'
,
(
1
,
0
),
(
'Name'
,
(
1
,
4
),
'v'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
9
),
'v'
,
(
'Load'
,)),
[(
'Pass'
,
(
1
,
11
))],
[])]),
(
'Module'
,
[(
'While'
,
(
1
,
0
),
(
'Name'
,
(
1
,
6
),
'v'
,
(
'Load'
,)),
[(
'Pass'
,
(
1
,
8
))],
[])]),
(
'Module'
,
[(
'If'
,
(
1
,
0
),
(
'Name'
,
(
1
,
3
),
'v'
,
(
'Load'
,)),
[(
'Pass'
,
(
1
,
5
))],
[])]),
(
'Module'
,
[(
'Raise'
,
(
1
,
0
),
(
'Name'
,
(
1
,
6
),
'Exception'
,
(
'Load'
,)),
(
'Str'
,
(
1
,
17
),
'string'
),
None
)]),
(
'Module'
,
[(
'TryExcept'
,
(
1
,
0
),
[(
'Pass'
,
(
2
,
2
))],
[(
'ExceptHandler'
,
(
3
,
0
),
(
'Name'
,
(
3
,
7
),
'Exception'
,
(
'Load'
,)),
None
,
[(
'Pass'
,
(
4
,
2
))])],
[])]),
(
'Module'
,
[(
'TryFinally'
,
(
1
,
0
),
[(
'Pass'
,
(
2
,
2
))],
[(
'Pass'
,
(
4
,
2
))])]),
(
'Module'
,
[(
'Assert'
,
(
1
,
0
),
(
'Name'
,
(
1
,
7
),
'v'
,
(
'Load'
,)),
None
)]),
(
'Module'
,
[(
'Import'
,
(
1
,
0
),
[(
'alias'
,
'sys'
,
None
)])]),
(
'Module'
,
[(
'ImportFrom'
,
(
1
,
0
),
'sys'
,
[(
'alias'
,
'v'
,
None
)],
0
)]),
(
'Module'
,
[(
'Exec'
,
(
1
,
0
),
(
'Str'
,
(
1
,
5
),
'v'
),
None
,
None
)]),
(
'Module'
,
[(
'Global'
,
(
1
,
0
),
[
'v'
])]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'Num'
,
(
1
,
0
),
1
))]),
(
'Module'
,
[(
'Pass'
,
(
1
,
0
))]),
(
'Module'
,
[(
'Break'
,
(
1
,
0
))]),
(
'Module'
,
[(
'Continue'
,
(
1
,
0
))]),
(
'Module'
,
[(
'For'
,
(
1
,
0
),
(
'Tuple'
,
(
1
,
4
),
[(
'Name'
,
(
1
,
4
),
'a'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
6
),
'b'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
1
,
11
),
'c'
,
(
'Load'
,)),
[(
'Pass'
,
(
1
,
14
))],
[])]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'ListComp'
,
(
1
,
1
),
(
'Tuple'
,
(
1
,
2
),
[(
'Name'
,
(
1
,
2
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
4
),
'b'
,
(
'Load'
,))],
(
'Load'
,)),
[(
'comprehension'
,
(
'Tuple'
,
(
1
,
11
),
[(
'Name'
,
(
1
,
11
),
'a'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
13
),
'b'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
1
,
18
),
'c'
,
(
'Load'
,)),
[])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'GeneratorExp'
,
(
1
,
1
),
(
'Tuple'
,
(
1
,
2
),
[(
'Name'
,
(
1
,
2
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
4
),
'b'
,
(
'Load'
,))],
(
'Load'
,)),
[(
'comprehension'
,
(
'Tuple'
,
(
1
,
11
),
[(
'Name'
,
(
1
,
11
),
'a'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
13
),
'b'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
1
,
18
),
'c'
,
(
'Load'
,)),
[])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'GeneratorExp'
,
(
1
,
1
),
(
'Tuple'
,
(
1
,
2
),
[(
'Name'
,
(
1
,
2
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
4
),
'b'
,
(
'Load'
,))],
(
'Load'
,)),
[(
'comprehension'
,
(
'Tuple'
,
(
1
,
12
),
[(
'Name'
,
(
1
,
12
),
'a'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
14
),
'b'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
1
,
20
),
'c'
,
(
'Load'
,)),
[])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'GeneratorExp'
,
(
2
,
4
),
(
'Tuple'
,
(
3
,
4
),
[(
'Name'
,
(
3
,
4
),
'Aa'
,
(
'Load'
,)),
(
'Name'
,
(
5
,
7
),
'Bb'
,
(
'Load'
,))],
(
'Load'
,)),
[(
'comprehension'
,
(
'Tuple'
,
(
8
,
4
),
[(
'Name'
,
(
8
,
4
),
'Aa'
,
(
'Store'
,)),
(
'Name'
,
(
10
,
4
),
'Bb'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
10
,
10
),
'Cc'
,
(
'Load'
,)),
[])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'DictComp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
5
),
'b'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Name'
,
(
1
,
11
),
'w'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
16
),
'x'
,
(
'Load'
,)),
[]),
(
'comprehension'
,
(
'Name'
,
(
1
,
22
),
'm'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
27
),
'p'
,
(
'Load'
,)),
[(
'Name'
,
(
1
,
32
),
'g'
,
(
'Load'
,))])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'DictComp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
5
),
'b'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Tuple'
,
(
1
,
11
),
[(
'Name'
,
(
1
,
11
),
'v'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
13
),
'w'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
1
,
18
),
'x'
,
(
'Load'
,)),
[])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'SetComp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'r'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Name'
,
(
1
,
7
),
'l'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
12
),
'x'
,
(
'Load'
,)),
[(
'Name'
,
(
1
,
17
),
'g'
,
(
'Load'
,))])]))]),
(
'Module'
,
[(
'Expr'
,
(
1
,
0
),
(
'SetComp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'r'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Tuple'
,
(
1
,
7
),
[(
'Name'
,
(
1
,
7
),
'l'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
9
),
'm'
,
(
'Store'
,))],
(
'Store'
,)),
(
'Name'
,
(
1
,
14
),
'x'
,
(
'Load'
,)),
[])]))]),
]
single_results
=
[
(
'Interactive'
,
[(
'Expr'
,
(
1
,
0
),
(
'BinOp'
,
(
1
,
0
),
(
'Num'
,
(
1
,
0
),
1
),
(
'Add'
,),
(
'Num'
,
(
1
,
2
),
2
)))]),
]
eval_results
=
[
(
'Expression'
,
(
'Name'
,
(
1
,
0
),
'None'
,
(
'Load'
,))),
(
'Expression'
,
(
'BoolOp'
,
(
1
,
0
),
(
'And'
,),
[(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
6
),
'b'
,
(
'Load'
,))])),
(
'Expression'
,
(
'BinOp'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
(
'Add'
,),
(
'Name'
,
(
1
,
4
),
'b'
,
(
'Load'
,)))),
(
'Expression'
,
(
'UnaryOp'
,
(
1
,
0
),
(
'Not'
,),
(
'Name'
,
(
1
,
4
),
'v'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Lambda'
,
(
1
,
0
),
(
'arguments'
,
[],
None
,
None
,
[]),
(
'Name'
,
(
1
,
7
),
'None'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[(
'Num'
,
(
1
,
2
),
1
)],
[(
'Num'
,
(
1
,
4
),
2
)])),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[],
[])),
(
'Expression'
,
(
'Set'
,
(
1
,
0
),
[(
'Name'
,
(
1
,
1
),
'None'
,
(
'Load'
,))])),
(
'Expression'
,
(
'Dict'
,
(
1
,
0
),
[(
'Num'
,
(
2
,
6
),
1
)],
[(
'Num'
,
(
4
,
10
),
2
)])),
(
'Expression'
,
(
'ListComp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'a'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Name'
,
(
1
,
7
),
'b'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
12
),
'c'
,
(
'Load'
,)),
[(
'Name'
,
(
1
,
17
),
'd'
,
(
'Load'
,))])])),
(
'Expression'
,
(
'GeneratorExp'
,
(
1
,
1
),
(
'Name'
,
(
1
,
1
),
'a'
,
(
'Load'
,)),
[(
'comprehension'
,
(
'Name'
,
(
1
,
7
),
'b'
,
(
'Store'
,)),
(
'Name'
,
(
1
,
12
),
'c'
,
(
'Load'
,)),
[(
'Name'
,
(
1
,
17
),
'd'
,
(
'Load'
,))])])),
(
'Expression'
,
(
'Compare'
,
(
1
,
0
),
(
'Num'
,
(
1
,
0
),
1
),
[(
'Lt'
,),
(
'Lt'
,)],
[(
'Num'
,
(
1
,
4
),
2
),
(
'Num'
,
(
1
,
8
),
3
)])),
(
'Expression'
,
(
'Call'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'f'
,
(
'Load'
,)),
[(
'Num'
,
(
1
,
2
),
1
),
(
'Num'
,
(
1
,
4
),
2
)],
[(
'keyword'
,
'c'
,
(
'Num'
,
(
1
,
8
),
3
))],
(
'Name'
,
(
1
,
11
),
'd'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
15
),
'e'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Repr'
,
(
1
,
0
),
(
'Name'
,
(
1
,
1
),
'v'
,
(
'Load'
,)))),
(
'Expression'
,
(
'Num'
,
(
1
,
0
),
10L
)),
(
'Expression'
,
(
'Str'
,
(
1
,
0
),
'string'
)),
(
'Expression'
,
(
'Attribute'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
'b'
,
(
'Load'
,))),
(
'Expression'
,
(
'Subscript'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
(
'Slice'
,
(
'Name'
,
(
1
,
2
),
'b'
,
(
'Load'
,)),
(
'Name'
,
(
1
,
4
),
'c'
,
(
'Load'
,)),
None
),
(
'Load'
,))),
(
'Expression'
,
(
'Name'
,
(
1
,
0
),
'v'
,
(
'Load'
,))),
(
'Expression'
,
(
'List'
,
(
1
,
0
),
[(
'Num'
,
(
1
,
1
),
1
),
(
'Num'
,
(
1
,
3
),
2
),
(
'Num'
,
(
1
,
5
),
3
)],
(
'Load'
,))),
(
'Expression'
,
(
'List'
,
(
1
,
0
),
[],
(
'Load'
,))),
(
'Expression'
,
(
'Tuple'
,
(
1
,
0
),
[(
'Num'
,
(
1
,
0
),
1
),
(
'Num'
,
(
1
,
2
),
2
),
(
'Num'
,
(
1
,
4
),
3
)],
(
'Load'
,))),
(
'Expression'
,
(
'Tuple'
,
(
1
,
1
),
[(
'Num'
,
(
1
,
1
),
1
),
(
'Num'
,
(
1
,
3
),
2
),
(
'Num'
,
(
1
,
5
),
3
)],
(
'Load'
,))),
(
'Expression'
,
(
'Tuple'
,
(
1
,
0
),
[],
(
'Load'
,))),
(
'Expression'
,
(
'Call'
,
(
1
,
0
),
(
'Attribute'
,
(
1
,
0
),
(
'Attribute'
,
(
1
,
0
),
(
'Attribute'
,
(
1
,
0
),
(
'Name'
,
(
1
,
0
),
'a'
,
(
'Load'
,)),
'b'
,
(
'Load'
,)),
'c'
,
(
'Load'
,)),
'd'
,
(
'Load'
,)),
[(
'Subscript'
,
(
1
,
8
),
(
'Attribute'
,
(
1
,
8
),
(
'Name'
,
(
1
,
8
),
'a'
,
(
'Load'
,)),
'b'
,
(
'Load'
,)),
(
'Slice'
,
(
'Num'
,
(
1
,
12
),
1
),
(
'Num'
,
(
1
,
14
),
2
),
None
),
(
'Load'
,))],
[],
None
,
None
)),
]
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment