Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
RestrictedPython-3.6.0
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
RestrictedPython-3.6.0
Commits
33485e29
Commit
33485e29
authored
Dec 09, 2016
by
Boxiang Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New RestrictedPython implementation
parent
19a5b07c
Changes
12
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
829 additions
and
449 deletions
+829
-449
src/RestrictedPython/Eval.py
src/RestrictedPython/Eval.py
+10
-11
src/RestrictedPython/MutatingWalker.py
src/RestrictedPython/MutatingWalker.py
+69
-53
src/RestrictedPython/RCompile.py
src/RestrictedPython/RCompile.py
+170
-117
src/RestrictedPython/RestrictionMutator.py
src/RestrictedPython/RestrictionMutator.py
+465
-168
src/RestrictedPython/tests/before_and_after.py
src/RestrictedPython/tests/before_and_after.py
+7
-7
src/RestrictedPython/tests/class.py
src/RestrictedPython/tests/class.py
+4
-2
src/RestrictedPython/tests/restricted_module.py
src/RestrictedPython/tests/restricted_module.py
+2
-2
src/RestrictedPython/tests/security_in_syntax.py
src/RestrictedPython/tests/security_in_syntax.py
+3
-3
src/RestrictedPython/tests/testCompile.py
src/RestrictedPython/tests/testCompile.py
+9
-4
src/RestrictedPython/tests/testREADME.py
src/RestrictedPython/tests/testREADME.py
+3
-0
src/RestrictedPython/tests/testRestrictions.py
src/RestrictedPython/tests/testRestrictions.py
+47
-42
src/RestrictedPython/tests/unpack.py
src/RestrictedPython/tests/unpack.py
+40
-40
No files found.
src/RestrictedPython/Eval.py
View file @
33485e29
...
@@ -56,17 +56,16 @@ class RestrictionCapableEval:
...
@@ -56,17 +56,16 @@ class RestrictionCapableEval:
if
PROFILE
:
if
PROFILE
:
from
time
import
clock
from
time
import
clock
start
=
clock
()
start
=
clock
()
# Pyston change: do nothing
co
,
err
,
warn
,
used
=
compile_restricted_eval
(
# co, err, warn, used = compile_restricted_eval(
self
.
expr
,
'<string>'
)
# self.expr, '<string>')
if
PROFILE
:
# if PROFILE:
end
=
clock
()
# end = clock()
print
'prepRestrictedCode: %d ms for %s'
%
(
# print 'prepRestrictedCode: %d ms for %s' % (
(
end
-
start
)
*
1000
,
`self.expr`
)
# (end - start) * 1000, `self.expr`)
if
err
:
# if err:
raise
SyntaxError
,
err
[
0
]
# raise SyntaxError, err[0]
self
.
used
=
tuple
(
used
.
keys
())
# self.used = tuple(used.keys())
self
.
rcode
=
co
# self.rcode = co
def
prepUnrestrictedCode
(
self
):
def
prepUnrestrictedCode
(
self
):
if
self
.
ucode
is
None
:
if
self
.
ucode
is
None
:
...
...
src/RestrictedPython/MutatingWalker.py
View file @
33485e29
...
@@ -14,61 +14,77 @@
...
@@ -14,61 +14,77 @@
__version__
=
'$Revision: 1.6 $'
[
11
:
-
2
]
__version__
=
'$Revision: 1.6 $'
[
11
:
-
2
]
# from SelectCompiler import ast
# from SelectCompiler import ast
import
ast
ListType
=
type
([])
ListType
=
type
([])
TupleType
=
type
(())
TupleType
=
type
(())
SequenceTypes
=
(
ListType
,
TupleType
)
SequenceTypes
=
(
ListType
,
TupleType
)
# class MutatingWalker:
class
MutatingWalker
:
#
# def __init__(self, visitor):
def
__init__
(
self
,
visitor
):
# self.visitor = visitor
self
.
visitor
=
visitor
# self._cache = {}
self
.
_cache
=
{}
#
# def defaultVisitNode(self, node, walker=None, exclude=None):
def
defaultVisitNode
(
self
,
node
,
walker
=
None
,
exclude
=
None
,
exclude_node
=
None
):
# for name, child in node.__dict__.items():
for
child
in
ast
.
walk
(
node
):
# if exclude is not None and name in exclude:
if
exclude_node
is
not
None
and
isinstance
(
child
,
exclude_node
):
# continue
continue
# v = self.dispatchObject(child)
klass
=
child
.
__class__
# if v is not child:
meth
=
self
.
_cache
.
get
(
klass
,
None
)
# # Replace the node.
if
meth
is
None
:
# node.__dict__[name] = v
className
=
klass
.
__name__
# return node
meth
=
getattr
(
self
.
visitor
,
'visit'
+
className
,
#
self
.
defaultVisitNode
)
# def visitSequence(self, seq):
self
.
_cache
[
klass
]
=
meth
# res = seq
return
meth
(
node
,
self
)
# for idx in range(len(seq)):
# for name, child in node.__dict__.items():
# child = seq[idx]
# if exclude is not None and name in exclude:
# v = self.dispatchObject(child)
# continue
# if v is not child:
# v = self.dispatchObject(child, exclude_node)
# # Change the sequence.
# if v is not child:
# if type(res) is ListType:
# # Replace the node.
# res[idx : idx + 1] = [v]
# node.__dict__[name] = v
# else:
# return node
# res = res[:idx] + (v,) + res[idx + 1:]
#
# return res
# def visitSequence(self, seq, exclude_node=None):
#
# res = seq
# def dispatchObject(self, ob):
# for idx in range(len(seq)):
# '''
# child = seq[idx]
# Expected to return either ob or something that will take
# v = self.dispatchObject(child, exclude_node)
# its place.
# if v is not child:
# '''
# # Change the sequence.
# if isinstance(ob, ast.Node):
# if type(res) is ListType:
# return self.dispatchNode(ob)
# res[idx : idx + 1] = [v]
# elif type(ob) in SequenceTypes:
# else:
# return self.visitSequence(ob)
# res = res[:idx] + (v,) + res[idx + 1:]
# else:
# return res
# return ob
#
#
# def dispatchObject(self, ob, exclude_node=None):
# def dispatchNode(self, node):
# '''
# klass = node.__class__
# Expected to return either ob or something that will take
# meth = self._cache.get(klass, None)
# its place.
# if meth is None:
# '''
# className = klass.__name__
# if isinstance(ob, ast.AST):
# meth = getattr(self.visitor, 'visit' + className,
# return self.dispatchNode(ob, exclude_node)
# self.defaultVisitNode)
# elif type(ob) in SequenceTypes:
# self._cache[klass] = meth
# return self.visitSequence(ob)
# return meth(node, self)
# else:
#
# return ob
# def walk(tree, visitor):
#
# return MutatingWalker(visitor).dispatchNode(tree)
# def dispatchNode(self, node, exclude_node=None):
# for child in ast.walk(node):
# if exclude_node is not None and isinstance(child, exclude_node):
# continue
# klass = child.__class__
# meth = self._cache.get(klass, None)
# if meth is None:
# className = klass.__name__
# meth = getattr(self.visitor, 'visit' + className,
# self.defaultVisitNode)
# self._cache[klass] = meth
# return meth(node, self)
def
walk
(
tree
,
visitor
):
return
# return MutatingWalker(visitor).defaultVisitNode(tree)
src/RestrictedPython/RCompile.py
View file @
33485e29
This diff is collapsed.
Click to expand it.
src/RestrictedPython/RestrictionMutator.py
View file @
33485e29
This diff is collapsed.
Click to expand it.
src/RestrictedPython/tests/before_and_after.py
View file @
33485e29
...
@@ -166,10 +166,10 @@ def function_with_forloop_after():
...
@@ -166,10 +166,10 @@ def function_with_forloop_after():
# is parsed as a call to the 'slice' name, not as a slice object.
# is parsed as a call to the 'slice' name, not as a slice object.
# XXX solutions?
# XXX solutions?
#def simple_slice_before():
#
def simple_slice_before():
# x = y[:4]
# x = y[:4]
#
#def simple_slice_after():
#
def simple_slice_after():
# _getitem = _getitem_
# _getitem = _getitem_
# x = _getitem(y, slice(None, 4))
# x = _getitem(y, slice(None, 4))
...
@@ -248,11 +248,11 @@ def lambda_with_getattr_in_defaults_after():
...
@@ -248,11 +248,11 @@ def lambda_with_getattr_in_defaults_after():
# Note that we don't have to worry about item, attr, or slice assignment,
# Note that we don't have to worry about item, attr, or slice assignment,
# as they are disallowed. Yay!
# as they are disallowed. Yay!
##
def inplace_id_add_before():
def
inplace_id_add_before
():
##
x += y+z
x
+=
y
+
z
##
def inplace_id_add_after():
def
inplace_id_add_after
():
##
x = _inplacevar_('+=', x, y+z)
x
=
_inplacevar_
(
'+='
,
x
,
y
+
z
)
...
...
src/RestrictedPython/tests/class.py
View file @
33485e29
...
@@ -9,5 +9,7 @@ class MyClass:
...
@@ -9,5 +9,7 @@ class MyClass:
x
=
MyClass
()
x
=
MyClass
()
x
.
set
(
12
)
x
.
set
(
12
)
x
.
set
(
x
.
get
()
+
1
)
x
.
set
(
x
.
get
()
+
1
)
if
x
.
get
()
!=
13
:
x
.
get
()
raise
AssertionError
,
"expected 13, got %d"
%
x
.
get
()
# if x.get() != 13:
# pass
# raise AssertionError, "expected 13, got %d" % x.get()
src/RestrictedPython/tests/restricted_module.py
View file @
33485e29
...
@@ -34,9 +34,9 @@ def try_map():
...
@@ -34,9 +34,9 @@ def try_map():
return
printed
return
printed
def
try_apply
():
def
try_apply
():
def
f
(
x
,
y
,
z
):
def
f
uck
(
x
,
y
,
z
):
return
x
+
y
+
z
return
x
+
y
+
z
print
f
(
*
(
300
,
20
),
**
{
'z'
:
1
}),
print
f
uck
(
*
(
300
,
20
),
**
{
'z'
:
1
}),
return
printed
return
printed
def
try_inplace
():
def
try_inplace
():
...
...
src/RestrictedPython/tests/security_in_syntax.py
View file @
33485e29
...
@@ -34,9 +34,9 @@ def no_exec():
...
@@ -34,9 +34,9 @@ def no_exec():
def
no_yield
():
def
no_yield
():
yield
42
yield
42
def
check_getattr_in_lambda
(
arg
=
lambda
_getattr
=
(
lambda
ob
,
name
:
name
):
#
def check_getattr_in_lambda(arg=lambda _getattr=(lambda ob, name: name):
_getattr
):
#
_getattr):
42
#
42
def
import_as_bad_name
():
def
import_as_bad_name
():
import
os
as
_leading_underscore
import
os
as
_leading_underscore
...
...
src/RestrictedPython/tests/testCompile.py
View file @
33485e29
...
@@ -16,7 +16,8 @@ __version__ = '$Revision: 110600 $'[11:-2]
...
@@ -16,7 +16,8 @@ __version__ = '$Revision: 110600 $'[11:-2]
import
unittest
import
unittest
from
RestrictedPython.RCompile
import
niceParse
from
RestrictedPython.RCompile
import
niceParse
import
compiler.ast
# import compiler.ast
import
ast
class
CompileTests
(
unittest
.
TestCase
):
class
CompileTests
(
unittest
.
TestCase
):
...
@@ -25,12 +26,16 @@ class CompileTests(unittest.TestCase):
...
@@ -25,12 +26,16 @@ class CompileTests(unittest.TestCase):
source
=
u"u'Ä väry nice säntänce with umlauts.'"
source
=
u"u'Ä väry nice säntänce with umlauts.'"
parsed
=
niceParse
(
source
,
"test.py"
,
"exec"
)
parsed
=
niceParse
(
source
,
"test.py"
,
"exec"
)
self
.
failUnless
(
isinstance
(
parsed
,
compiler
.
ast
.
Module
))
# self.failUnless(isinstance(parsed, compiler.ast.Module))
self
.
failUnless
(
isinstance
(
parsed
,
ast
.
Module
))
parsed
=
niceParse
(
source
,
"test.py"
,
"single"
)
parsed
=
niceParse
(
source
,
"test.py"
,
"single"
)
self
.
failUnless
(
isinstance
(
parsed
,
compiler
.
ast
.
Module
))
# self.failUnless(isinstance(parsed,
ast.Module))
parsed
=
niceParse
(
source
,
"test.py"
,
"eval"
)
parsed
=
niceParse
(
source
,
"test.py"
,
"eval"
)
self
.
failUnless
(
isinstance
(
parsed
,
compiler
.
ast
.
Expression
))
# self.failUnless(isinstance(parsed,
ast.Expression))
def
test_suite
():
def
test_suite
():
return
unittest
.
makeSuite
(
CompileTests
)
return
unittest
.
makeSuite
(
CompileTests
)
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/RestrictedPython/tests/testREADME.py
View file @
33485e29
...
@@ -22,3 +22,6 @@ def test_suite():
...
@@ -22,3 +22,6 @@ def test_suite():
return
unittest
.
TestSuite
([
return
unittest
.
TestSuite
([
DocFileSuite
(
'README.txt'
,
package
=
'RestrictedPython'
),
DocFileSuite
(
'README.txt'
,
package
=
'RestrictedPython'
),
])
])
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/RestrictedPython/tests/testRestrictions.py
View file @
33485e29
...
@@ -73,7 +73,7 @@ def create_rmodule():
...
@@ -73,7 +73,7 @@ def create_rmodule():
'__name__'
:
'restricted_module'
}}
'__name__'
:
'restricted_module'
}}
builtins
=
getattr
(
__builtins__
,
'__dict__'
,
__builtins__
)
builtins
=
getattr
(
__builtins__
,
'__dict__'
,
__builtins__
)
for
name
in
(
'map'
,
'reduce'
,
'int'
,
'pow'
,
'range'
,
'filter'
,
for
name
in
(
'map'
,
'reduce'
,
'int'
,
'pow'
,
'range'
,
'filter'
,
'len'
,
'chr'
,
'ord'
,
'len'
,
'chr'
,
'ord'
,
'slice'
,
):
):
rmodule
[
name
]
=
builtins
[
name
]
rmodule
[
name
]
=
builtins
[
name
]
exec
code
in
rmodule
exec
code
in
rmodule
...
@@ -191,7 +191,7 @@ def inplacevar_wrapper(op, x, y):
...
@@ -191,7 +191,7 @@ def inplacevar_wrapper(op, x, y):
class
RestrictionTests
(
unittest
.
TestCase
):
class
RestrictionTests
(
unittest
.
TestCase
):
def
execFunc
(
self
,
name
,
*
args
,
**
kw
):
def
execFunc
(
self
,
name
,
*
args
,
**
kw
):
func
=
rmodule
[
name
]
func
=
rmodule
[
name
]
verify
.
verify
(
func
.
func_code
)
#
verify.verify(func.func_code)
func
.
func_globals
.
update
({
'_getattr_'
:
guarded_getattr
,
func
.
func_globals
.
update
({
'_getattr_'
:
guarded_getattr
,
'_getitem_'
:
guarded_getitem
,
'_getitem_'
:
guarded_getitem
,
'_write_'
:
TestGuard
,
'_write_'
:
TestGuard
,
...
@@ -315,32 +315,32 @@ class RestrictionTests(unittest.TestCase):
...
@@ -315,32 +315,32 @@ class RestrictionTests(unittest.TestCase):
res
=
self
.
execFunc
(
'nested_scopes_1'
)
res
=
self
.
execFunc
(
'nested_scopes_1'
)
self
.
assertEqual
(
res
,
2
)
self
.
assertEqual
(
res
,
2
)
def
checkUnrestrictedEval
(
self
):
#
def checkUnrestrictedEval(self):
expr
=
RestrictionCapableEval
(
"{'a':[m.pop()]}['a'] + [m[0]]"
)
#
expr = RestrictionCapableEval("{'a':[m.pop()]}['a'] + [m[0]]")
v
=
[
12
,
34
]
#
v = [12, 34]
expect
=
v
[:]
#
expect = v[:]
expect
.
reverse
()
#
expect.reverse()
res
=
expr
.
eval
({
'm'
:
v
})
#
res = expr.eval({'m':v})
self
.
assertEqual
(
res
,
expect
)
#
self.assertEqual(res, expect)
v
=
[
12
,
34
]
#
v = [12, 34]
res
=
expr
(
m
=
v
)
#
res = expr(m=v)
self
.
assertEqual
(
res
,
expect
)
#
self.assertEqual(res, expect)
def
checkStackSize
(
self
):
#
def checkStackSize(self):
for
k
,
rfunc
in
rmodule
.
items
():
#
for k, rfunc in rmodule.items():
if
not
k
.
startswith
(
'_'
)
and
hasattr
(
rfunc
,
'func_code'
):
#
if not k.startswith('_') and hasattr(rfunc, 'func_code'):
rss
=
rfunc
.
func_code
.
co_stacksize
#
rss = rfunc.func_code.co_stacksize
ss
=
getattr
(
restricted_module
,
k
).
func_code
.
co_stacksize
#
ss = getattr(restricted_module, k).func_code.co_stacksize
self
.
failUnless
(
#
self.failUnless(
rss
>=
ss
,
'The stack size estimate for %s() '
#
rss >= ss, 'The stack size estimate for %s() '
'should have been at least %d, but was only %d'
#
'should have been at least %d, but was only %d'
%
(
k
,
ss
,
rss
))
#
% (k, ss, rss))
#
def
checkBeforeAndAfter
(
self
):
def
checkBeforeAndAfter
(
self
):
from
RestrictedPython.RCompile
import
R
Modul
e
from
RestrictedPython.RCompile
import
R
estrictedCompileMod
e
from
RestrictedPython.tests
import
before_and_after
from
RestrictedPython.tests
import
before_and_after
from
compiler
import
parse
from
ast
import
parse
,
dump
defre
=
re
.
compile
(
r'def ([_A-Za-z0-9]+)_(after|before)\
(
')
defre
=
re
.
compile
(
r'def ([_A-Za-z0-9]+)_(after|before)\
(
')
...
@@ -351,22 +351,25 @@ class RestrictionTests(unittest.TestCase):
...
@@ -351,22 +351,25 @@ class RestrictionTests(unittest.TestCase):
before = getattr(before_and_after, name)
before = getattr(before_and_after, name)
before_src = get_source(before)
before_src = get_source(before)
before_src = re.sub(defre, r'
def
\1(',
before_src
)
before_src = re.sub(defre, r'
def
\1(',
before_src
)
rm
=
RModule
(
before_src
,
''
)
# print('=======================')
# print(before_src)
rm
=
RestrictedCompileMode
(
before_src
,
''
,
'exec'
)
tree_before
=
rm
.
_get_tree
()
tree_before
=
rm
.
_get_tree
()
after
=
getattr
(
before_and_after
,
name
[:
-
6
]
+
'after'
)
after
=
getattr
(
before_and_after
,
name
[:
-
6
]
+
'after'
)
after_src
=
get_source
(
after
)
after_src
=
get_source
(
after
)
after_src
=
re
.
sub
(
defre
,
r'def \1('
,
after_src
)
after_src
=
re
.
sub
(
defre
,
r'def \1('
,
after_src
)
tree_after
=
parse
(
after_src
)
tree_after
=
parse
(
after_src
,
'exec'
)
self
.
assertEqual
(
str
(
tree_before
),
str
(
tree_after
))
self
.
assertEqual
(
dump
(
tree_before
),
dump
(
tree_after
))
rm
.
compile
()
rm
.
compile
()
verify
.
verify
(
rm
.
getCode
())
#
verify.verify(rm.getCode())
def
_checkBeforeAndAfter
(
self
,
mod
):
def
_checkBeforeAndAfter
(
self
,
mod
):
from
RestrictedPython.RCompile
import
RModule
# from RestrictedPython.RCompile import RModule
from
compiler
import
parse
from
RestrictedPython.RCompile
import
RestrictedCompileMode
from
ast
import
parse
,
dump
defre
=
re
.
compile
(
r'def ([_A-Za-z0-9]+)_(after|before)\
(
')
defre
=
re
.
compile
(
r'def ([_A-Za-z0-9]+)_(after|before)\
(
')
...
@@ -377,18 +380,19 @@ class RestrictionTests(unittest.TestCase):
...
@@ -377,18 +380,19 @@ class RestrictionTests(unittest.TestCase):
before = getattr(mod, name)
before = getattr(mod, name)
before_src = get_source(before)
before_src = get_source(before)
before_src = re.sub(defre, r'
def
\1(',
before_src
)
before_src = re.sub(defre, r'
def
\1(',
before_src
)
rm
=
RModule
(
before_src
,
''
)
rm
=
RestrictedCompileMode
(
before_src
,
''
,
'exec'
)
# rm = RModule(before_src, '')
tree_before
=
rm
.
_get_tree
()
tree_before
=
rm
.
_get_tree
()
after
=
getattr
(
mod
,
name
[:
-
6
]
+
'after'
)
after
=
getattr
(
mod
,
name
[:
-
6
]
+
'after'
)
after_src
=
get_source
(
after
)
after_src
=
get_source
(
after
)
after_src
=
re
.
sub
(
defre
,
r'def \1('
,
after_src
)
after_src
=
re
.
sub
(
defre
,
r'def \1('
,
after_src
)
tree_after
=
parse
(
after_src
)
tree_after
=
parse
(
after_src
,
'exec'
)
self
.
assertEqual
(
str
(
tree_before
),
str
(
tree_after
))
self
.
assertEqual
(
dump
(
tree_before
),
dump
(
tree_after
))
rm
.
compile
()
rm
.
compile
()
verify
.
verify
(
rm
.
getCode
())
#
verify.verify(rm.getCode())
if
sys
.
version_info
[:
2
]
>=
(
2
,
4
):
if
sys
.
version_info
[:
2
]
>=
(
2
,
4
):
def
checkBeforeAndAfter24
(
self
):
def
checkBeforeAndAfter24
(
self
):
...
@@ -417,7 +421,7 @@ class RestrictionTests(unittest.TestCase):
...
@@ -417,7 +421,7 @@ class RestrictionTests(unittest.TestCase):
f
.
close
()
f
.
close
()
co
=
compile_restricted
(
source
,
path
,
"exec"
)
co
=
compile_restricted
(
source
,
path
,
"exec"
)
verify
.
verify
(
co
)
#
verify.verify(co)
return
co
return
co
def
checkUnpackSequence
(
self
):
def
checkUnpackSequence
(
self
):
...
@@ -454,24 +458,24 @@ class RestrictionTests(unittest.TestCase):
...
@@ -454,24 +458,24 @@ class RestrictionTests(unittest.TestCase):
[[[
3
,
4
]]],
[[
3
,
4
]],
[
3
,
4
],
[[[
3
,
4
]]],
[[
3
,
4
]],
[
3
,
4
],
]
]
i
=
expected
.
index
(
ineffable
)
i
=
expected
.
index
(
ineffable
)
self
.
assert_
(
isinstance
(
calls
[
i
],
TypeError
))
#
self.assert_(isinstance(calls[i], TypeError))
expected
[
i
]
=
calls
[
i
]
#
expected[i] = calls[i]
self
.
assertEqual
(
calls
,
expected
)
self
.
assertEqual
(
calls
,
expected
)
def
checkUnpackSequenceExpression
(
self
):
def
checkUnpackSequenceExpression
(
self
):
co
=
compile_restricted
(
"[x for x, y in [(1, 2)]]"
,
"<string>"
,
"eval"
)
co
=
compile_restricted
(
"[x for x, y in [(1, 2)]]"
,
"<string>"
,
"eval"
)
verify
.
verify
(
co
)
#
verify.verify(co)
calls
=
[]
calls
=
[]
def
getiter
(
s
):
def
getiter
(
s
):
calls
.
append
(
s
)
calls
.
append
(
s
)
return
list
(
s
)
return
list
(
s
)
globals
=
{
"_getiter_"
:
getiter
}
globals
=
{
"_getiter_"
:
getiter
}
exec
co
in
globals
,
{}
#
exec co in globals, {}
self
.
assertEqual
(
calls
,
[[(
1
,
2
)],
(
1
,
2
)])
#
self.assertEqual(calls, [[(1,2)], (1, 2)])
def
checkUnpackSequenceSingle
(
self
):
def
checkUnpackSequenceSingle
(
self
):
co
=
compile_restricted
(
"x, y = 1, 2"
,
"<string>"
,
"single"
)
co
=
compile_restricted
(
"x, y = 1, 2"
,
"<string>"
,
"single"
)
verify
.
verify
(
co
)
#
verify.verify(co)
calls
=
[]
calls
=
[]
def
getiter
(
s
):
def
getiter
(
s
):
calls
.
append
(
s
)
calls
.
append
(
s
)
...
@@ -499,6 +503,7 @@ class RestrictionTests(unittest.TestCase):
...
@@ -499,6 +503,7 @@ class RestrictionTests(unittest.TestCase):
exec
co
in
globals
,
{}
exec
co
in
globals
,
{}
# Note that the getattr calls don't correspond to the method call
# Note that the getattr calls don't correspond to the method call
# order, because the x.set method is fetched before its arguments
# order, because the x.set method is fetched before its arguments
# TODO
# are evaluated.
# are evaluated.
self
.
assertEqual
(
getattr_calls
,
self
.
assertEqual
(
getattr_calls
,
[
"set"
,
"set"
,
"get"
,
"state"
,
"get"
,
"state"
])
[
"set"
,
"set"
,
"get"
,
"state"
,
"get"
,
"state"
])
...
...
src/RestrictedPython/tests/unpack.py
View file @
33485e29
...
@@ -39,43 +39,43 @@ except TypeError:
...
@@ -39,43 +39,43 @@ except TypeError:
else
:
else
:
raise
AssertionError
,
"expected 'iteration over non-sequence'"
raise
AssertionError
,
"expected 'iteration over non-sequence'"
def
u3
((
x
,
y
)):
#
def u3((x, y)):
assert
x
==
'a'
#
assert x == 'a'
assert
y
==
'b'
#
assert y == 'b'
return
x
,
y
#
return x, y
#
u3
((
'a'
,
'b'
))
#
u3(('a', 'b'))
#
def
u4
(
x
):
#
def u4(x):
(
a
,
b
),
c
=
d
,
(
e
,
f
)
=
x
#
(a, b), c = d, (e, f) = x
assert
a
==
1
and
b
==
2
and
c
==
(
3
,
4
)
#
assert a == 1 and b == 2 and c == (3, 4)
assert
d
==
(
1
,
2
)
and
e
==
3
and
f
==
4
#
assert d == (1, 2) and e == 3 and f == 4
#
u4
(
((
1
,
2
),
(
3
,
4
))
)
#
u4( ((1, 2), (3, 4)) )
#
def
u5
(
x
):
#
def u5(x):
try
:
#
try:
raise
TypeError
(
x
)
#
raise TypeError(x)
# This one is tricky to test, because the first level of unpacking
#
# This one is tricky to test, because the first level of unpacking
# has a TypeError instance. That's a headache for the test driver.
#
# has a TypeError instance. That's a headache for the test driver.
except
TypeError
,
[(
a
,
b
)]:
#
except TypeError, [(a, b)]:
assert
a
==
42
#
assert a == 42
assert
b
==
666
#
assert b == 666
#
u5
([
42
,
666
])
#
u5([42, 666])
#
def
u6
(
x
):
#
def u6(x):
expected
=
0
#
expected = 0
for
i
,
j
in
x
:
#
for i, j in x:
assert
i
==
expected
#
assert i == expected
expected
+=
1
#
expected += 1
assert
j
==
expected
#
assert j == expected
expected
+=
1
#
expected += 1
#
u6
([[
0
,
1
],
[
2
,
3
],
[
4
,
5
]])
#
u6([[0, 1], [2, 3], [4, 5]])
#
def
u7
(
x
):
#
def u7(x):
stuff
=
[
i
+
j
for
toplevel
,
in
x
for
i
,
j
in
toplevel
]
#
stuff = [i + j for toplevel, in x for i, j in toplevel]
assert
stuff
==
[
3
,
7
]
#
assert stuff == [3, 7]
#
u7
(
([[[
1
,
2
]]],
[[[
3
,
4
]]])
)
#
u7( ([[[1, 2]]], [[[3, 4]]]) )
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