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
8f7bb100
Commit
8f7bb100
authored
Aug 06, 2018
by
Serhiy Storchaka
Committed by
GitHub
Aug 06, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-34272: Move argument parsing tests from test_capi to test_getargs2. (GH-8567)
parent
28c7f8c8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
182 additions
and
181 deletions
+182
-181
Lib/test/test_capi.py
Lib/test/test_capi.py
+3
-180
Lib/test/test_getargs2.py
Lib/test/test_getargs2.py
+179
-1
No files found.
Lib/test/test_capi.py
View file @
8f7bb100
...
...
@@ -6,7 +6,6 @@ import os
import
pickle
import
random
import
re
import
string
import
subprocess
import
sys
import
sysconfig
...
...
@@ -414,174 +413,6 @@ class SubinterpreterTest(unittest.TestCase):
self
.
assertNotEqual
(
pickle
.
load
(
f
),
id
(
builtins
))
# Bug #6012
class
Test6012
(
unittest
.
TestCase
):
def
test
(
self
):
self
.
assertEqual
(
_testcapi
.
argparsing
(
"Hello"
,
"World"
),
1
)
class
SkipitemTest
(
unittest
.
TestCase
):
def
test_skipitem
(
self
):
"""
If this test failed, you probably added a new "format unit"
in Python/getargs.c, but neglected to update our poor friend
skipitem() in the same file. (If so, shame on you!)
With a few exceptions**, this function brute-force tests all
printable ASCII*** characters (32 to 126 inclusive) as format units,
checking to see that PyArg_ParseTupleAndKeywords() return consistent
errors both when the unit is attempted to be used and when it is
skipped. If the format unit doesn't exist, we'll get one of two
specific error messages (one for used, one for skipped); if it does
exist we *won't* get that error--we'll get either no error or some
other error. If we get the specific "does not exist" error for one
test and not for the other, there's a mismatch, and the test fails.
** Some format units have special funny semantics and it would
be difficult to accommodate them here. Since these are all
well-established and properly skipped in skipitem() we can
get away with not testing them--this test is really intended
to catch *new* format units.
*** Python C source files must be ASCII. Therefore it's impossible
to have non-ASCII format units.
"""
empty_tuple
=
()
tuple_1
=
(
0
,)
dict_b
=
{
'b'
:
1
}
keywords
=
[
"a"
,
"b"
]
for
i
in
range
(
32
,
127
):
c
=
chr
(
i
)
# skip parentheses, the error reporting is inconsistent about them
# skip 'e', it's always a two-character code
# skip '|' and '$', they don't represent arguments anyway
if
c
in
'()e|$'
:
continue
# test the format unit when not skipped
format
=
c
+
"i"
try
:
_testcapi
.
parse_tuple_and_keywords
(
tuple_1
,
dict_b
,
format
,
keywords
)
when_not_skipped
=
False
except
SystemError
as
e
:
s
=
"argument 1 (impossible<bad format char>)"
when_not_skipped
=
(
str
(
e
)
==
s
)
except
TypeError
:
when_not_skipped
=
False
# test the format unit when skipped
optional_format
=
"|"
+
format
try
:
_testcapi
.
parse_tuple_and_keywords
(
empty_tuple
,
dict_b
,
optional_format
,
keywords
)
when_skipped
=
False
except
SystemError
as
e
:
s
=
"impossible<bad format char>: '{}'"
.
format
(
format
)
when_skipped
=
(
str
(
e
)
==
s
)
message
=
(
"test_skipitem_parity: "
"detected mismatch between convertsimple and skipitem "
"for format unit '{}' ({}), not skipped {}, skipped {}"
.
format
(
c
,
i
,
when_skipped
,
when_not_skipped
))
self
.
assertIs
(
when_skipped
,
when_not_skipped
,
message
)
def
test_skipitem_with_suffix
(
self
):
parse
=
_testcapi
.
parse_tuple_and_keywords
empty_tuple
=
()
tuple_1
=
(
0
,)
dict_b
=
{
'b'
:
1
}
keywords
=
[
"a"
,
"b"
]
supported
=
(
's#'
,
's*'
,
'z#'
,
'z*'
,
'u#'
,
'Z#'
,
'y#'
,
'y*'
,
'w#'
,
'w*'
)
for
c
in
string
.
ascii_letters
:
for
c2
in
'#*'
:
f
=
c
+
c2
with
self
.
subTest
(
format
=
f
):
optional_format
=
"|"
+
f
+
"i"
if
f
in
supported
:
parse
(
empty_tuple
,
dict_b
,
optional_format
,
keywords
)
else
:
with
self
.
assertRaisesRegex
(
SystemError
,
'impossible<bad format char>'
):
parse
(
empty_tuple
,
dict_b
,
optional_format
,
keywords
)
for
c
in
map
(
chr
,
range
(
32
,
128
)):
f
=
'e'
+
c
optional_format
=
"|"
+
f
+
"i"
with
self
.
subTest
(
format
=
f
):
if
c
in
'st'
:
parse
(
empty_tuple
,
dict_b
,
optional_format
,
keywords
)
else
:
with
self
.
assertRaisesRegex
(
SystemError
,
'impossible<bad format char>'
):
parse
(
empty_tuple
,
dict_b
,
optional_format
,
keywords
)
def
test_parse_tuple_and_keywords
(
self
):
# Test handling errors in the parse_tuple_and_keywords helper itself
self
.
assertRaises
(
TypeError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{},
42
,
[])
self
.
assertRaises
(
ValueError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{},
''
,
42
)
self
.
assertRaises
(
ValueError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{},
''
,
[
''
]
*
42
)
self
.
assertRaises
(
ValueError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{},
''
,
[
42
])
def
test_bad_use
(
self
):
# Test handling invalid format and keywords in
# PyArg_ParseTupleAndKeywords()
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(
1
,),
{},
'||O'
,
[
'a'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(
1
,
2
),
{},
'|O|O'
,
[
'a'
,
'b'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{
'a'
:
1
},
'$$O'
,
[
'a'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{
'a'
:
1
,
'b'
:
2
},
'$O$O'
,
[
'a'
,
'b'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{
'a'
:
1
},
'$|O'
,
[
'a'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{
'a'
:
1
,
'b'
:
2
},
'$O|O'
,
[
'a'
,
'b'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(
1
,),
{},
'|O'
,
[
'a'
,
'b'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(
1
,),
{},
'|OO'
,
[
'a'
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{},
'|$O'
,
[
''
])
self
.
assertRaises
(
SystemError
,
_testcapi
.
parse_tuple_and_keywords
,
(),
{},
'|OO'
,
[
'a'
,
''
])
def
test_positional_only
(
self
):
parse
=
_testcapi
.
parse_tuple_and_keywords
parse
((
1
,
2
,
3
),
{},
'OOO'
,
[
''
,
''
,
'a'
])
parse
((
1
,
2
),
{
'a'
:
3
},
'OOO'
,
[
''
,
''
,
'a'
])
with
self
.
assertRaisesRegex
(
TypeError
,
r'function takes at least 2 positional arguments \
(
1 given\
)
'):
parse((1,), {'
a
': 3}, '
OOO
', ['', '', '
a
'])
parse((1,), {}, '
O
|
OO
', ['', '', '
a
'])
with self.assertRaisesRegex(TypeError,
r'
function
takes
at
least
1
positional
arguments
\
(
0
given
\
)
'):
parse((), {}, '
O
|
OO
', ['', '', '
a
'])
parse((1, 2), {'
a
': 3}, '
OO
$
O
', ['', '', '
a
'])
with self.assertRaisesRegex(TypeError,
r'
function
takes
exactly
2
positional
arguments
\
(
1
given
\
)
'):
parse((1,), {'
a
': 3}, '
OO
$
O
', ['', '', '
a
'])
parse((1,), {}, '
O
|
O
$
O
', ['', '', '
a
'])
with self.assertRaisesRegex(TypeError,
r'
function
takes
at
least
1
positional
arguments
\
(
0
given
\
)
'):
parse((), {}, '
O
|
O
$
O
', ['', '', '
a
'])
with self.assertRaisesRegex(SystemError, r'
Empty
parameter
name
after
\
$
'):
parse((1,), {}, '
O
|
$
OO
', ['', '', '
a
'])
with self.assertRaisesRegex(SystemError, '
Empty
keyword
'):
parse((1,), {}, '
O
|
OO
', ['', '
a
', ''])
class
TestThreadState
(
unittest
.
TestCase
):
@
support
.
reap_threads
...
...
@@ -607,17 +438,9 @@ class TestThreadState(unittest.TestCase):
class
Test_testcapi
(
unittest
.
TestCase
):
def test__testcapi(self):
if support.verbose:
print()
for name in dir(_testcapi):
if not name.startswith('test_'):
continue
with self.subTest("
internal
", name=name):
if support.verbose:
print(f"
{
name
}
", flush=True)
test = getattr(_testcapi, name)
test()
locals
().
update
((
name
,
getattr
(
_testcapi
,
name
))
for
name
in
dir
(
_testcapi
)
if
name
.
startswith
(
'test_'
)
and
not
name
.
endswith
(
'_code'
))
class
PyMemDebugTests
(
unittest
.
TestCase
):
...
...
Lib/test/test_getargs2.py
View file @
8f7bb100
import
unittest
import
math
import
string
import
sys
from
test
import
support
# Skip this test if the _testcapi module isn't available.
support
.
import_module
(
'_testcapi'
)
_testcapi
=
support
.
import_module
(
'_testcapi'
)
from
_testcapi
import
getargs_keywords
,
getargs_keyword_only
# > How about the following counterproposal. This also changes some of
...
...
@@ -956,5 +957,182 @@ class Object_TestCase(unittest.TestCase):
self.assertRaises(TypeError, getargs_U, None)
# Bug #6012
class Test6012(unittest.TestCase):
def test(self):
self.assertEqual(_testcapi.argparsing("
Hello
", "
World
"), 1)
class SkipitemTest(unittest.TestCase):
def test_skipitem(self):
"""
If this test failed, you probably added a new "
format
unit
"
in Python/getargs.c, but neglected to update our poor friend
skipitem() in the same file. (If so, shame on you!)
With a few exceptions**, this function brute-force tests all
printable ASCII*** characters (32 to 126 inclusive) as format units,
checking to see that PyArg_ParseTupleAndKeywords() return consistent
errors both when the unit is attempted to be used and when it is
skipped. If the format unit doesn't exist, we'll get one of two
specific error messages (one for used, one for skipped); if it does
exist we *won't* get that error--we'll get either no error or some
other error. If we get the specific "
does
not
exist
" error for one
test and not for the other, there's a mismatch, and the test fails.
** Some format units have special funny semantics and it would
be difficult to accommodate them here. Since these are all
well-established and properly skipped in skipitem() we can
get away with not testing them--this test is really intended
to catch *new* format units.
*** Python C source files must be ASCII. Therefore it's impossible
to have non-ASCII format units.
"""
empty_tuple = ()
tuple_1 = (0,)
dict_b = {'b':1}
keywords = ["
a
", "b"]
for i in range(32, 127):
c = chr(i)
# skip parentheses, the error reporting is inconsistent about them
# skip 'e', it's always a two-character code
# skip '|' and '$', they don't represent arguments anyway
if c in '()e|$':
continue
# test the format unit when not skipped
format = c + "
i
"
try:
_testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
format, keywords)
when_not_skipped = False
except SystemError as e:
s = "
argument
1
(
impossible
<
bad
format
char
>
)
"
when_not_skipped = (str(e) == s)
except TypeError:
when_not_skipped = False
# test the format unit when skipped
optional_format = "
|
" + format
try:
_testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
optional_format, keywords)
when_skipped = False
except SystemError as e:
s = "
impossible
<
bad
format
char
>
:
'{}'".format(format)
when_skipped = (str(e) == s)
message = ("
test_skipitem_parity
:
"
"
detected
mismatch
between
convertsimple
and
skipitem
"
"
for
format
unit
'{}'
({}),
not
skipped
{},
skipped
{}
".format(
c, i, when_skipped, when_not_skipped))
self.assertIs(when_skipped, when_not_skipped, message)
def test_skipitem_with_suffix(self):
parse = _testcapi.parse_tuple_and_keywords
empty_tuple = ()
tuple_1 = (0,)
dict_b = {'b':1}
keywords = ["
a
", "b"]
supported = ('s#', 's*', 'z#', 'z*', 'u#', 'Z#', 'y#', 'y*', 'w#', 'w*')
for c in string.ascii_letters:
for c2 in '#*':
f = c + c2
with self.subTest(format=f):
optional_format = "
|
" + f + "
i
"
if f in supported:
parse(empty_tuple, dict_b, optional_format, keywords)
else:
with self.assertRaisesRegex(SystemError,
'impossible<bad format char>'):
parse(empty_tuple, dict_b, optional_format, keywords)
for c in map(chr, range(32, 128)):
f = 'e' + c
optional_format = "
|
" + f + "
i
"
with self.subTest(format=f):
if c in 'st':
parse(empty_tuple, dict_b, optional_format, keywords)
else:
with self.assertRaisesRegex(SystemError,
'impossible<bad format char>'):
parse(empty_tuple, dict_b, optional_format, keywords)
class ParseTupleAndKeywords_Test(unittest.TestCase):
def test_parse_tuple_and_keywords(self):
# Test handling errors in the parse_tuple_and_keywords helper itself
self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
(), {}, 42, [])
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, '', 42)
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, '', [''] * 42)
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, '', [42])
def test_bad_use(self):
# Test handling invalid format and keywords in
# PyArg_ParseTupleAndKeywords()
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(1,), {}, '||O', ['a'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(1, 2), {}, '|O|O', ['a', 'b'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(), {'a': 1}, '$$O', ['a'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(), {'a': 1, 'b': 2}, '$O$O', ['a', 'b'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(), {'a': 1}, '$|O', ['a'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(), {'a': 1, 'b': 2}, '$O|O', ['a', 'b'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(1,), {}, '|O', ['a', 'b'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(1,), {}, '|OO', ['a'])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(), {}, '|$O', [''])
self.assertRaises(SystemError, _testcapi.parse_tuple_and_keywords,
(), {}, '|OO', ['a', ''])
def test_positional_only(self):
parse = _testcapi.parse_tuple_and_keywords
parse((1, 2, 3), {}, 'OOO', ['', '', 'a'])
parse((1, 2), {'a': 3}, 'OOO', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
r'function takes at least 2 positional arguments
\
(
1
given
\
)
'
):
parse((1,), {'a': 3}, 'OOO', ['', '', 'a'])
parse((1,), {}, 'O|OO', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
r'function takes at least 1 positional arguments
\
(
0
given
\
)
'
):
parse((), {}, 'O|OO', ['', '', 'a'])
parse((1, 2), {'a': 3}, 'OO$O', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
r'function takes exactly 2 positional arguments
\
(
1
given
\
)
'
):
parse((1,), {'a': 3}, 'OO$O', ['', '', 'a'])
parse((1,), {}, 'O|O$O', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
r'function takes at least 1 positional arguments
\
(
0
given
\
)
'
):
parse((), {}, 'O|O$O', ['', '', 'a'])
with self.assertRaisesRegex(SystemError, r'Empty parameter name after
\
$
'
):
parse((1,), {}, 'O|$OO', ['', '', 'a'])
with self.assertRaisesRegex(SystemError, 'Empty keyword'):
parse((1,), {}, 'O|OO', ['', 'a', ''])
class Test_testcapi(unittest.TestCase):
locals().update((name, getattr(_testcapi, name))
for name in dir(_testcapi)
if name.startswith('test_') and name.endswith('_code'))
if __name__ == "
__main__
":
unittest.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