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