Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-113317: Finish splitting Argument Clinic into sub-files #117513

Merged
merged 1 commit into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 56 additions & 48 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,26 @@
test_tools.skip_if_missing('clinic')
with test_tools.imports_under_tool('clinic'):
import libclinic
from libclinic.converters import int_converter, str_converter
from libclinic import ClinicError, unspecified, NULL, fail
from libclinic.converters import int_converter, str_converter, self_converter
from libclinic.function import (
Module, Class, Function, FunctionKind, Parameter,
permute_optional_groups, permute_right_option_groups,
permute_left_option_groups)
import clinic
from clinic import DSLParser
from libclinic.clanguage import CLanguage
from libclinic.converter import converters, legacy_converters
from libclinic.return_converters import return_converters, int_return_converter
from libclinic.block_parser import Block, BlockParser
from libclinic.codegen import BlockPrinter, Destination
from libclinic.dsl_parser import DSLParser
from libclinic.cli import parse_file, Clinic


def _make_clinic(*, filename='clinic_tests', limited_capi=False):
clang = clinic.CLanguage(filename)
c = clinic.Clinic(clang, filename=filename, limited_capi=limited_capi)
c.block_parser = clinic.BlockParser('', clang)
clang = CLanguage(filename)
c = Clinic(clang, filename=filename, limited_capi=limited_capi)
c.block_parser = BlockParser('', clang)
return c


