[Python-checkins] [3.12] gh-106368: Clean up Argument Clinic tests (#106373) (#106379)
erlend-aasland
webhook-mailer at python.org
Mon Jul 3 18:27:37 EDT 2023
https://github.com/python/cpython/commit/38fe0e7c2d0db1bba75bebc7dd5e890a93aa11b0
commit: 38fe0e7c2d0db1bba75bebc7dd5e890a93aa11b0
branch: 3.12
author: Erlend E. Aasland <erlend at python.org>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-07-03T22:27:34Z
summary:
[3.12] gh-106368: Clean up Argument Clinic tests (#106373) (#106379)
(cherry picked from commit 3ee8dac7a1b3882aa3aac7703bdae2de7b6402ad)
files:
M Lib/test/test_clinic.py
diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index 30e8dcc3e8ef1..b3602887ab635 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -3,7 +3,8 @@
# Licensed to the PSF under a contributor agreement.
from test import support, test_tools
-from test.support import import_helper, os_helper
+from test.support import os_helper
+from textwrap import dedent
from unittest import TestCase
import collections
import inspect
@@ -171,43 +172,43 @@ def test_solo_newline(self):
def test_no_substitution(self):
self._test("""
abc
- """, """
+ """, """
abc
- """)
+ """)
def test_empty_substitution(self):
self._test("""
abc
{name}
def
- """, """
+ """, """
abc
def
- """, name='')
+ """, name='')
def test_single_line_substitution(self):
self._test("""
abc
{name}
def
- """, """
+ """, """
abc
GARGLE
def
- """, name='GARGLE')
+ """, name='GARGLE')
def test_multiline_substitution(self):
self._test("""
abc
{name}
def
- """, """
+ """, """
abc
bingle
bungle
def
- """, name='bingle\nbungle\n')
+ """, name='bingle\nbungle\n')
class InertParser:
def __init__(self, clinic):
@@ -240,9 +241,9 @@ def round_trip(self, input):
def test_round_trip_1(self):
self.round_trip("""
- verbatim text here
- lah dee dah
-""")
+ verbatim text here
+ lah dee dah
+ """)
def test_round_trip_2(self):
self.round_trip("""
verbatim text here
@@ -286,22 +287,38 @@ def test_clinic_1(self):
class ClinicParserTest(TestCase):
+ def checkDocstring(self, fn, expected):
+ self.assertTrue(hasattr(fn, "docstring"))
+ self.assertEqual(fn.docstring.strip(),
+ dedent(expected).strip())
+
def test_trivial(self):
parser = DSLParser(FakeClinic())
- block = clinic.Block("module os\nos.access")
+ block = clinic.Block("""
+ module os
+ os.access
+ """)
parser.parse(block)
module, function = block.signatures
self.assertEqual("access", function.name)
self.assertEqual("os", module.name)
def test_ignore_line(self):
- block = self.parse("#\nmodule os\nos.access")
+ block = self.parse(dedent("""
+ #
+ module os
+ os.access
+ """))
module, function = block.signatures
self.assertEqual("access", function.name)
self.assertEqual("os", module.name)
def test_param(self):
- function = self.parse_function("module os\nos.access\n path: int")
+ function = self.parse_function("""
+ module os
+ os.access
+ path: int
+ """)
self.assertEqual("access", function.name)
self.assertEqual(2, len(function.parameters))
p = function.parameters['path']
@@ -309,236 +326,296 @@ def test_param(self):
self.assertIsInstance(p.converter, clinic.int_converter)
def test_param_default(self):
- function = self.parse_function("module os\nos.access\n follow_symlinks: bool = True")
+ function = self.parse_function("""
+ module os
+ os.access
+ follow_symlinks: bool = True
+ """)
p = function.parameters['follow_symlinks']
self.assertEqual(True, p.default)
def test_param_with_continuations(self):
- function = self.parse_function("module os\nos.access\n follow_symlinks: \\\n bool \\\n =\\\n True")
+ function = self.parse_function(r"""
+ module os
+ os.access
+ follow_symlinks: \
+ bool \
+ = \
+ True
+ """)
p = function.parameters['follow_symlinks']
self.assertEqual(True, p.default)
def test_param_default_expression(self):
- function = self.parse_function("module os\nos.access\n follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize")
+ function = self.parse_function("""
+ module os
+ os.access
+ follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize
+ """)
p = function.parameters['follow_symlinks']
self.assertEqual(sys.maxsize, p.default)
self.assertEqual("MAXSIZE", p.converter.c_default)
- s = self.parse_function_should_fail("module os\nos.access\n follow_symlinks: int = sys.maxsize")
- self.assertEqual(s, "Error on line 0:\nWhen you specify a named constant ('sys.maxsize') as your default value,\nyou MUST specify a valid c_default.\n")
+ expected_msg = (
+ "Error on line 0:\n"
+ "When you specify a named constant ('sys.maxsize') as your default value,\n"
+ "you MUST specify a valid c_default.\n"
+ )
+ out = self.parse_function_should_fail("""
+ module os
+ os.access
+ follow_symlinks: int = sys.maxsize
+ """)
+ self.assertEqual(out, expected_msg)
def test_param_no_docstring(self):
function = self.parse_function("""
-module os
-os.access
- follow_symlinks: bool = True
- something_else: str = ''""")
+ module os
+ os.access
+ follow_symlinks: bool = True
+ something_else: str = ''
+ """)
p = function.parameters['follow_symlinks']
self.assertEqual(3, len(function.parameters))
- self.assertIsInstance(function.parameters['something_else'].converter, clinic.str_converter)
+ conv = function.parameters['something_else'].converter
+ self.assertIsInstance(conv, clinic.str_converter)
def test_param_default_parameters_out_of_order(self):
- s = self.parse_function_should_fail("""
-module os
-os.access
- follow_symlinks: bool = True
- something_else: str""")
- self.assertEqual(s, """Error on line 0:
-Can't have a parameter without a default ('something_else')
-after a parameter with a default!
-""")
+ expected_msg = (
+ "Error on line 0:\n"
+ "Can't have a parameter without a default ('something_else')\n"
+ "after a parameter with a default!\n"
+ )
+ out = self.parse_function_should_fail("""
+ module os
+ os.access
+ follow_symlinks: bool = True
+ something_else: str""")
+ self.assertEqual(out, expected_msg)
def disabled_test_converter_arguments(self):
- function = self.parse_function("module os\nos.access\n path: path_t(allow_fd=1)")
+ function = self.parse_function("""
+ module os
+ os.access
+ path: path_t(allow_fd=1)
+ """)
p = function.parameters['path']
self.assertEqual(1, p.converter.args['allow_fd'])
def test_function_docstring(self):
function = self.parse_function("""
-module os
-os.stat as os_stat_fn
+ module os
+ os.stat as os_stat_fn
- path: str
- Path to be examined
+ path: str
+ Path to be examined
-Perform a stat system call on the given path.""")
- self.assertEqual("""
-stat($module, /, path)
---
+ Perform a stat system call on the given path.
+ """)
+ self.checkDocstring(function, """
+ stat($module, /, path)
+ --
-Perform a stat system call on the given path.
+ Perform a stat system call on the given path.
- path
- Path to be examined
-""".strip(), function.docstring)
+ path
+ Path to be examined
+ """)
def test_explicit_parameters_in_docstring(self):
- function = self.parse_function("""
-module foo
-foo.bar
- x: int
- Documentation for x.
- y: int
+ function = self.parse_function(dedent("""
+ module foo
+ foo.bar
+ x: int
+ Documentation for x.
+ y: int
-This is the documentation for foo.
+ This is the documentation for foo.
-Okay, we're done here.
-""")
- self.assertEqual("""
-bar($module, /, x, y)
---
+ Okay, we're done here.
+ """))
+ self.checkDocstring(function, """
+ bar($module, /, x, y)
+ --
-This is the documentation for foo.
+ This is the documentation for foo.
- x
- Documentation for x.
+ x
+ Documentation for x.
-Okay, we're done here.
-""".strip(), function.docstring)
+ Okay, we're done here.
+ """)
def test_parser_regression_special_character_in_parameter_column_of_docstring_first_line(self):
- function = self.parse_function("""
-module os
-os.stat
- path: str
-This/used to break Clinic!
-""")
- self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring)
+ function = self.parse_function(dedent("""
+ module os
+ os.stat
+ path: str
+ This/used to break Clinic!
+ """))
+ self.checkDocstring(function, """
+ stat($module, /, path)
+ --
+
+ This/used to break Clinic!
+ """)
def test_c_name(self):
- function = self.parse_function("module os\nos.stat as os_stat_fn")
+ function = self.parse_function("""
+ module os
+ os.stat as os_stat_fn
+ """)
self.assertEqual("os_stat_fn", function.c_basename)
def test_return_converter(self):
- function = self.parse_function("module os\nos.stat -> int")
+ function = self.parse_function("""
+ module os
+ os.stat -> int
+ """)
self.assertIsInstance(function.return_converter, clinic.int_return_converter)
def test_star(self):
- function = self.parse_function("module os\nos.access\n *\n follow_symlinks: bool = True")
+ function = self.parse_function("""
+ module os
+ os.access
+ *
+ follow_symlinks: bool = True
+ """)
p = function.parameters['follow_symlinks']
self.assertEqual(inspect.Parameter.KEYWORD_ONLY, p.kind)
self.assertEqual(0, p.group)
def test_group(self):
- function = self.parse_function("module window\nwindow.border\n [\n ls : int\n ]\n /\n")
+ function = self.parse_function("""
+ module window
+ window.border
+ [
+ ls: int
+ ]
+ /
+ """)
p = function.parameters['ls']
self.assertEqual(1, p.group)
def test_left_group(self):
function = self.parse_function("""
-module curses
-curses.addch
- [
- y: int
- Y-coordinate.
- x: int
- X-coordinate.
- ]
- ch: char
- Character to add.
- [
- attr: long
- Attributes for the character.
- ]
- /
-""")
- for name, group in (
+ module curses
+ curses.addch
+ [
+ y: int
+ Y-coordinate.
+ x: int
+ X-coordinate.
+ ]
+ ch: char
+ Character to add.
+ [
+ attr: long
+ Attributes for the character.
+ ]
+ /
+ """)
+ dataset = (
('y', -1), ('x', -1),
('ch', 0),
('attr', 1),
- ):
- p = function.parameters[name]
- self.assertEqual(p.group, group)
- self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
- self.assertEqual(function.docstring.strip(), """
-addch([y, x,] ch, [attr])
-
-
- y
- Y-coordinate.
- x
- X-coordinate.
- ch
- Character to add.
- attr
- Attributes for the character.
- """.strip())
+ )
+ for name, group in dataset:
+ with self.subTest(name=name, group=group):
+ p = function.parameters[name]
+ self.assertEqual(p.group, group)
+ self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
+ self.checkDocstring(function, """
+ addch([y, x,] ch, [attr])
+
+
+ y
+ Y-coordinate.
+ x
+ X-coordinate.
+ ch
+ Character to add.
+ attr
+ Attributes for the character.
+ """)
def test_nested_groups(self):
function = self.parse_function("""
-module curses
-curses.imaginary
- [
- [
- y1: int
- Y-coordinate.
- y2: int
- Y-coordinate.
- ]
- x1: int
- X-coordinate.
- x2: int
- X-coordinate.
- ]
- ch: char
- Character to add.
- [
- attr1: long
- Attributes for the character.
- attr2: long
- Attributes for the character.
- attr3: long
- Attributes for the character.
- [
- attr4: long
- Attributes for the character.
- attr5: long
- Attributes for the character.
- attr6: long
- Attributes for the character.
- ]
- ]
- /
-""")
- for name, group in (
+ module curses
+ curses.imaginary
+ [
+ [
+ y1: int
+ Y-coordinate.
+ y2: int
+ Y-coordinate.
+ ]
+ x1: int
+ X-coordinate.
+ x2: int
+ X-coordinate.
+ ]
+ ch: char
+ Character to add.
+ [
+ attr1: long
+ Attributes for the character.
+ attr2: long
+ Attributes for the character.
+ attr3: long
+ Attributes for the character.
+ [
+ attr4: long
+ Attributes for the character.
+ attr5: long
+ Attributes for the character.
+ attr6: long
+ Attributes for the character.
+ ]
+ ]
+ /
+ """)
+ dataset = (
('y1', -2), ('y2', -2),
('x1', -1), ('x2', -1),
('ch', 0),
('attr1', 1), ('attr2', 1), ('attr3', 1),
('attr4', 2), ('attr5', 2), ('attr6', 2),
- ):
- p = function.parameters[name]
- self.assertEqual(p.group, group)
- self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
-
- self.assertEqual(function.docstring.strip(), """
-imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5,
- attr6]])
-
-
- y1
- Y-coordinate.
- y2
- Y-coordinate.
- x1
- X-coordinate.
- x2
- X-coordinate.
- ch
- Character to add.
- attr1
- Attributes for the character.
- attr2
- Attributes for the character.
- attr3
- Attributes for the character.
- attr4
- Attributes for the character.
- attr5
- Attributes for the character.
- attr6
- Attributes for the character.
- """.strip())
+ )
+ for name, group in dataset:
+ with self.subTest(name=name, group=group):
+ p = function.parameters[name]
+ self.assertEqual(p.group, group)
+ self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
+
+ self.checkDocstring(function, """
+ imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5,
+ attr6]])
+
+
+ y1
+ Y-coordinate.
+ y2
+ Y-coordinate.
+ x1
+ X-coordinate.
+ x2
+ X-coordinate.
+ ch
+ Character to add.
+ attr1
+ Attributes for the character.
+ attr2
+ Attributes for the character.
+ attr3
+ Attributes for the character.
+ attr4
+ Attributes for the character.
+ attr5
+ Attributes for the character.
+ attr6
+ Attributes for the character.
+ """)
def parse_function_should_fail(self, s):
with support.captured_stdout() as stdout:
@@ -547,104 +624,108 @@ def parse_function_should_fail(self, s):
return stdout.getvalue()
def test_disallowed_grouping__two_top_groups_on_left(self):
- s = self.parse_function_should_fail("""
-module foo
-foo.two_top_groups_on_left
- [
- group1 : int
- ]
- [
- group2 : int
- ]
- param: int
- """)
- self.assertEqual(s,
- ('Error on line 0:\n'
- 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b)\n'))
+ expected_msg = (
+ 'Error on line 0:\n'
+ 'Function two_top_groups_on_left has an unsupported group '
+ 'configuration. (Unexpected state 2.b)\n'
+ )
+ out = self.parse_function_should_fail("""
+ module foo
+ foo.two_top_groups_on_left
+ [
+ group1 : int
+ ]
+ [
+ group2 : int
+ ]
+ param: int
+ """)
+ self.assertEqual(out, expected_msg)
def test_disallowed_grouping__two_top_groups_on_right(self):
self.parse_function_should_fail("""
-module foo
-foo.two_top_groups_on_right
- param: int
- [
- group1 : int
- ]
- [
- group2 : int
- ]
- """)
+ module foo
+ foo.two_top_groups_on_right
+ param: int
+ [
+ group1 : int
+ ]
+ [
+ group2 : int
+ ]
+ """)
def test_disallowed_grouping__parameter_after_group_on_right(self):
self.parse_function_should_fail("""
-module foo
-foo.parameter_after_group_on_right
- param: int
- [
- [
- group1 : int
- ]
- group2 : int
- ]
- """)
+ module foo
+ foo.parameter_after_group_on_right
+ param: int
+ [
+ [
+ group1 : int
+ ]
+ group2 : int
+ ]
+ """)
def test_disallowed_grouping__group_after_parameter_on_left(self):
self.parse_function_should_fail("""
-module foo
-foo.group_after_parameter_on_left
- [
- group2 : int
- [
- group1 : int
- ]
- ]
- param: int
- """)
+ module foo
+ foo.group_after_parameter_on_left
+ [
+ group2 : int
+ [
+ group1 : int
+ ]
+ ]
+ param: int
+ """)
def test_disallowed_grouping__empty_group_on_left(self):
self.parse_function_should_fail("""
-module foo
-foo.empty_group
- [
- [
- ]
- group2 : int
- ]
- param: int
- """)
+ module foo
+ foo.empty_group
+ [
+ [
+ ]
+ group2 : int
+ ]
+ param: int
+ """)
def test_disallowed_grouping__empty_group_on_right(self):
self.parse_function_should_fail("""
-module foo
-foo.empty_group
- param: int
- [
- [
- ]
- group2 : int
- ]
- """)
+ module foo
+ foo.empty_group
+ param: int
+ [
+ [
+ ]
+ group2 : int
+ ]
+ """)
def test_no_parameters(self):
function = self.parse_function("""
-module foo
-foo.bar
+ module foo
+ foo.bar
-Docstring
+ Docstring
-""")
+ """)
self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring)
self.assertEqual(1, len(function.parameters)) # self!
def test_init_with_no_parameters(self):
function = self.parse_function("""
-module foo
-class foo.Bar "unused" "notneeded"
-foo.Bar.__init__
+ module foo
+ class foo.Bar "unused" "notneeded"
+ foo.Bar.__init__
-Docstring
+ Docstring
+
+ """, signatures_in_block=3, function_index=2)
-""", signatures_in_block=3, function_index=2)
# self is not in the signature
self.assertEqual("Bar()\n--\n\nDocstring", function.docstring)
# but it *is* a parameter
@@ -652,113 +733,117 @@ class foo.Bar "unused" "notneeded"
def test_illegal_module_line(self):
self.parse_function_should_fail("""
-module foo
-foo.bar => int
- /
-""")
+ module foo
+ foo.bar => int
+ /
+ """)
def test_illegal_c_basename(self):
self.parse_function_should_fail("""
-module foo
-foo.bar as 935
- /
-""")
+ module foo
+ foo.bar as 935
+ /
+ """)
def test_single_star(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- *
- *
-""")
+ module foo
+ foo.bar
+ *
+ *
+ """)
def test_parameters_required_after_star_without_initial_parameters_or_docstring(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- *
-""")
+ module foo
+ foo.bar
+ *
+ """)
def test_parameters_required_after_star_without_initial_parameters_with_docstring(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- *
-Docstring here.
-""")
+ module foo
+ foo.bar
+ *
+ Docstring here.
+ """)
def test_parameters_required_after_star_with_initial_parameters_without_docstring(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- this: int
- *
-""")
+ module foo
+ foo.bar
+ this: int
+ *
+ """)
def test_parameters_required_after_star_with_initial_parameters_and_docstring(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- this: int
- *
-Docstring.
-""")
+ module foo
+ foo.bar
+ this: int
+ *
+ Docstring.
+ """)
def test_single_slash(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- /
- /
-""")
+ module foo
+ foo.bar
+ /
+ /
+ """)
def test_mix_star_and_slash(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- x: int
- y: int
- *
- z: int
- /
-""")
+ module foo
+ foo.bar
+ x: int
+ y: int
+ *
+ z: int
+ /
+ """)
def test_parameters_not_permitted_after_slash_for_now(self):
self.parse_function_should_fail("""
-module foo
-foo.bar
- /
- x: int
-""")
+ module foo
+ foo.bar
+ /
+ x: int
+ """)
def test_parameters_no_more_than_one_vararg(self):
- s = self.parse_function_should_fail("""
-module foo
-foo.bar
- *vararg1: object
- *vararg2: object
-""")
- self.assertEqual(s, "Error on line 0:\nToo many var args\n")
+ expected_msg = (
+ "Error on line 0:\n"
+ "Too many var args\n"
+ )
+ out = self.parse_function_should_fail("""
+ module foo
+ foo.bar
+ *vararg1: object
+ *vararg2: object
+ """)
+ self.assertEqual(out, expected_msg)
def test_function_not_at_column_0(self):
function = self.parse_function("""
- module foo
- foo.bar
- x: int
- Nested docstring here, goeth.
- *
- y: str
- Not at column 0!
-""")
- self.assertEqual("""
-bar($module, /, x, *, y)
---
+ module foo
+ foo.bar
+ x: int
+ Nested docstring here, goeth.
+ *
+ y: str
+ Not at column 0!
+ """)
+ self.checkDocstring(function, """
+ bar($module, /, x, *, y)
+ --
-Not at column 0!
+ Not at column 0!
- x
- Nested docstring here, goeth.
-""".strip(), function.docstring)
+ x
+ Nested docstring here, goeth.
+ """)
def test_directive(self):
c = FakeClinic()
@@ -772,46 +857,39 @@ def test_directive(self):
def test_legacy_converters(self):
block = self.parse('module os\nos.access\n path: "s"')
module, function = block.signatures
- self.assertIsInstance((function.parameters['path']).converter, clinic.str_converter)
+ conv = (function.parameters['path']).converter
+ self.assertIsInstance(conv, clinic.str_converter)
def test_legacy_converters_non_string_constant_annotation(self):
- expected_failure_message = """\
-Error on line 0:
-Annotations must be either a name, a function call, or a string.
-"""
-
- s = self.parse_function_should_fail('module os\nos.access\n path: 42')
- self.assertEqual(s, expected_failure_message)
-
- s = self.parse_function_should_fail('module os\nos.access\n path: 42.42')
- self.assertEqual(s, expected_failure_message)
-
- s = self.parse_function_should_fail('module os\nos.access\n path: 42j')
- self.assertEqual(s, expected_failure_message)
-
- s = self.parse_function_should_fail('module os\nos.access\n path: b"42"')
- self.assertEqual(s, expected_failure_message)
-
- def test_other_bizarre_things_in_annotations_fail(self):
- expected_failure_message = """\
-Error on line 0:
-Annotations must be either a name, a function call, or a string.
-"""
-
- s = self.parse_function_should_fail(
- 'module os\nos.access\n path: {"some": "dictionary"}'
+ expected_failure_message = (
+ "Error on line 0:\n"
+ "Annotations must be either a name, a function call, or a string.\n"
)
- self.assertEqual(s, expected_failure_message)
-
- s = self.parse_function_should_fail(
- 'module os\nos.access\n path: ["list", "of", "strings"]'
+ dataset = (
+ 'module os\nos.access\n path: 42',
+ 'module os\nos.access\n path: 42.42',
+ 'module os\nos.access\n path: 42j',
+ 'module os\nos.access\n path: b"42"',
)
- self.assertEqual(s, expected_failure_message)
+ for block in dataset:
+ with self.subTest(block=block):
+ out = self.parse_function_should_fail(block)
+ self.assertEqual(out, expected_failure_message)
- s = self.parse_function_should_fail(
- 'module os\nos.access\n path: (x for x in range(42))'
+ def test_other_bizarre_things_in_annotations_fail(self):
+ expected_failure_message = (
+ "Error on line 0:\n"
+ "Annotations must be either a name, a function call, or a string.\n"
+ )
+ dataset = (
+ 'module os\nos.access\n path: {"some": "dictionary"}',
+ 'module os\nos.access\n path: ["list", "of", "strings"]',
+ 'module os\nos.access\n path: (x for x in range(42))',
)
- self.assertEqual(s, expected_failure_message)
+ for block in dataset:
+ with self.subTest(block=block):
+ out = self.parse_function_should_fail(block)
+ self.assertEqual(out, expected_failure_message)
def test_kwarg_splats_disallowed_in_function_call_annotations(self):
expected_error_msg = (
@@ -945,10 +1023,16 @@ def test_scaffolding(self):
self.assertEqual(repr(clinic.NULL), '<Null>')
# test that fail fails
+ expected = (
+ 'Error in file "clown.txt" on line 69:\n'
+ 'The igloos are melting!\n'
+ )
with support.captured_stdout() as stdout:
with self.assertRaises(SystemExit):
- clinic.fail('The igloos are melting!', filename='clown.txt', line_number=69)
- self.assertEqual(stdout.getvalue(), 'Error in file "clown.txt" on line 69:\nThe igloos are melting!\n')
+ clinic.fail('The igloos are melting!',
+ filename='clown.txt', line_number=69)
+ actual = stdout.getvalue()
+ self.assertEqual(actual, expected)
class ClinicExternalTest(TestCase):
More information about the Python-checkins
mailing list