Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Kirill Smelkov
cpython
Commits
f2bf2b3e
Commit
f2bf2b3e
authored
Mar 17, 2010
by
Collin Winter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add some tests for ways users can change or shadow globals and builtins.
parent
0077b65a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
199 additions
and
1 deletion
+199
-1
Lib/test/support.py
Lib/test/support.py
+56
-1
Lib/test/test_dynamic.py
Lib/test/test_dynamic.py
+143
-0
No files found.
Lib/test/support.py
View file @
f2bf2b3e
...
...
@@ -30,7 +30,8 @@ __all__ = ["Error", "TestFailed", "ResourceDenied", "import_module",
"run_with_locale"
,
"set_memlimit"
,
"bigmemtest"
,
"bigaddrspacetest"
,
"BasicTestRunner"
,
"run_unittest"
,
"run_doctest"
,
"threading_setup"
,
"threading_cleanup"
,
"reap_children"
,
"cpython_only"
,
"check_impl_detail"
,
"get_attribute"
]
"reap_children"
,
"cpython_only"
,
"check_impl_detail"
,
"get_attribute"
,
"swap_item"
,
"swap_attr"
]
class
Error
(
Exception
):
"""Base class for regression test exceptions."""
...
...
@@ -1074,3 +1075,57 @@ def reap_children():
break
except
:
break
@
contextlib
.
contextmanager
def
swap_attr
(
obj
,
attr
,
new_val
):
"""Temporary swap out an attribute with a new object.
Usage:
with swap_attr(obj, "attr", 5):
...
This will set obj.attr to 5 for the duration of the with: block,
restoring the old value at the end of the block. If `attr` doesn't
exist on `obj`, it will be created and then deleted at the end of the
block.
"""
if
hasattr
(
obj
,
attr
):
real_val
=
getattr
(
obj
,
attr
)
setattr
(
obj
,
attr
,
new_val
)
try
:
yield
finally
:
setattr
(
obj
,
attr
,
real_val
)
else
:
setattr
(
obj
,
attr
,
new_val
)
try
:
yield
finally
:
delattr
(
obj
,
attr
)
@
contextlib
.
contextmanager
def
swap_item
(
obj
,
item
,
new_val
):
"""Temporary swap out an item with a new object.
Usage:
with swap_item(obj, "item", 5):
...
This will set obj["item"] to 5 for the duration of the with: block,
restoring the old value at the end of the block. If `item` doesn't
exist on `obj`, it will be created and then deleted at the end of the
block.
"""
if
item
in
obj
:
real_val
=
obj
[
item
]
obj
[
item
]
=
new_val
try
:
yield
finally
:
obj
[
item
]
=
real_val
else
:
obj
[
item
]
=
new_val
try
:
yield
finally
:
del
obj
[
item
]
Lib/test/test_dynamic.py
0 → 100644
View file @
f2bf2b3e
# Test the most dynamic corner cases of Python's runtime semantics.
import
builtins
import
contextlib
import
unittest
from
test.support
import
run_unittest
,
swap_item
,
swap_attr
class
RebindBuiltinsTests
(
unittest
.
TestCase
):
"""Test all the ways that we can change/shadow globals/builtins."""
def
configure_func
(
self
,
func
,
*
args
):
"""Perform TestCase-specific configuration on a function before testing.
By default, this does nothing. Example usage: spinning a function so
that a JIT will optimize it. Subclasses should override this as needed.
Args:
func: function to configure.
*args: any arguments that should be passed to func, if calling it.
Returns:
Nothing. Work will be performed on func in-place.
"""
pass
def
test_globals_shadow_builtins
(
self
):
# Modify globals() to shadow an entry in builtins.
def
foo
():
return
len
([
1
,
2
,
3
])
self
.
configure_func
(
foo
)
self
.
assertEqual
(
foo
(),
3
)
with
swap_item
(
globals
(),
"len"
,
lambda
x
:
7
):
self
.
assertEqual
(
foo
(),
7
)
def
test_modify_builtins
(
self
):
# Modify the builtins module directly.
def
foo
():
return
len
([
1
,
2
,
3
])
self
.
configure_func
(
foo
)
self
.
assertEqual
(
foo
(),
3
)
with
swap_attr
(
builtins
,
"len"
,
lambda
x
:
7
):
self
.
assertEqual
(
foo
(),
7
)
def
test_modify_builtins_while_generator_active
(
self
):
# Modify the builtins out from under a live generator.
def
foo
():
x
=
range
(
3
)
yield
len
(
x
)
yield
len
(
x
)
self
.
configure_func
(
foo
)
g
=
foo
()
self
.
assertEqual
(
next
(
g
),
3
)
with
swap_attr
(
builtins
,
"len"
,
lambda
x
:
7
):
self
.
assertEqual
(
next
(
g
),
7
)
def
test_modify_builtins_from_leaf_function
(
self
):
# Verify that modifications made by leaf functions percolate up the
# callstack.
with
swap_attr
(
builtins
,
"len"
,
len
):
def
bar
():
builtins
.
len
=
lambda
x
:
4
def
foo
(
modifier
):
l
=
[]
l
.
append
(
len
(
range
(
7
)))
modifier
()
l
.
append
(
len
(
range
(
7
)))
return
l
self
.
configure_func
(
foo
,
lambda
:
None
)
self
.
assertEqual
(
foo
(
bar
),
[
7
,
4
])
def
test_cannot_change_globals_or_builtins_with_eval
(
self
):
def
foo
():
return
len
([
1
,
2
,
3
])
self
.
configure_func
(
foo
)
# Note that this *doesn't* change the definition of len() seen by foo().
builtins_dict
=
{
"len"
:
lambda
x
:
7
}
globals_dict
=
{
"foo"
:
foo
,
"__builtins__"
:
builtins_dict
,
"len"
:
lambda
x
:
8
}
self
.
assertEqual
(
eval
(
"foo()"
,
globals_dict
),
3
)
self
.
assertEqual
(
eval
(
"foo()"
,
{
"foo"
:
foo
}),
3
)
def
test_cannot_change_globals_or_builtins_with_exec
(
self
):
def
foo
():
return
len
([
1
,
2
,
3
])
self
.
configure_func
(
foo
)
globals_dict
=
{
"foo"
:
foo
}
exec
(
"x = foo()"
,
globals_dict
)
self
.
assertEqual
(
globals_dict
[
"x"
],
3
)
# Note that this *doesn't* change the definition of len() seen by foo().
builtins_dict
=
{
"len"
:
lambda
x
:
7
}
globals_dict
=
{
"foo"
:
foo
,
"__builtins__"
:
builtins_dict
,
"len"
:
lambda
x
:
8
}
exec
(
"x = foo()"
,
globals_dict
)
self
.
assertEqual
(
globals_dict
[
"x"
],
3
)
def
test_cannot_replace_builtins_dict_while_active
(
self
):
def
foo
():
x
=
range
(
3
)
yield
len
(
x
)
yield
len
(
x
)
self
.
configure_func
(
foo
)
g
=
foo
()
self
.
assertEqual
(
next
(
g
),
3
)
with
swap_item
(
globals
(),
"__builtins__"
,
{
"len"
:
lambda
x
:
7
}):
self
.
assertEqual
(
next
(
g
),
3
)
def
test_cannot_replace_builtins_dict_between_calls
(
self
):
def
foo
():
return
len
([
1
,
2
,
3
])
self
.
configure_func
(
foo
)
self
.
assertEqual
(
foo
(),
3
)
with
swap_item
(
globals
(),
"__builtins__"
,
{
"len"
:
lambda
x
:
7
}):
self
.
assertEqual
(
foo
(),
3
)
def
test_eval_gives_lambda_custom_globals
(
self
):
globals_dict
=
{
"len"
:
lambda
x
:
7
}
foo
=
eval
(
"lambda: len([])"
,
globals_dict
)
self
.
configure_func
(
foo
)
self
.
assertEqual
(
foo
(),
7
)
def
test_main
():
run_unittest
(
RebindBuiltinsTests
)
if
__name__
==
"__main__"
:
test_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