Expand All @@ -47,7 +55,7 @@ def _expect_failure(tc, parser, code, errmsg, *, filename=None, lineno=None,
if strip:
code = code.strip()
errmsg = re.escape(errmsg)
with tc.assertRaisesRegex(clinic.ClinicError, errmsg) as cm:
with tc.assertRaisesRegex(ClinicError, errmsg) as cm:
parser(code)
if filename is not None:
tc.assertEqual(cm.exception.filename, filename)
Expand All @@ -62,12 +70,12 @@ def restore_dict(converters, old_converters):


def save_restore_converters(testcase):
testcase.addCleanup(restore_dict, clinic.converters,
clinic.converters.copy())
testcase.addCleanup(restore_dict, clinic.legacy_converters,
clinic.legacy_converters.copy())
testcase.addCleanup(restore_dict, clinic.return_converters,
clinic.return_converters.copy())
testcase.addCleanup(restore_dict, converters,
converters.copy())
testcase.addCleanup(restore_dict, legacy_converters,
legacy_converters.copy())
testcase.addCleanup(restore_dict, return_converters,
return_converters.copy())


class ClinicWholeFileTest(TestCase):
Expand Down Expand Up @@ -140,11 +148,11 @@ def test_whitespace_before_stop_line(self):
self.expect_failure(raw, err, filename="test.c", lineno=2)

def test_parse_with_body_prefix(self):
clang = clinic.CLanguage(None)
clang = CLanguage(None)
clang.body_prefix = "//"
clang.start_line = "//[{dsl_name} start]"
clang.stop_line = "//[{dsl_name} stop]"
cl = clinic.Clinic(clang, filename="test.c", limited_capi=False)
cl = Clinic(clang, filename="test.c", limited_capi=False)
raw = dedent("""
//[clinic start]
//module test
Expand Down Expand Up @@ -660,8 +668,8 @@ def expect_parsing_failure(
self, *, filename, expected_error, verify=True, output=None
):
errmsg = re.escape(dedent(expected_error).strip())
with self.assertRaisesRegex(clinic.ClinicError, errmsg):
clinic.parse_file(filename, limited_capi=False)
with self.assertRaisesRegex(ClinicError, errmsg):
parse_file(filename, limited_capi=False)

def test_parse_file_no_extension(self) -> None:
self.expect_parsing_failure(
Expand Down Expand Up @@ -782,13 +790,13 @@ def test_multiline_substitution(self):

def test_text_before_block_marker(self):
regex = re.escape("found before '{marker}'")
with self.assertRaisesRegex(clinic.ClinicError, regex):
with self.assertRaisesRegex(ClinicError, regex):
libclinic.linear_format("no text before marker for you! {marker}",
marker="not allowed!")

def test_text_after_block_marker(self):
regex = re.escape("found after '{marker}'")
with self.assertRaisesRegex(clinic.ClinicError, regex):
with self.assertRaisesRegex(ClinicError, regex):
libclinic.linear_format("{marker} no text after marker for you!",
marker="not allowed!")

Expand All @@ -810,10 +818,10 @@ def parse(self, block):

class ClinicBlockParserTest(TestCase):
def _test(self, input, output):
language = clinic.CLanguage(None)
language = CLanguage(None)

blocks = list(clinic.BlockParser(input, language))
writer = clinic.BlockPrinter(language)
blocks = list(BlockParser(input, language))
writer = BlockPrinter(language)
c = _make_clinic()
for block in blocks:
writer.print_block(block, limited_capi=c.limited_capi, header_includes=c.includes)
Expand Down Expand Up @@ -841,8 +849,8 @@ def test_round_trip_2(self):
""")

def _test_clinic(self, input, output):
language = clinic.CLanguage(None)
c = clinic.Clinic(language, filename="file", limited_capi=False)
language = CLanguage(None)
c = Clinic(language, filename="file", limited_capi=False)
c.parsers['inert'] = InertParser(c)
c.parsers['copy'] = CopyParser(c)
computed = c.parse(input)
Expand Down Expand Up @@ -875,16 +883,16 @@ class ClinicParserTest(TestCase):
def parse(self, text):
c = _make_clinic()
parser = DSLParser(c)
block = clinic.Block(text)
block = Block(text)
parser.parse(block)
return block

def parse_function(self, text, signatures_in_block=2, function_index=1):
block = self.parse(text)
s = block.signatures
self.assertEqual(len(s), signatures_in_block)
assert isinstance(s[0], clinic.Module)
assert isinstance(s[function_index], clinic.Function)
assert isinstance(s[0], Module)
assert isinstance(s[function_index], Function)
return s[function_index]

def expect_failure(self, block, err, *,
Expand All @@ -899,7 +907,7 @@ def checkDocstring(self, fn, expected):

def test_trivial(self):
parser = DSLParser(_make_clinic())
block = clinic.Block("""
block = Block("""
module os
os.access
""")
Expand Down Expand Up @@ -1188,7 +1196,7 @@ def test_base_invalid_syntax(self):
Function 'stat' has an invalid parameter declaration:
\s+'invalid syntax: int = 42'
""").strip()
with self.assertRaisesRegex(clinic.ClinicError, err):
with self.assertRaisesRegex(ClinicError, err):
self.parse_function(block)

def test_param_default_invalid_syntax(self):
Expand Down Expand Up @@ -1220,7 +1228,7 @@ def test_return_converter(self):
module os
os.stat -> int
""")
self.assertIsInstance(function.return_converter, clinic.int_return_converter)
self.assertIsInstance(function.return_converter, int_return_converter)

def test_return_converter_invalid_syntax(self):
block = """
Expand Down Expand Up @@ -2036,7 +2044,7 @@ def test_directive(self):
parser = DSLParser(_make_clinic())
parser.flag = False
parser.directives['setflag'] = lambda : setattr(parser, 'flag', True)
block = clinic.Block("setflag")
block = Block("setflag")
parser.parse(block)
self.assertTrue(parser.flag)

Expand Down Expand Up @@ -2301,14 +2309,14 @@ def test_unused_param(self):

def test_scaffolding(self):
# test repr on special values
self.assertEqual(repr(clinic.unspecified), '<Unspecified>')
self.assertEqual(repr(clinic.NULL), '<Null>')
self.assertEqual(repr(unspecified), '<Unspecified>')
self.assertEqual(repr(NULL), '<Null>')

# test that fail fails
with support.captured_stdout() as stdout:
errmsg = 'The igloos are melting'
with self.assertRaisesRegex(clinic.ClinicError, errmsg) as cm:
clinic.fail(errmsg, filename='clown.txt', line_number=69)
with self.assertRaisesRegex(ClinicError, errmsg) as cm:
fail(errmsg, filename='clown.txt', line_number=69)
exc = cm.exception
self.assertEqual(exc.filename, 'clown.txt')
self.assertEqual(exc.lineno, 69)
Expand Down Expand Up @@ -3998,15 +4006,15 @@ def test_suffix_all_lines(self):

class ClinicReprTests(unittest.TestCase):
def test_Block_repr(self):
block = clinic.Block("foo")
block = Block("foo")
expected_repr = "<clinic.Block 'text' input='foo' output=None>"
self.assertEqual(repr(block), expected_repr)

block2 = clinic.Block("bar", "baz", [], "eggs", "spam")
block2 = Block("bar", "baz", [], "eggs", "spam")
expected_repr_2 = "<clinic.Block 'baz' input='bar' output='eggs'>"
self.assertEqual(repr(block2), expected_repr_2)

block3 = clinic.Block(
block3 = Block(
input="longboi_" * 100,
dsl_name="wow_so_long",
signatures=[],
Expand All @@ -4021,47 +4029,47 @@ def test_Block_repr(self):
def test_Destination_repr(self):
c = _make_clinic()

destination = clinic.Destination(
destination = Destination(
"foo", type="file", clinic=c, args=("eggs",)
)
self.assertEqual(
repr(destination), "<clinic.Destination 'foo' type='file' file='eggs'>"
)

destination2 = clinic.Destination("bar", type="buffer", clinic=c)
destination2 = Destination("bar", type="buffer", clinic=c)
self.assertEqual(repr(destination2), "<clinic.Destination 'bar' type='buffer'>")

def test_Module_repr(self):
module = clinic.Module("foo", _make_clinic())
module = Module("foo", _make_clinic())
self.assertRegex(repr(module), r"<clinic.Module 'foo' at \d+>")

def test_Class_repr(self):
cls = clinic.Class("foo", _make_clinic(), None, 'some_typedef', 'some_type_object')
cls = Class("foo", _make_clinic(), None, 'some_typedef', 'some_type_object')
self.assertRegex(repr(cls), r"<clinic.Class 'foo' at \d+>")

def test_FunctionKind_repr(self):
self.assertEqual(
repr(clinic.FunctionKind.INVALID), "<clinic.FunctionKind.INVALID>"
repr(FunctionKind.INVALID), "<clinic.FunctionKind.INVALID>"
)
self.assertEqual(
repr(clinic.FunctionKind.CLASS_METHOD), "<clinic.FunctionKind.CLASS_METHOD>"
repr(FunctionKind.CLASS_METHOD), "<clinic.FunctionKind.CLASS_METHOD>"
)

def test_Function_and_Parameter_reprs(self):
function = clinic.Function(
function = Function(
name='foo',
module=_make_clinic(),
cls=None,
c_basename=None,
full_name='foofoo',
return_converter=clinic.int_return_converter(),
kind=clinic.FunctionKind.METHOD_INIT,
return_converter=int_return_converter(),
kind=FunctionKind.METHOD_INIT,
coexist=False
)
self.assertEqual(repr(function), "<clinic.Function 'foo'>")

converter = clinic.self_converter('bar', 'bar', function)
parameter = clinic.Parameter(
converter = self_converter('bar', 'bar', function)
parameter = Parameter(
"bar",
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
function=function,
Expand Down
Loading
Loading