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
60d1456e
Commit
60d1456e
authored
Feb 05, 2008
by
Georg Brandl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge r60522 from trunk.
parent
479a7e7a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
232 additions
and
368 deletions
+232
-368
Lib/test/test_funcattrs.py
Lib/test/test_funcattrs.py
+232
-368
No files found.
Lib/test/test_funcattrs.py
View file @
60d1456e
from
test
.test_support
import
verbose
,
TestFailed
,
verify
from
test
import
test_support
import
types
import
types
import
unittest
class
F
:
def
a
(
self
):
class
FuncAttrsTest
(
unittest
.
TestCase
):
pass
def
setUp
(
self
):
class
F
:
def
b
():
def
a
(
self
):
'my docstring'
pass
pass
def
b
():
return
3
# __module__ is a special attribute
self
.
fi
=
F
()
verify
(
b
.
__module__
==
__name__
)
self
.
F
=
F
verify
(
verify
.
__module__
==
"test.test_support"
)
self
.
b
=
b
# setting attributes on functions
def
cannot_set_attr
(
self
,
obj
,
name
,
value
,
exceptions
):
try
:
try
:
b
.
publish
setattr
(
obj
,
name
,
value
)
except
AttributeError
:
pass
except
exceptions
:
else
:
raise
TestFailed
(
'expected AttributeError'
)
pass
else
:
if
b
.
__dict__
!=
{}:
self
.
fail
(
"shouldn't be able to set %s to %r"
%
(
name
,
value
))
raise
TestFailed
(
'expected unassigned func.__dict__ to be {}'
)
try
:
delattr
(
obj
,
name
)
b
.
publish
=
1
except
exceptions
:
if
b
.
publish
!=
1
:
pass
raise
TestFailed
(
'function attribute not set to expected value'
)
else
:
self
.
fail
(
"shouldn't be able to del %s"
%
name
)
docstring
=
'its docstring'
b
.
__doc__
=
docstring
if
b
.
__doc__
!=
docstring
:
class
FunctionPropertiesTest
(
FuncAttrsTest
):
raise
TestFailed
(
'problem with setting __doc__ attribute'
)
# Include the external setUp method that is common to all tests
def
test_module
(
self
):
if
'publish'
not
in
dir
(
b
):
self
.
assertEqual
(
self
.
b
.
__module__
,
__name__
)
raise
TestFailed
(
'attribute not in dir()'
)
def
test_dir_includes_correct_attrs
(
self
):
try
:
self
.
b
.
known_attr
=
7
del
b
.
__dict__
self
.
assert_
(
'known_attr'
in
dir
(
self
.
b
),
except
TypeError
:
pass
"set attributes not in dir listing of method"
)
else
:
raise
TestFailed
(
'del func.__dict__ expected TypeError'
)
# Test on underlying function object of method
self
.
F
.
a
.
known_attr
=
7
b
.
publish
=
1
self
.
assert_
(
'known_attr'
in
dir
(
self
.
fi
.
a
),
"set attribute on function "
try
:
"implementations, should show up in next dir"
)
b
.
__dict__
=
None
except
TypeError
:
pass
def
test_duplicate_function_equality
(
self
):
else
:
raise
TestFailed
(
'func.__dict__ = None expected TypeError'
)
# Body of `duplicate' is the exact same as self.b
def
duplicate
():
d
=
{
'hello'
:
'world'
}
'my docstring'
b
.
__dict__
=
d
return
3
if
b
.
__dict__
is
not
d
:
self
.
assertNotEqual
(
self
.
b
,
duplicate
)
raise
TestFailed
(
'func.__dict__ assignment to dictionary failed'
)
if
b
.
hello
!=
'world'
:
def
test_copying___code__
(
self
):
raise
TestFailed
(
'attribute after func.__dict__ assignment failed'
)
def
test
():
pass
self
.
assertEqual
(
test
(),
None
)
f1
=
F
()
test
.
__code__
=
self
.
b
.
__code__
f2
=
F
()
self
.
assertEqual
(
test
(),
3
)
# self.b always returns 3, arbitrarily
try
:
def
test___globals__
(
self
):
F
.
a
.
publish
self
.
assertEqual
(
self
.
b
.
__globals__
,
globals
())
except
AttributeError
:
pass
self
.
cannot_set_attr
(
self
.
b
,
'__globals__'
,
2
,
(
AttributeError
,
TypeError
))
else
:
raise
TestFailed
(
'expected AttributeError'
)
def
test___name__
(
self
):
try
:
self
.
assertEqual
(
self
.
b
.
__name__
,
'b'
)
f1
.
a
.
publish
self
.
b
.
__name__
=
'c'
except
AttributeError
:
pass
self
.
assertEqual
(
self
.
b
.
__name__
,
'c'
)
else
:
raise
TestFailed
(
'expected AttributeError'
)
self
.
b
.
__name__
=
'd'
self
.
assertEqual
(
self
.
b
.
__name__
,
'd'
)
# In Python 2.1 beta 1, we disallowed setting attributes on unbound methods
# __name__ and __name__ must be a string
# (it was already disallowed on bound methods). See the PEP for details.
self
.
cannot_set_attr
(
self
.
b
,
'__name__'
,
7
,
TypeError
)
# In Python 3.0 unbound methods are gone.
# __name__ must be available when in restricted mode. Exec will raise
F
.
a
.
publish
=
1
# AttributeError if __name__ is not available on f.
s
=
"""def f(): pass
\
n
f.__name__"""
if
F
.
a
.
publish
!=
1
:
exec
(
s
,
{
'__builtins__'
:
{}})
raise
TestFailed
(
'unbound method attribute not set to expected value'
)
# Test on methods, too
self
.
assertEqual
(
self
.
fi
.
a
.
__name__
,
'a'
)
if
f1
.
a
.
publish
!=
1
:
self
.
cannot_set_attr
(
self
.
fi
.
a
,
"__name__"
,
'a'
,
AttributeError
)
raise
TestFailed
(
'bound method attribute access did not work'
)
def
test___code__
(
self
):
if
f2
.
a
.
publish
!=
1
:
num_one
,
num_two
=
7
,
8
raise
TestFailed
(
'bound method attribute access did not work'
)
def
a
():
pass
def
b
():
return
12
if
'publish'
not
in
dir
(
F
.
a
):
def
c
():
return
num_one
raise
TestFailed
(
'attribute not in dir()'
)
def
d
():
return
num_two
def
e
():
return
num_one
,
num_two
try
:
for
func
in
[
a
,
b
,
c
,
d
,
e
]:
f1
.
a
.
publish
=
0
self
.
assertEqual
(
type
(
func
.
__code__
),
types
.
CodeType
)
except
(
AttributeError
,
TypeError
):
pass
self
.
assertEqual
(
c
(),
7
)
else
:
raise
TestFailed
(
'expected AttributeError or TypeError'
)
self
.
assertEqual
(
d
(),
8
)
d
.
__code__
=
c
.
__code__
# try setting __dict__
self
.
assertEqual
(
c
.
__code__
,
d
.
__code__
)
F
.
a
.
__dict__
=
{
'one'
:
11
,
'two'
:
22
,
'three'
:
33
}
self
.
assertEqual
(
c
(),
7
)
# self.assertEqual(d(), 7)
if
f1
.
a
.
two
!=
22
:
try
:
b
.
__code__
=
c
.
__code__
raise
TestFailed
(
'setting __dict__'
)
except
ValueError
:
pass
else
:
self
.
fail
(
from
UserDict
import
UserDict
"__code__ with different numbers of free vars should not be "
d
=
UserDict
({
'four'
:
44
,
'five'
:
55
})
"possible"
)
try
:
e
.
__code__
=
d
.
__code__
try
:
except
ValueError
:
pass
F
.
a
.
__dict__
=
d
else
:
self
.
fail
(
except
(
AttributeError
,
TypeError
):
pass
"__code__ with different numbers of free vars should not be "
else
:
raise
TestFailed
"possible"
)
if
f2
.
a
.
one
!=
f1
.
a
.
one
!=
F
.
a
.
one
!=
11
:
def
test_blank_func_defaults
(
self
):
raise
TestFailed
self
.
assertEqual
(
self
.
b
.
__defaults__
,
None
)
del
self
.
b
.
__defaults__
# __func__ may not be a Python method!
self
.
assertEqual
(
self
.
b
.
__defaults__
,
None
)
import
types
F
.
id
=
id
def
test_func_default_args
(
self
):
def
first_func
(
a
,
b
):
eff
=
F
()
return
a
+
b
eff
.
id
=
types
.
MethodType
(
id
,
eff
)
def
second_func
(
a
=
1
,
b
=
2
):
if
eff
.
id
()
!=
id
(
eff
):
return
a
+
b
raise
TestFailed
self
.
assertEqual
(
first_func
.
__defaults__
,
None
)
self
.
assertEqual
(
second_func
.
__defaults__
,
(
1
,
2
))
try
:
first_func
.
__defaults__
=
(
1
,
2
)
F
.
id
.
foo
self
.
assertEqual
(
first_func
.
__defaults__
,
(
1
,
2
))
except
AttributeError
:
pass
self
.
assertEqual
(
first_func
(),
3
)
else
:
raise
TestFailed
self
.
assertEqual
(
first_func
(
3
),
5
)
self
.
assertEqual
(
first_func
(
3
,
5
),
8
)
try
:
del
second_func
.
__defaults__
F
.
id
.
foo
=
12
self
.
assertEqual
(
second_func
.
__defaults__
,
None
)
except
(
AttributeError
,
TypeError
):
pass
try
:
second_func
()
else
:
raise
TestFailed
except
TypeError
:
pass
else
:
self
.
fail
(
try
:
"func_defaults does not update; deleting it does not remove "
F
.
id
.
foo
"requirement"
)
except
AttributeError
:
pass
else
:
raise
TestFailed
class
ImplicitReferencesTest
(
FuncAttrsTest
):
try
:
def
test___class__
(
self
):
eff
.
id
.
foo
self
.
assertEqual
(
self
.
fi
.
a
.
__self__
.
__class__
,
self
.
F
)
except
AttributeError
:
pass
self
.
cannot_set_attr
(
self
.
fi
.
a
,
"__class__"
,
self
.
F
,
TypeError
)
else
:
raise
TestFailed
def
test___func__
(
self
):
try
:
self
.
assertEqual
(
self
.
fi
.
a
.
__func__
,
self
.
F
.
a
)
eff
.
id
.
foo
=
12
self
.
cannot_set_attr
(
self
.
fi
.
a
,
"__func__"
,
self
.
F
.
a
,
AttributeError
)
except
(
AttributeError
,
TypeError
):
pass
else
:
raise
TestFailed
def
test___self__
(
self
):
self
.
assertEqual
(
self
.
fi
.
a
.
__self__
,
self
.
fi
)
try
:
self
.
cannot_set_attr
(
self
.
fi
.
a
,
"__self__"
,
self
.
fi
,
AttributeError
)
eff
.
id
.
foo
except
AttributeError
:
pass
def
test___func___non_method
(
self
):
else
:
raise
TestFailed
# Behavior should be the same when a method is added via an attr
# assignment
# Regression test for a crash in pre-2.1a1
self
.
fi
.
id
=
types
.
MethodType
(
id
,
self
.
fi
)
def
another
():
self
.
assertEqual
(
self
.
fi
.
id
(),
id
(
self
.
fi
))
pass
# Test usage
try
:
self
.
fi
.
id
.
unknown_attr
try
:
except
AttributeError
:
pass
del
another
.
__dict__
else
:
self
.
fail
(
"using unknown attributes should raise AttributeError"
)
except
TypeError
:
pass
# Test assignment and deletion
else
:
raise
TestFailed
self
.
cannot_set_attr
(
self
.
fi
.
id
,
'unknown_attr'
,
2
,
AttributeError
)
try
:
class
ArbitraryFunctionAttrTest
(
FuncAttrsTest
):
del
another
.
__dict__
def
test_set_attr
(
self
):
except
TypeError
:
pass
self
.
b
.
known_attr
=
7
else
:
raise
TestFailed
self
.
assertEqual
(
self
.
b
.
known_attr
,
7
)
try
:
self
.
fi
.
a
.
known_attr
=
7
try
:
except
AttributeError
:
pass
another
.
__dict__
=
None
else
:
self
.
fail
(
"setting attributes on methods should raise error"
)
except
TypeError
:
pass
else
:
raise
TestFailed
def
test_delete_unknown_attr
(
self
):
try
:
del
self
.
b
.
unknown_attr
try
:
except
AttributeError
:
pass
del
another
.
bar
else
:
self
.
fail
(
"deleting unknown attribute should raise TypeError"
)
except
AttributeError
:
pass
else
:
raise
TestFailed
def
test_unset_attr
(
self
):
for
func
in
[
self
.
b
,
self
.
fi
.
a
]:
# This isn't specifically related to function attributes, but it does test a
try
:
func
.
non_existant_attr
# core dump regression in funcobject.c
except
AttributeError
:
pass
del
another
.
__defaults__
else
:
self
.
fail
(
"using unknown attributes should raise "
"AttributeError"
)
def
foo
():
pass
class
FunctionDictsTest
(
FuncAttrsTest
):
def
test_setting_dict_to_invalid
(
self
):
def
bar
():
self
.
cannot_set_attr
(
self
.
b
,
'__dict__'
,
None
,
TypeError
)
pass
from
UserDict
import
UserDict
d
=
UserDict
({
'known_attr'
:
7
})
def
temp
():
self
.
cannot_set_attr
(
self
.
fi
.
a
.
__func__
,
'__dict__'
,
d
,
TypeError
)
print
(
1
)
def
test_setting_dict_to_valid
(
self
):
if
foo
==
bar
:
d
=
{
'known_attr'
:
7
}
raise
TestFailed
self
.
b
.
__dict__
=
d
# Test assignment
d
=
{}
self
.
assertEqual
(
d
,
self
.
b
.
__dict__
)
d
[
foo
]
=
1
# ... and on all the different ways of referencing the method's func
self
.
F
.
a
.
__dict__
=
d
foo
.
__code__
=
temp
.
__code__
self
.
assertEqual
(
d
,
self
.
fi
.
a
.
__func__
.
__dict__
)
self
.
assertEqual
(
d
,
self
.
fi
.
a
.
__dict__
)
d
[
foo
]
# Test value
self
.
assertEqual
(
self
.
b
.
known_attr
,
7
)
# Test all predefined function attributes systematically
self
.
assertEqual
(
self
.
b
.
__dict__
[
'known_attr'
],
7
)
# ... and again, on all the different method's names
def
cantset
(
obj
,
name
,
value
,
exception
=
(
AttributeError
,
TypeError
)):
self
.
assertEqual
(
self
.
fi
.
a
.
__func__
.
known_attr
,
7
)
verify
(
hasattr
(
obj
,
name
))
# Otherwise it's probably a typo
self
.
assertEqual
(
self
.
fi
.
a
.
known_attr
,
7
)
try
:
setattr
(
obj
,
name
,
value
)
def
test_delete___dict__
(
self
):
except
exception
:
try
:
del
self
.
b
.
__dict__
pass
except
TypeError
:
pass
else
:
else
:
self
.
fail
(
"deleting function dictionary should raise TypeError"
)
raise
TestFailed
(
"shouldn't be able to set %s to %r"
%
(
name
,
value
))
try
:
def
test_unassigned_dict
(
self
):
delattr
(
obj
,
name
)
self
.
assertEqual
(
self
.
b
.
__dict__
,
{})
except
(
AttributeError
,
TypeError
):
pass
def
test_func_as_dict_key
(
self
):
else
:
value
=
"Some string"
raise
TestFailed
(
"shouldn't be able to del %s"
%
name
)
d
=
{}
d
[
self
.
b
]
=
value
def
test_func_closure
():
self
.
assertEqual
(
d
[
self
.
b
],
value
)
a
=
12
def
f
():
print
(
a
)
class
FunctionDocstringTest
(
FuncAttrsTest
):
c
=
f
.
__closure__
def
test_set_docstring_attr
(
self
):
verify
(
isinstance
(
c
,
tuple
))
self
.
assertEqual
(
self
.
b
.
__doc__
,
None
)
verify
(
len
(
c
)
==
1
)
docstr
=
"A test method that does nothing"
verify
(
c
[
0
].
__class__
.
__name__
==
"cell"
)
# don't have a type object handy
self
.
b
.
__doc__
=
docstr
cantset
(
f
,
"__closure__"
,
c
)
self
.
F
.
a
.
__doc__
=
docstr
self
.
assertEqual
(
self
.
b
.
__doc__
,
docstr
)
def
test_empty_cell
():
self
.
assertEqual
(
self
.
fi
.
a
.
__doc__
,
docstr
)
def
f
():
print
(
a
)
self
.
cannot_set_attr
(
self
.
fi
.
a
,
"__doc__"
,
docstr
,
AttributeError
)
try
:
f
.
__closure__
[
0
].
cell_contents
def
test_delete_docstring
(
self
):
except
ValueError
:
self
.
b
.
__doc__
=
"The docstring"
pass
del
self
.
b
.
__doc__
else
:
self
.
assertEqual
(
self
.
b
.
__doc__
,
None
)
raise
TestFailed
(
"shouldn't be able to read an empty cell"
)
def
test_main
():
a
=
12
test_support
.
run_unittest
(
FunctionPropertiesTest
,
ImplicitReferencesTest
,
ArbitraryFunctionAttrTest
,
FunctionDictsTest
,
def
test_func_doc
():
FunctionDocstringTest
)
def
f
():
pass
verify
(
f
.
__doc__
is
None
)
if
__name__
==
"__main__"
:
f
.
__doc__
=
"hello"
test_main
()
verify
(
f
.
__doc__
==
"hello"
)
del
f
.
__doc__
verify
(
f
.
__doc__
is
None
)
def
test_func_globals
():
def
f
():
pass
verify
(
f
.
__globals__
is
globals
())
cantset
(
f
,
"__globals__"
,
globals
())
def
test_func_name
():
def
f
():
pass
verify
(
f
.
__name__
==
"f"
)
f
.
__name__
=
"g"
verify
(
f
.
__name__
==
"g"
)
cantset
(
f
,
"__globals__"
,
1
)
cantset
(
f
,
"__name__"
,
1
)
# test that you can access func.__name__ in restricted mode
s
=
"""def f(): pass
\
n
f.__name__"""
exec
(
s
,
{
'__builtins__'
:{}})
def
test_func_code
():
a
=
b
=
24
def
f
():
pass
def
g
():
print
(
12
)
def
f1
():
print
(
a
)
def
g1
():
print
(
b
)
def
f2
():
print
(
a
,
b
)
verify
(
type
(
f
.
__code__
)
is
types
.
CodeType
)
f
.
__code__
=
g
.
__code__
cantset
(
f
,
"__code__"
,
None
)
# can't change the number of free vars
cantset
(
f
,
"__code__"
,
f1
.
__code__
,
exception
=
ValueError
)
cantset
(
f1
,
"__code__"
,
f
.
__code__
,
exception
=
ValueError
)
cantset
(
f1
,
"__code__"
,
f2
.
__code__
,
exception
=
ValueError
)
f1
.
__code__
=
g1
.
__code__
def
test_func_defaults
():
def
f
(
a
,
b
):
return
(
a
,
b
)
verify
(
f
.
__defaults__
is
None
)
f
.
__defaults__
=
(
1
,
2
)
verify
(
f
.
__defaults__
==
(
1
,
2
))
verify
(
f
(
10
)
==
(
10
,
2
))
def
g
(
a
=
1
,
b
=
2
):
return
(
a
,
b
)
verify
(
g
.
__defaults__
==
(
1
,
2
))
del
g
.
__defaults__
verify
(
g
.
__defaults__
is
None
)
try
:
g
()
except
TypeError
:
pass
else
:
raise
TestFailed
(
"shouldn't be allowed to call g() w/o defaults"
)
def
test_func_dict
():
def
f
():
pass
a
=
f
.
__dict__
verify
(
a
==
{})
f
.
hello
=
'world'
verify
(
a
==
{
'hello'
:
'world'
})
verify
(
a
is
f
.
__dict__
)
f
.
__dict__
=
{
'world'
:
'hello'
}
verify
(
f
.
world
==
"hello"
)
verify
(
f
.
__dict__
==
{
'world'
:
'hello'
})
cantset
(
f
,
"__dict__"
,
None
)
def
test___self__
():
class
C
:
def
foo
(
self
):
pass
#verify(C.foo.__self__.__class__ is C)
verify
(
C
().
foo
.
__self__
.
__class__
is
C
)
#cantset(C.foo, "__self__.__class__", C)
cantset
(
C
().
foo
,
"__self__.__class__"
,
C
)
def
test___func__
():
def
foo
(
self
):
pass
class
C
:
pass
C
.
foo
=
foo
#verify(C.foo.__func__ is foo)
verify
(
C
().
foo
.
__func__
is
foo
)
#cantset(C.foo, "__func__", foo)
cantset
(
C
().
foo
,
"__func__"
,
foo
)
def
test___self__
():
class
C
:
def
foo
(
self
):
pass
#verify(C.foo.__self__ is None)
c
=
C
()
#verify(c.foo.__self__ is c)
#cantset(C.foo, "__self__", None)
#cantset(c.foo, "__self__", c)
def
test_im_dict
():
class
C
:
def
foo
(
self
):
pass
foo
.
bar
=
42
verify
(
C
.
foo
.
__dict__
==
{
'bar'
:
42
})
verify
(
C
().
foo
.
__dict__
==
{
'bar'
:
42
})
#cantset(C.foo, "__dict__", C.foo.__dict__)
#cantset(C().foo, "__dict__", C.foo.__dict__)
def
test_im_doc
():
class
C
:
def
foo
(
self
):
"hello"
verify
(
C
.
foo
.
__doc__
==
"hello"
)
verify
(
C
().
foo
.
__doc__
==
"hello"
)
#cantset(C.foo, "__doc__", "hello")
#cantset(C().foo, "__doc__", "hello")
def
test_im_name
():
class
C
:
def
foo
(
self
):
pass
verify
(
C
.
foo
.
__name__
==
"foo"
)
verify
(
C
().
foo
.
__name__
==
"foo"
)
#cantset(C.foo, "__name__", "foo")
#cantset(C().foo, "__name__", "foo")
def
testmore
():
test_func_closure
()
test_empty_cell
()
test_func_doc
()
test_func_globals
()
test_func_name
()
test_func_code
()
test_func_defaults
()
test_func_dict
()
# Tests for instance method attributes
test___self__
()
test___func__
()
test___self__
()
test_im_dict
()
test_im_doc
()
test_im_name
()
testmore
()
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