test_clinic.py 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. # Argument Clinic
  2. # Copyright 2012-2013 by Larry Hastings.
  3. # Licensed to the PSF under a contributor agreement.
  4. from test import support, test_tools
  5. from test.support import import_helper, os_helper
  6. from unittest import TestCase
  7. import collections
  8. import inspect
  9. import os.path
  10. import sys
  11. import unittest
  12. test_tools.skip_if_missing('clinic')
  13. with test_tools.imports_under_tool('clinic'):
  14. import clinic
  15. from clinic import DSLParser
  16. class FakeConverter:
  17. def __init__(self, name, args):
  18. self.name = name
  19. self.args = args
  20. class FakeConverterFactory:
  21. def __init__(self, name):
  22. self.name = name
  23. def __call__(self, name, default, **kwargs):
  24. return FakeConverter(self.name, kwargs)
  25. class FakeConvertersDict:
  26. def __init__(self):
  27. self.used_converters = {}
  28. def get(self, name, default):
  29. return self.used_converters.setdefault(name, FakeConverterFactory(name))
  30. c = clinic.Clinic(language='C', filename = "file")
  31. class FakeClinic:
  32. def __init__(self):
  33. self.converters = FakeConvertersDict()
  34. self.legacy_converters = FakeConvertersDict()
  35. self.language = clinic.CLanguage(None)
  36. self.filename = None
  37. self.destination_buffers = {}
  38. self.block_parser = clinic.BlockParser('', self.language)
  39. self.modules = collections.OrderedDict()
  40. self.classes = collections.OrderedDict()
  41. clinic.clinic = self
  42. self.name = "FakeClinic"
  43. self.line_prefix = self.line_suffix = ''
  44. self.destinations = {}
  45. self.add_destination("block", "buffer")
  46. self.add_destination("file", "buffer")
  47. self.add_destination("suppress", "suppress")
  48. d = self.destinations.get
  49. self.field_destinations = collections.OrderedDict((
  50. ('docstring_prototype', d('suppress')),
  51. ('docstring_definition', d('block')),
  52. ('methoddef_define', d('block')),
  53. ('impl_prototype', d('block')),
  54. ('parser_prototype', d('suppress')),
  55. ('parser_definition', d('block')),
  56. ('impl_definition', d('block')),
  57. ))
  58. def get_destination(self, name):
  59. d = self.destinations.get(name)
  60. if not d:
  61. sys.exit("Destination does not exist: " + repr(name))
  62. return d
  63. def add_destination(self, name, type, *args):
  64. if name in self.destinations:
  65. sys.exit("Destination already exists: " + repr(name))
  66. self.destinations[name] = clinic.Destination(name, type, self, *args)
  67. def is_directive(self, name):
  68. return name == "module"
  69. def directive(self, name, args):
  70. self.called_directives[name] = args
  71. _module_and_class = clinic.Clinic._module_and_class
  72. class ClinicWholeFileTest(TestCase):
  73. def test_eol(self):
  74. # regression test:
  75. # clinic's block parser didn't recognize
  76. # the "end line" for the block if it
  77. # didn't end in "\n" (as in, the last)
  78. # byte of the file was '/'.
  79. # so it would spit out an end line for you.
  80. # and since you really already had one,
  81. # the last line of the block got corrupted.
  82. c = clinic.Clinic(clinic.CLanguage(None), filename="file")
  83. raw = "/*[clinic]\nfoo\n[clinic]*/"
  84. cooked = c.parse(raw).splitlines()
  85. end_line = cooked[2].rstrip()
  86. # this test is redundant, it's just here explicitly to catch
  87. # the regression test so we don't forget what it looked like
  88. self.assertNotEqual(end_line, "[clinic]*/[clinic]*/")
  89. self.assertEqual(end_line, "[clinic]*/")
  90. class ClinicGroupPermuterTest(TestCase):
  91. def _test(self, l, m, r, output):
  92. computed = clinic.permute_optional_groups(l, m, r)
  93. self.assertEqual(output, computed)
  94. def test_range(self):
  95. self._test([['start']], ['stop'], [['step']],
  96. (
  97. ('stop',),
  98. ('start', 'stop',),
  99. ('start', 'stop', 'step',),
  100. ))
  101. def test_add_window(self):
  102. self._test([['x', 'y']], ['ch'], [['attr']],
  103. (
  104. ('ch',),
  105. ('ch', 'attr'),
  106. ('x', 'y', 'ch',),
  107. ('x', 'y', 'ch', 'attr'),
  108. ))
  109. def test_ludicrous(self):
  110. self._test([['a1', 'a2', 'a3'], ['b1', 'b2']], ['c1'], [['d1', 'd2'], ['e1', 'e2', 'e3']],
  111. (
  112. ('c1',),
  113. ('b1', 'b2', 'c1'),
  114. ('b1', 'b2', 'c1', 'd1', 'd2'),
  115. ('a1', 'a2', 'a3', 'b1', 'b2', 'c1'),
  116. ('a1', 'a2', 'a3', 'b1', 'b2', 'c1', 'd1', 'd2'),
  117. ('a1', 'a2', 'a3', 'b1', 'b2', 'c1', 'd1', 'd2', 'e1', 'e2', 'e3'),
  118. ))
  119. def test_right_only(self):
  120. self._test([], [], [['a'],['b'],['c']],
  121. (
  122. (),
  123. ('a',),
  124. ('a', 'b'),
  125. ('a', 'b', 'c')
  126. ))
  127. def test_have_left_options_but_required_is_empty(self):
  128. def fn():
  129. clinic.permute_optional_groups(['a'], [], [])
  130. self.assertRaises(AssertionError, fn)
  131. class ClinicLinearFormatTest(TestCase):
  132. def _test(self, input, output, **kwargs):
  133. computed = clinic.linear_format(input, **kwargs)
  134. self.assertEqual(output, computed)
  135. def test_empty_strings(self):
  136. self._test('', '')
  137. def test_solo_newline(self):
  138. self._test('\n', '\n')
  139. def test_no_substitution(self):
  140. self._test("""
  141. abc
  142. """, """
  143. abc
  144. """)
  145. def test_empty_substitution(self):
  146. self._test("""
  147. abc
  148. {name}
  149. def
  150. """, """
  151. abc
  152. def
  153. """, name='')
  154. def test_single_line_substitution(self):
  155. self._test("""
  156. abc
  157. {name}
  158. def
  159. """, """
  160. abc
  161. GARGLE
  162. def
  163. """, name='GARGLE')
  164. def test_multiline_substitution(self):
  165. self._test("""
  166. abc
  167. {name}
  168. def
  169. """, """
  170. abc
  171. bingle
  172. bungle
  173. def
  174. """, name='bingle\nbungle\n')
  175. class InertParser:
  176. def __init__(self, clinic):
  177. pass
  178. def parse(self, block):
  179. pass
  180. class CopyParser:
  181. def __init__(self, clinic):
  182. pass
  183. def parse(self, block):
  184. block.output = block.input
  185. class ClinicBlockParserTest(TestCase):
  186. def _test(self, input, output):
  187. language = clinic.CLanguage(None)
  188. blocks = list(clinic.BlockParser(input, language))
  189. writer = clinic.BlockPrinter(language)
  190. for block in blocks:
  191. writer.print_block(block)
  192. output = writer.f.getvalue()
  193. assert output == input, "output != input!\n\noutput " + repr(output) + "\n\n input " + repr(input)
  194. def round_trip(self, input):
  195. return self._test(input, input)
  196. def test_round_trip_1(self):
  197. self.round_trip("""
  198. verbatim text here
  199. lah dee dah
  200. """)
  201. def test_round_trip_2(self):
  202. self.round_trip("""
  203. verbatim text here
  204. lah dee dah
  205. /*[inert]
  206. abc
  207. [inert]*/
  208. def
  209. /*[inert checksum: 7b18d017f89f61cf17d47f92749ea6930a3f1deb]*/
  210. xyz
  211. """)
  212. def _test_clinic(self, input, output):
  213. language = clinic.CLanguage(None)
  214. c = clinic.Clinic(language, filename="file")
  215. c.parsers['inert'] = InertParser(c)
  216. c.parsers['copy'] = CopyParser(c)
  217. computed = c.parse(input)
  218. self.assertEqual(output, computed)
  219. def test_clinic_1(self):
  220. self._test_clinic("""
  221. verbatim text here
  222. lah dee dah
  223. /*[copy input]
  224. def
  225. [copy start generated code]*/
  226. abc
  227. /*[copy end generated code: output=03cfd743661f0797 input=7b18d017f89f61cf]*/
  228. xyz
  229. """, """
  230. verbatim text here
  231. lah dee dah
  232. /*[copy input]
  233. def
  234. [copy start generated code]*/
  235. def
  236. /*[copy end generated code: output=7b18d017f89f61cf input=7b18d017f89f61cf]*/
  237. xyz
  238. """)
  239. class ClinicParserTest(TestCase):
  240. def test_trivial(self):
  241. parser = DSLParser(FakeClinic())
  242. block = clinic.Block("module os\nos.access")
  243. parser.parse(block)
  244. module, function = block.signatures
  245. self.assertEqual("access", function.name)
  246. self.assertEqual("os", module.name)
  247. def test_ignore_line(self):
  248. block = self.parse("#\nmodule os\nos.access")
  249. module, function = block.signatures
  250. self.assertEqual("access", function.name)
  251. self.assertEqual("os", module.name)
  252. def test_param(self):
  253. function = self.parse_function("module os\nos.access\n path: int")
  254. self.assertEqual("access", function.name)
  255. self.assertEqual(2, len(function.parameters))
  256. p = function.parameters['path']
  257. self.assertEqual('path', p.name)
  258. self.assertIsInstance(p.converter, clinic.int_converter)
  259. def test_param_default(self):
  260. function = self.parse_function("module os\nos.access\n follow_symlinks: bool = True")
  261. p = function.parameters['follow_symlinks']
  262. self.assertEqual(True, p.default)
  263. def test_param_with_continuations(self):
  264. function = self.parse_function("module os\nos.access\n follow_symlinks: \\\n bool \\\n =\\\n True")
  265. p = function.parameters['follow_symlinks']
  266. self.assertEqual(True, p.default)
  267. def test_param_default_expression(self):
  268. function = self.parse_function("module os\nos.access\n follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize")
  269. p = function.parameters['follow_symlinks']
  270. self.assertEqual(sys.maxsize, p.default)
  271. self.assertEqual("MAXSIZE", p.converter.c_default)
  272. s = self.parse_function_should_fail("module os\nos.access\n follow_symlinks: int = sys.maxsize")
  273. 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")
  274. def test_param_no_docstring(self):
  275. function = self.parse_function("""
  276. module os
  277. os.access
  278. follow_symlinks: bool = True
  279. something_else: str = ''""")
  280. p = function.parameters['follow_symlinks']
  281. self.assertEqual(3, len(function.parameters))
  282. self.assertIsInstance(function.parameters['something_else'].converter, clinic.str_converter)
  283. def test_param_default_parameters_out_of_order(self):
  284. s = self.parse_function_should_fail("""
  285. module os
  286. os.access
  287. follow_symlinks: bool = True
  288. something_else: str""")
  289. self.assertEqual(s, """Error on line 0:
  290. Can't have a parameter without a default ('something_else')
  291. after a parameter with a default!
  292. """)
  293. def disabled_test_converter_arguments(self):
  294. function = self.parse_function("module os\nos.access\n path: path_t(allow_fd=1)")
  295. p = function.parameters['path']
  296. self.assertEqual(1, p.converter.args['allow_fd'])
  297. def test_function_docstring(self):
  298. function = self.parse_function("""
  299. module os
  300. os.stat as os_stat_fn
  301. path: str
  302. Path to be examined
  303. Perform a stat system call on the given path.""")
  304. self.assertEqual("""
  305. stat($module, /, path)
  306. --
  307. Perform a stat system call on the given path.
  308. path
  309. Path to be examined
  310. """.strip(), function.docstring)
  311. def test_explicit_parameters_in_docstring(self):
  312. function = self.parse_function("""
  313. module foo
  314. foo.bar
  315. x: int
  316. Documentation for x.
  317. y: int
  318. This is the documentation for foo.
  319. Okay, we're done here.
  320. """)
  321. self.assertEqual("""
  322. bar($module, /, x, y)
  323. --
  324. This is the documentation for foo.
  325. x
  326. Documentation for x.
  327. Okay, we're done here.
  328. """.strip(), function.docstring)
  329. def test_parser_regression_special_character_in_parameter_column_of_docstring_first_line(self):
  330. function = self.parse_function("""
  331. module os
  332. os.stat
  333. path: str
  334. This/used to break Clinic!
  335. """)
  336. self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring)
  337. def test_c_name(self):
  338. function = self.parse_function("module os\nos.stat as os_stat_fn")
  339. self.assertEqual("os_stat_fn", function.c_basename)
  340. def test_return_converter(self):
  341. function = self.parse_function("module os\nos.stat -> int")
  342. self.assertIsInstance(function.return_converter, clinic.int_return_converter)
  343. def test_star(self):
  344. function = self.parse_function("module os\nos.access\n *\n follow_symlinks: bool = True")
  345. p = function.parameters['follow_symlinks']
  346. self.assertEqual(inspect.Parameter.KEYWORD_ONLY, p.kind)
  347. self.assertEqual(0, p.group)
  348. def test_group(self):
  349. function = self.parse_function("module window\nwindow.border\n [\n ls : int\n ]\n /\n")
  350. p = function.parameters['ls']
  351. self.assertEqual(1, p.group)
  352. def test_left_group(self):
  353. function = self.parse_function("""
  354. module curses
  355. curses.addch
  356. [
  357. y: int
  358. Y-coordinate.
  359. x: int
  360. X-coordinate.
  361. ]
  362. ch: char
  363. Character to add.
  364. [
  365. attr: long
  366. Attributes for the character.
  367. ]
  368. /
  369. """)
  370. for name, group in (
  371. ('y', -1), ('x', -1),
  372. ('ch', 0),
  373. ('attr', 1),
  374. ):
  375. p = function.parameters[name]
  376. self.assertEqual(p.group, group)
  377. self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
  378. self.assertEqual(function.docstring.strip(), """
  379. addch([y, x,] ch, [attr])
  380. y
  381. Y-coordinate.
  382. x
  383. X-coordinate.
  384. ch
  385. Character to add.
  386. attr
  387. Attributes for the character.
  388. """.strip())
  389. def test_nested_groups(self):
  390. function = self.parse_function("""
  391. module curses
  392. curses.imaginary
  393. [
  394. [
  395. y1: int
  396. Y-coordinate.
  397. y2: int
  398. Y-coordinate.
  399. ]
  400. x1: int
  401. X-coordinate.
  402. x2: int
  403. X-coordinate.
  404. ]
  405. ch: char
  406. Character to add.
  407. [
  408. attr1: long
  409. Attributes for the character.
  410. attr2: long
  411. Attributes for the character.
  412. attr3: long
  413. Attributes for the character.
  414. [
  415. attr4: long
  416. Attributes for the character.
  417. attr5: long
  418. Attributes for the character.
  419. attr6: long
  420. Attributes for the character.
  421. ]
  422. ]
  423. /
  424. """)
  425. for name, group in (
  426. ('y1', -2), ('y2', -2),
  427. ('x1', -1), ('x2', -1),
  428. ('ch', 0),
  429. ('attr1', 1), ('attr2', 1), ('attr3', 1),
  430. ('attr4', 2), ('attr5', 2), ('attr6', 2),
  431. ):
  432. p = function.parameters[name]
  433. self.assertEqual(p.group, group)
  434. self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
  435. self.assertEqual(function.docstring.strip(), """
  436. imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5,
  437. attr6]])
  438. y1
  439. Y-coordinate.
  440. y2
  441. Y-coordinate.
  442. x1
  443. X-coordinate.
  444. x2
  445. X-coordinate.
  446. ch
  447. Character to add.
  448. attr1
  449. Attributes for the character.
  450. attr2
  451. Attributes for the character.
  452. attr3
  453. Attributes for the character.
  454. attr4
  455. Attributes for the character.
  456. attr5
  457. Attributes for the character.
  458. attr6
  459. Attributes for the character.
  460. """.strip())
  461. def parse_function_should_fail(self, s):
  462. with support.captured_stdout() as stdout:
  463. with self.assertRaises(SystemExit):
  464. self.parse_function(s)
  465. return stdout.getvalue()
  466. def test_disallowed_grouping__two_top_groups_on_left(self):
  467. s = self.parse_function_should_fail("""
  468. module foo
  469. foo.two_top_groups_on_left
  470. [
  471. group1 : int
  472. ]
  473. [
  474. group2 : int
  475. ]
  476. param: int
  477. """)
  478. self.assertEqual(s,
  479. ('Error on line 0:\n'
  480. 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b)\n'))
  481. def test_disallowed_grouping__two_top_groups_on_right(self):
  482. self.parse_function_should_fail("""
  483. module foo
  484. foo.two_top_groups_on_right
  485. param: int
  486. [
  487. group1 : int
  488. ]
  489. [
  490. group2 : int
  491. ]
  492. """)
  493. def test_disallowed_grouping__parameter_after_group_on_right(self):
  494. self.parse_function_should_fail("""
  495. module foo
  496. foo.parameter_after_group_on_right
  497. param: int
  498. [
  499. [
  500. group1 : int
  501. ]
  502. group2 : int
  503. ]
  504. """)
  505. def test_disallowed_grouping__group_after_parameter_on_left(self):
  506. self.parse_function_should_fail("""
  507. module foo
  508. foo.group_after_parameter_on_left
  509. [
  510. group2 : int
  511. [
  512. group1 : int
  513. ]
  514. ]
  515. param: int
  516. """)
  517. def test_disallowed_grouping__empty_group_on_left(self):
  518. self.parse_function_should_fail("""
  519. module foo
  520. foo.empty_group
  521. [
  522. [
  523. ]
  524. group2 : int
  525. ]
  526. param: int
  527. """)
  528. def test_disallowed_grouping__empty_group_on_right(self):
  529. self.parse_function_should_fail("""
  530. module foo
  531. foo.empty_group
  532. param: int
  533. [
  534. [
  535. ]
  536. group2 : int
  537. ]
  538. """)
  539. def test_no_parameters(self):
  540. function = self.parse_function("""
  541. module foo
  542. foo.bar
  543. Docstring
  544. """)
  545. self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring)
  546. self.assertEqual(1, len(function.parameters)) # self!
  547. def test_init_with_no_parameters(self):
  548. function = self.parse_function("""
  549. module foo
  550. class foo.Bar "unused" "notneeded"
  551. foo.Bar.__init__
  552. Docstring
  553. """, signatures_in_block=3, function_index=2)
  554. # self is not in the signature
  555. self.assertEqual("Bar()\n--\n\nDocstring", function.docstring)
  556. # but it *is* a parameter
  557. self.assertEqual(1, len(function.parameters))
  558. def test_illegal_module_line(self):
  559. self.parse_function_should_fail("""
  560. module foo
  561. foo.bar => int
  562. /
  563. """)
  564. def test_illegal_c_basename(self):
  565. self.parse_function_should_fail("""
  566. module foo
  567. foo.bar as 935
  568. /
  569. """)
  570. def test_single_star(self):
  571. self.parse_function_should_fail("""
  572. module foo
  573. foo.bar
  574. *
  575. *
  576. """)
  577. def test_parameters_required_after_star_without_initial_parameters_or_docstring(self):
  578. self.parse_function_should_fail("""
  579. module foo
  580. foo.bar
  581. *
  582. """)
  583. def test_parameters_required_after_star_without_initial_parameters_with_docstring(self):
  584. self.parse_function_should_fail("""
  585. module foo
  586. foo.bar
  587. *
  588. Docstring here.
  589. """)
  590. def test_parameters_required_after_star_with_initial_parameters_without_docstring(self):
  591. self.parse_function_should_fail("""
  592. module foo
  593. foo.bar
  594. this: int
  595. *
  596. """)
  597. def test_parameters_required_after_star_with_initial_parameters_and_docstring(self):
  598. self.parse_function_should_fail("""
  599. module foo
  600. foo.bar
  601. this: int
  602. *
  603. Docstring.
  604. """)
  605. def test_single_slash(self):
  606. self.parse_function_should_fail("""
  607. module foo
  608. foo.bar
  609. /
  610. /
  611. """)
  612. def test_mix_star_and_slash(self):
  613. self.parse_function_should_fail("""
  614. module foo
  615. foo.bar
  616. x: int
  617. y: int
  618. *
  619. z: int
  620. /
  621. """)
  622. def test_parameters_not_permitted_after_slash_for_now(self):
  623. self.parse_function_should_fail("""
  624. module foo
  625. foo.bar
  626. /
  627. x: int
  628. """)
  629. def test_parameters_no_more_than_one_vararg(self):
  630. s = self.parse_function_should_fail("""
  631. module foo
  632. foo.bar
  633. *vararg1: object
  634. *vararg2: object
  635. """)
  636. self.assertEqual(s, "Error on line 0:\nToo many var args\n")
  637. def test_function_not_at_column_0(self):
  638. function = self.parse_function("""
  639. module foo
  640. foo.bar
  641. x: int
  642. Nested docstring here, goeth.
  643. *
  644. y: str
  645. Not at column 0!
  646. """)
  647. self.assertEqual("""
  648. bar($module, /, x, *, y)
  649. --
  650. Not at column 0!
  651. x
  652. Nested docstring here, goeth.
  653. """.strip(), function.docstring)
  654. def test_directive(self):
  655. c = FakeClinic()
  656. parser = DSLParser(c)
  657. parser.flag = False
  658. parser.directives['setflag'] = lambda : setattr(parser, 'flag', True)
  659. block = clinic.Block("setflag")
  660. parser.parse(block)
  661. self.assertTrue(parser.flag)
  662. def test_legacy_converters(self):
  663. block = self.parse('module os\nos.access\n path: "s"')
  664. module, function = block.signatures
  665. self.assertIsInstance((function.parameters['path']).converter, clinic.str_converter)
  666. def parse(self, text):
  667. c = FakeClinic()
  668. parser = DSLParser(c)
  669. block = clinic.Block(text)
  670. parser.parse(block)
  671. return block
  672. def parse_function(self, text, signatures_in_block=2, function_index=1):
  673. block = self.parse(text)
  674. s = block.signatures
  675. self.assertEqual(len(s), signatures_in_block)
  676. assert isinstance(s[0], clinic.Module)
  677. assert isinstance(s[function_index], clinic.Function)
  678. return s[function_index]
  679. def test_scaffolding(self):
  680. # test repr on special values
  681. self.assertEqual(repr(clinic.unspecified), '<Unspecified>')
  682. self.assertEqual(repr(clinic.NULL), '<Null>')
  683. # test that fail fails
  684. with support.captured_stdout() as stdout:
  685. with self.assertRaises(SystemExit):
  686. clinic.fail('The igloos are melting!', filename='clown.txt', line_number=69)
  687. self.assertEqual(stdout.getvalue(), 'Error in file "clown.txt" on line 69:\nThe igloos are melting!\n')
  688. class ClinicExternalTest(TestCase):
  689. maxDiff = None
  690. def test_external(self):
  691. # bpo-42398: Test that the destination file is left unchanged if the
  692. # content does not change. Moreover, check also that the file
  693. # modification time does not change in this case.
  694. source = support.findfile('clinic.test')
  695. with open(source, 'r', encoding='utf-8') as f:
  696. orig_contents = f.read()
  697. with os_helper.temp_dir() as tmp_dir:
  698. testfile = os.path.join(tmp_dir, 'clinic.test.c')
  699. with open(testfile, 'w', encoding='utf-8') as f:
  700. f.write(orig_contents)
  701. old_mtime_ns = os.stat(testfile).st_mtime_ns
  702. clinic.parse_file(testfile)
  703. with open(testfile, 'r', encoding='utf-8') as f:
  704. new_contents = f.read()
  705. new_mtime_ns = os.stat(testfile).st_mtime_ns
  706. self.assertEqual(new_contents, orig_contents)
  707. # Don't change the file modification time
  708. # if the content does not change
  709. self.assertEqual(new_mtime_ns, old_mtime_ns)
  710. ac_tester = import_helper.import_module('_testclinic')
  711. class ClinicFunctionalTest(unittest.TestCase):
  712. locals().update((name, getattr(ac_tester, name))
  713. for name in dir(ac_tester) if name.startswith('test_'))
  714. def test_objects_converter(self):
  715. with self.assertRaises(TypeError):
  716. ac_tester.objects_converter()
  717. self.assertEqual(ac_tester.objects_converter(1, 2), (1, 2))
  718. self.assertEqual(ac_tester.objects_converter([], 'whatever class'), ([], 'whatever class'))
  719. self.assertEqual(ac_tester.objects_converter(1), (1, None))
  720. def test_bytes_object_converter(self):
  721. with self.assertRaises(TypeError):
  722. ac_tester.bytes_object_converter(1)
  723. self.assertEqual(ac_tester.bytes_object_converter(b'BytesObject'), (b'BytesObject',))
  724. def test_byte_array_object_converter(self):
  725. with self.assertRaises(TypeError):
  726. ac_tester.byte_array_object_converter(1)
  727. byte_arr = bytearray(b'ByteArrayObject')
  728. self.assertEqual(ac_tester.byte_array_object_converter(byte_arr), (byte_arr,))
  729. def test_unicode_converter(self):
  730. with self.assertRaises(TypeError):
  731. ac_tester.unicode_converter(1)
  732. self.assertEqual(ac_tester.unicode_converter('unicode'), ('unicode',))
  733. def test_bool_converter(self):
  734. with self.assertRaises(TypeError):
  735. ac_tester.bool_converter(False, False, 'not a int')
  736. self.assertEqual(ac_tester.bool_converter(), (True, True, True))
  737. self.assertEqual(ac_tester.bool_converter('', [], 5), (False, False, True))
  738. self.assertEqual(ac_tester.bool_converter(('not empty',), {1: 2}, 0), (True, True, False))
  739. def test_char_converter(self):
  740. with self.assertRaises(TypeError):
  741. ac_tester.char_converter(1)
  742. with self.assertRaises(TypeError):
  743. ac_tester.char_converter(b'ab')
  744. chars = [b'A', b'\a', b'\b', b'\t', b'\n', b'\v', b'\f', b'\r', b'"', b"'", b'?', b'\\', b'\000', b'\377']
  745. expected = tuple(ord(c) for c in chars)
  746. self.assertEqual(ac_tester.char_converter(), expected)
  747. chars = [b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'0', b'a', b'b', b'c', b'd']
  748. expected = tuple(ord(c) for c in chars)
  749. self.assertEqual(ac_tester.char_converter(*chars), expected)
  750. def test_unsigned_char_converter(self):
  751. from _testcapi import UCHAR_MAX
  752. with self.assertRaises(OverflowError):
  753. ac_tester.unsigned_char_converter(-1)
  754. with self.assertRaises(OverflowError):
  755. ac_tester.unsigned_char_converter(UCHAR_MAX + 1)
  756. with self.assertRaises(OverflowError):
  757. ac_tester.unsigned_char_converter(0, UCHAR_MAX + 1)
  758. with self.assertRaises(TypeError):
  759. ac_tester.unsigned_char_converter([])
  760. self.assertEqual(ac_tester.unsigned_char_converter(), (12, 34, 56))
  761. self.assertEqual(ac_tester.unsigned_char_converter(0, 0, UCHAR_MAX + 1), (0, 0, 0))
  762. self.assertEqual(ac_tester.unsigned_char_converter(0, 0, (UCHAR_MAX + 1) * 3 + 123), (0, 0, 123))
  763. def test_short_converter(self):
  764. from _testcapi import SHRT_MIN, SHRT_MAX
  765. with self.assertRaises(OverflowError):
  766. ac_tester.short_converter(SHRT_MIN - 1)
  767. with self.assertRaises(OverflowError):
  768. ac_tester.short_converter(SHRT_MAX + 1)
  769. with self.assertRaises(TypeError):
  770. ac_tester.short_converter([])
  771. self.assertEqual(ac_tester.short_converter(-1234), (-1234,))
  772. self.assertEqual(ac_tester.short_converter(4321), (4321,))
  773. def test_unsigned_short_converter(self):
  774. from _testcapi import USHRT_MAX
  775. with self.assertRaises(ValueError):
  776. ac_tester.unsigned_short_converter(-1)
  777. with self.assertRaises(OverflowError):
  778. ac_tester.unsigned_short_converter(USHRT_MAX + 1)
  779. with self.assertRaises(OverflowError):
  780. ac_tester.unsigned_short_converter(0, USHRT_MAX + 1)
  781. with self.assertRaises(TypeError):
  782. ac_tester.unsigned_short_converter([])
  783. self.assertEqual(ac_tester.unsigned_short_converter(), (12, 34, 56))
  784. self.assertEqual(ac_tester.unsigned_short_converter(0, 0, USHRT_MAX + 1), (0, 0, 0))
  785. self.assertEqual(ac_tester.unsigned_short_converter(0, 0, (USHRT_MAX + 1) * 3 + 123), (0, 0, 123))
  786. def test_int_converter(self):
  787. from _testcapi import INT_MIN, INT_MAX
  788. with self.assertRaises(OverflowError):
  789. ac_tester.int_converter(INT_MIN - 1)
  790. with self.assertRaises(OverflowError):
  791. ac_tester.int_converter(INT_MAX + 1)
  792. with self.assertRaises(TypeError):
  793. ac_tester.int_converter(1, 2, 3)
  794. with self.assertRaises(TypeError):
  795. ac_tester.int_converter([])
  796. self.assertEqual(ac_tester.int_converter(), (12, 34, 45))
  797. self.assertEqual(ac_tester.int_converter(1, 2, '3'), (1, 2, ord('3')))
  798. def test_unsigned_int_converter(self):
  799. from _testcapi import UINT_MAX
  800. with self.assertRaises(ValueError):
  801. ac_tester.unsigned_int_converter(-1)
  802. with self.assertRaises(OverflowError):
  803. ac_tester.unsigned_int_converter(UINT_MAX + 1)
  804. with self.assertRaises(OverflowError):
  805. ac_tester.unsigned_int_converter(0, UINT_MAX + 1)
  806. with self.assertRaises(TypeError):
  807. ac_tester.unsigned_int_converter([])
  808. self.assertEqual(ac_tester.unsigned_int_converter(), (12, 34, 56))
  809. self.assertEqual(ac_tester.unsigned_int_converter(0, 0, UINT_MAX + 1), (0, 0, 0))
  810. self.assertEqual(ac_tester.unsigned_int_converter(0, 0, (UINT_MAX + 1) * 3 + 123), (0, 0, 123))
  811. def test_long_converter(self):
  812. from _testcapi import LONG_MIN, LONG_MAX
  813. with self.assertRaises(OverflowError):
  814. ac_tester.long_converter(LONG_MIN - 1)
  815. with self.assertRaises(OverflowError):
  816. ac_tester.long_converter(LONG_MAX + 1)
  817. with self.assertRaises(TypeError):
  818. ac_tester.long_converter([])
  819. self.assertEqual(ac_tester.long_converter(), (12,))
  820. self.assertEqual(ac_tester.long_converter(-1234), (-1234,))
  821. def test_unsigned_long_converter(self):
  822. from _testcapi import ULONG_MAX
  823. with self.assertRaises(ValueError):
  824. ac_tester.unsigned_long_converter(-1)
  825. with self.assertRaises(OverflowError):
  826. ac_tester.unsigned_long_converter(ULONG_MAX + 1)
  827. with self.assertRaises(OverflowError):
  828. ac_tester.unsigned_long_converter(0, ULONG_MAX + 1)
  829. with self.assertRaises(TypeError):
  830. ac_tester.unsigned_long_converter([])
  831. self.assertEqual(ac_tester.unsigned_long_converter(), (12, 34, 56))
  832. self.assertEqual(ac_tester.unsigned_long_converter(0, 0, ULONG_MAX + 1), (0, 0, 0))
  833. self.assertEqual(ac_tester.unsigned_long_converter(0, 0, (ULONG_MAX + 1) * 3 + 123), (0, 0, 123))
  834. def test_long_long_converter(self):
  835. from _testcapi import LLONG_MIN, LLONG_MAX
  836. with self.assertRaises(OverflowError):
  837. ac_tester.long_long_converter(LLONG_MIN - 1)
  838. with self.assertRaises(OverflowError):
  839. ac_tester.long_long_converter(LLONG_MAX + 1)
  840. with self.assertRaises(TypeError):
  841. ac_tester.long_long_converter([])
  842. self.assertEqual(ac_tester.long_long_converter(), (12,))
  843. self.assertEqual(ac_tester.long_long_converter(-1234), (-1234,))
  844. def test_unsigned_long_long_converter(self):
  845. from _testcapi import ULLONG_MAX
  846. with self.assertRaises(ValueError):
  847. ac_tester.unsigned_long_long_converter(-1)
  848. with self.assertRaises(OverflowError):
  849. ac_tester.unsigned_long_long_converter(ULLONG_MAX + 1)
  850. with self.assertRaises(OverflowError):
  851. ac_tester.unsigned_long_long_converter(0, ULLONG_MAX + 1)
  852. with self.assertRaises(TypeError):
  853. ac_tester.unsigned_long_long_converter([])
  854. self.assertEqual(ac_tester.unsigned_long_long_converter(), (12, 34, 56))
  855. self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, ULLONG_MAX + 1), (0, 0, 0))
  856. self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, (ULLONG_MAX + 1) * 3 + 123), (0, 0, 123))
  857. def test_py_ssize_t_converter(self):
  858. from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
  859. with self.assertRaises(OverflowError):
  860. ac_tester.py_ssize_t_converter(PY_SSIZE_T_MIN - 1)
  861. with self.assertRaises(OverflowError):
  862. ac_tester.py_ssize_t_converter(PY_SSIZE_T_MAX + 1)
  863. with self.assertRaises(TypeError):
  864. ac_tester.py_ssize_t_converter([])
  865. self.assertEqual(ac_tester.py_ssize_t_converter(), (12, 34, 56))
  866. self.assertEqual(ac_tester.py_ssize_t_converter(1, 2, None), (1, 2, 56))
  867. def test_slice_index_converter(self):
  868. from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
  869. with self.assertRaises(TypeError):
  870. ac_tester.slice_index_converter([])
  871. self.assertEqual(ac_tester.slice_index_converter(), (12, 34, 56))
  872. self.assertEqual(ac_tester.slice_index_converter(1, 2, None), (1, 2, 56))
  873. self.assertEqual(ac_tester.slice_index_converter(PY_SSIZE_T_MAX, PY_SSIZE_T_MAX + 1, PY_SSIZE_T_MAX + 1234),
  874. (PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX))
  875. self.assertEqual(ac_tester.slice_index_converter(PY_SSIZE_T_MIN, PY_SSIZE_T_MIN - 1, PY_SSIZE_T_MIN - 1234),
  876. (PY_SSIZE_T_MIN, PY_SSIZE_T_MIN, PY_SSIZE_T_MIN))
  877. def test_size_t_converter(self):
  878. with self.assertRaises(ValueError):
  879. ac_tester.size_t_converter(-1)
  880. with self.assertRaises(TypeError):
  881. ac_tester.size_t_converter([])
  882. self.assertEqual(ac_tester.size_t_converter(), (12,))
  883. def test_float_converter(self):
  884. with self.assertRaises(TypeError):
  885. ac_tester.float_converter([])
  886. self.assertEqual(ac_tester.float_converter(), (12.5,))
  887. self.assertEqual(ac_tester.float_converter(-0.5), (-0.5,))
  888. def test_double_converter(self):
  889. with self.assertRaises(TypeError):
  890. ac_tester.double_converter([])
  891. self.assertEqual(ac_tester.double_converter(), (12.5,))
  892. self.assertEqual(ac_tester.double_converter(-0.5), (-0.5,))
  893. def test_py_complex_converter(self):
  894. with self.assertRaises(TypeError):
  895. ac_tester.py_complex_converter([])
  896. self.assertEqual(ac_tester.py_complex_converter(complex(1, 2)), (complex(1, 2),))
  897. self.assertEqual(ac_tester.py_complex_converter(complex('-1-2j')), (complex('-1-2j'),))
  898. self.assertEqual(ac_tester.py_complex_converter(-0.5), (-0.5,))
  899. self.assertEqual(ac_tester.py_complex_converter(10), (10,))
  900. def test_str_converter(self):
  901. with self.assertRaises(TypeError):
  902. ac_tester.str_converter(1)
  903. with self.assertRaises(TypeError):
  904. ac_tester.str_converter('a', 'b', 'c')
  905. with self.assertRaises(ValueError):
  906. ac_tester.str_converter('a', b'b\0b', 'c')
  907. self.assertEqual(ac_tester.str_converter('a', b'b', 'c'), ('a', 'b', 'c'))
  908. self.assertEqual(ac_tester.str_converter('a', b'b', b'c'), ('a', 'b', 'c'))
  909. self.assertEqual(ac_tester.str_converter('a', b'b', 'c\0c'), ('a', 'b', 'c\0c'))
  910. def test_str_converter_encoding(self):
  911. with self.assertRaises(TypeError):
  912. ac_tester.str_converter_encoding(1)
  913. self.assertEqual(ac_tester.str_converter_encoding('a', 'b', 'c'), ('a', 'b', 'c'))
  914. with self.assertRaises(TypeError):
  915. ac_tester.str_converter_encoding('a', b'b\0b', 'c')
  916. self.assertEqual(ac_tester.str_converter_encoding('a', b'b', bytearray([ord('c')])), ('a', 'b', 'c'))
  917. self.assertEqual(ac_tester.str_converter_encoding('a', b'b', bytearray([ord('c'), 0, ord('c')])),
  918. ('a', 'b', 'c\x00c'))
  919. self.assertEqual(ac_tester.str_converter_encoding('a', b'b', b'c\x00c'), ('a', 'b', 'c\x00c'))
  920. def test_py_buffer_converter(self):
  921. with self.assertRaises(TypeError):
  922. ac_tester.py_buffer_converter('a', 'b')
  923. self.assertEqual(ac_tester.py_buffer_converter('abc', bytearray([1, 2, 3])), (b'abc', b'\x01\x02\x03'))
  924. def test_keywords(self):
  925. self.assertEqual(ac_tester.keywords(1, 2), (1, 2))
  926. self.assertEqual(ac_tester.keywords(1, b=2), (1, 2))
  927. self.assertEqual(ac_tester.keywords(a=1, b=2), (1, 2))
  928. def test_keywords_kwonly(self):
  929. with self.assertRaises(TypeError):
  930. ac_tester.keywords_kwonly(1, 2)
  931. self.assertEqual(ac_tester.keywords_kwonly(1, b=2), (1, 2))
  932. self.assertEqual(ac_tester.keywords_kwonly(a=1, b=2), (1, 2))
  933. def test_keywords_opt(self):
  934. self.assertEqual(ac_tester.keywords_opt(1), (1, None, None))
  935. self.assertEqual(ac_tester.keywords_opt(1, 2), (1, 2, None))
  936. self.assertEqual(ac_tester.keywords_opt(1, 2, 3), (1, 2, 3))
  937. self.assertEqual(ac_tester.keywords_opt(1, b=2), (1, 2, None))
  938. self.assertEqual(ac_tester.keywords_opt(1, 2, c=3), (1, 2, 3))
  939. self.assertEqual(ac_tester.keywords_opt(a=1, c=3), (1, None, 3))
  940. self.assertEqual(ac_tester.keywords_opt(a=1, b=2, c=3), (1, 2, 3))
  941. def test_keywords_opt_kwonly(self):
  942. self.assertEqual(ac_tester.keywords_opt_kwonly(1), (1, None, None, None))
  943. self.assertEqual(ac_tester.keywords_opt_kwonly(1, 2), (1, 2, None, None))
  944. with self.assertRaises(TypeError):
  945. ac_tester.keywords_opt_kwonly(1, 2, 3)
  946. self.assertEqual(ac_tester.keywords_opt_kwonly(1, b=2), (1, 2, None, None))
  947. self.assertEqual(ac_tester.keywords_opt_kwonly(1, 2, c=3), (1, 2, 3, None))
  948. self.assertEqual(ac_tester.keywords_opt_kwonly(a=1, c=3), (1, None, 3, None))
  949. self.assertEqual(ac_tester.keywords_opt_kwonly(a=1, b=2, c=3, d=4), (1, 2, 3, 4))
  950. def test_keywords_kwonly_opt(self):
  951. self.assertEqual(ac_tester.keywords_kwonly_opt(1), (1, None, None))
  952. with self.assertRaises(TypeError):
  953. ac_tester.keywords_kwonly_opt(1, 2)
  954. self.assertEqual(ac_tester.keywords_kwonly_opt(1, b=2), (1, 2, None))
  955. self.assertEqual(ac_tester.keywords_kwonly_opt(a=1, c=3), (1, None, 3))
  956. self.assertEqual(ac_tester.keywords_kwonly_opt(a=1, b=2, c=3), (1, 2, 3))
  957. def test_posonly_keywords(self):
  958. with self.assertRaises(TypeError):
  959. ac_tester.posonly_keywords(1)
  960. with self.assertRaises(TypeError):
  961. ac_tester.posonly_keywords(a=1, b=2)
  962. self.assertEqual(ac_tester.posonly_keywords(1, 2), (1, 2))
  963. self.assertEqual(ac_tester.posonly_keywords(1, b=2), (1, 2))
  964. def test_posonly_kwonly(self):
  965. with self.assertRaises(TypeError):
  966. ac_tester.posonly_kwonly(1)
  967. with self.assertRaises(TypeError):
  968. ac_tester.posonly_kwonly(1, 2)
  969. with self.assertRaises(TypeError):
  970. ac_tester.posonly_kwonly(a=1, b=2)
  971. self.assertEqual(ac_tester.posonly_kwonly(1, b=2), (1, 2))
  972. def test_posonly_keywords_kwonly(self):
  973. with self.assertRaises(TypeError):
  974. ac_tester.posonly_keywords_kwonly(1)
  975. with self.assertRaises(TypeError):
  976. ac_tester.posonly_keywords_kwonly(1, 2, 3)
  977. with self.assertRaises(TypeError):
  978. ac_tester.posonly_keywords_kwonly(a=1, b=2, c=3)
  979. self.assertEqual(ac_tester.posonly_keywords_kwonly(1, 2, c=3), (1, 2, 3))
  980. self.assertEqual(ac_tester.posonly_keywords_kwonly(1, b=2, c=3), (1, 2, 3))
  981. def test_posonly_keywords_opt(self):
  982. with self.assertRaises(TypeError):
  983. ac_tester.posonly_keywords_opt(1)
  984. self.assertEqual(ac_tester.posonly_keywords_opt(1, 2), (1, 2, None, None))
  985. self.assertEqual(ac_tester.posonly_keywords_opt(1, 2, 3), (1, 2, 3, None))
  986. self.assertEqual(ac_tester.posonly_keywords_opt(1, 2, 3, 4), (1, 2, 3, 4))
  987. self.assertEqual(ac_tester.posonly_keywords_opt(1, b=2), (1, 2, None, None))
  988. self.assertEqual(ac_tester.posonly_keywords_opt(1, 2, c=3), (1, 2, 3, None))
  989. with self.assertRaises(TypeError):
  990. ac_tester.posonly_keywords_opt(a=1, b=2, c=3, d=4)
  991. self.assertEqual(ac_tester.posonly_keywords_opt(1, b=2, c=3, d=4), (1, 2, 3, 4))
  992. def test_posonly_opt_keywords_opt(self):
  993. self.assertEqual(ac_tester.posonly_opt_keywords_opt(1), (1, None, None, None))
  994. self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2), (1, 2, None, None))
  995. self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, 3), (1, 2, 3, None))
  996. self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, 3, 4), (1, 2, 3, 4))
  997. with self.assertRaises(TypeError):
  998. ac_tester.posonly_opt_keywords_opt(1, b=2)
  999. self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, c=3), (1, 2, 3, None))
  1000. self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, c=3, d=4), (1, 2, 3, 4))
  1001. with self.assertRaises(TypeError):
  1002. ac_tester.posonly_opt_keywords_opt(a=1, b=2, c=3, d=4)
  1003. def test_posonly_kwonly_opt(self):
  1004. with self.assertRaises(TypeError):
  1005. ac_tester.posonly_kwonly_opt(1)
  1006. with self.assertRaises(TypeError):
  1007. ac_tester.posonly_kwonly_opt(1, 2)
  1008. self.assertEqual(ac_tester.posonly_kwonly_opt(1, b=2), (1, 2, None, None))
  1009. self.assertEqual(ac_tester.posonly_kwonly_opt(1, b=2, c=3), (1, 2, 3, None))
  1010. self.assertEqual(ac_tester.posonly_kwonly_opt(1, b=2, c=3, d=4), (1, 2, 3, 4))
  1011. with self.assertRaises(TypeError):
  1012. ac_tester.posonly_kwonly_opt(a=1, b=2, c=3, d=4)
  1013. def test_posonly_opt_kwonly_opt(self):
  1014. self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1), (1, None, None, None))
  1015. self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1, 2), (1, 2, None, None))
  1016. with self.assertRaises(TypeError):
  1017. ac_tester.posonly_opt_kwonly_opt(1, 2, 3)
  1018. with self.assertRaises(TypeError):
  1019. ac_tester.posonly_opt_kwonly_opt(1, b=2)
  1020. self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1, 2, c=3), (1, 2, 3, None))
  1021. self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4))
  1022. def test_posonly_keywords_kwonly_opt(self):
  1023. with self.assertRaises(TypeError):
  1024. ac_tester.posonly_keywords_kwonly_opt(1)
  1025. with self.assertRaises(TypeError):
  1026. ac_tester.posonly_keywords_kwonly_opt(1, 2)
  1027. with self.assertRaises(TypeError):
  1028. ac_tester.posonly_keywords_kwonly_opt(1, b=2)
  1029. with self.assertRaises(TypeError):
  1030. ac_tester.posonly_keywords_kwonly_opt(1, 2, 3)
  1031. with self.assertRaises(TypeError):
  1032. ac_tester.posonly_keywords_kwonly_opt(a=1, b=2, c=3)
  1033. self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, 2, c=3), (1, 2, 3, None, None))
  1034. self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, b=2, c=3), (1, 2, 3, None, None))
  1035. self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4, None))
  1036. self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, 2, c=3, d=4, e=5), (1, 2, 3, 4, 5))
  1037. def test_posonly_keywords_opt_kwonly_opt(self):
  1038. with self.assertRaises(TypeError):
  1039. ac_tester.posonly_keywords_opt_kwonly_opt(1)
  1040. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2), (1, 2, None, None, None))
  1041. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, b=2), (1, 2, None, None, None))
  1042. with self.assertRaises(TypeError):
  1043. ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, 3, 4)
  1044. with self.assertRaises(TypeError):
  1045. ac_tester.posonly_keywords_opt_kwonly_opt(a=1, b=2)
  1046. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, c=3), (1, 2, 3, None, None))
  1047. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, b=2, c=3), (1, 2, 3, None, None))
  1048. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, 3, d=4), (1, 2, 3, 4, None))
  1049. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4, None))
  1050. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, 3, d=4, e=5), (1, 2, 3, 4, 5))
  1051. self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, c=3, d=4, e=5), (1, 2, 3, 4, 5))
  1052. def test_posonly_opt_keywords_opt_kwonly_opt(self):
  1053. self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1), (1, None, None, None))
  1054. self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2), (1, 2, None, None))
  1055. with self.assertRaises(TypeError):
  1056. ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, b=2)
  1057. self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, 3), (1, 2, 3, None))
  1058. self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, c=3), (1, 2, 3, None))
  1059. self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, 3, d=4), (1, 2, 3, 4))
  1060. self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4))
  1061. with self.assertRaises(TypeError):
  1062. ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, 3, 4)
  1063. def test_keyword_only_parameter(self):
  1064. with self.assertRaises(TypeError):
  1065. ac_tester.keyword_only_parameter()
  1066. with self.assertRaises(TypeError):
  1067. ac_tester.keyword_only_parameter(1)
  1068. self.assertEqual(ac_tester.keyword_only_parameter(a=1), (1,))
  1069. def test_posonly_vararg(self):
  1070. with self.assertRaises(TypeError):
  1071. ac_tester.posonly_vararg()
  1072. self.assertEqual(ac_tester.posonly_vararg(1, 2), (1, 2, ()))
  1073. self.assertEqual(ac_tester.posonly_vararg(1, b=2), (1, 2, ()))
  1074. self.assertEqual(ac_tester.posonly_vararg(1, 2, 3, 4), (1, 2, (3, 4)))
  1075. def test_vararg_and_posonly(self):
  1076. with self.assertRaises(TypeError):
  1077. ac_tester.vararg_and_posonly()
  1078. with self.assertRaises(TypeError):
  1079. ac_tester.vararg_and_posonly(1, b=2)
  1080. self.assertEqual(ac_tester.vararg_and_posonly(1, 2, 3, 4), (1, (2, 3, 4)))
  1081. def test_vararg(self):
  1082. with self.assertRaises(TypeError):
  1083. ac_tester.vararg()
  1084. with self.assertRaises(TypeError):
  1085. ac_tester.vararg(1, b=2)
  1086. self.assertEqual(ac_tester.vararg(1, 2, 3, 4), (1, (2, 3, 4)))
  1087. def test_vararg_with_default(self):
  1088. with self.assertRaises(TypeError):
  1089. ac_tester.vararg_with_default()
  1090. self.assertEqual(ac_tester.vararg_with_default(1, b=False), (1, (), False))
  1091. self.assertEqual(ac_tester.vararg_with_default(1, 2, 3, 4), (1, (2, 3, 4), False))
  1092. self.assertEqual(ac_tester.vararg_with_default(1, 2, 3, 4, b=True), (1, (2, 3, 4), True))
  1093. def test_vararg_with_only_defaults(self):
  1094. self.assertEqual(ac_tester.vararg_with_only_defaults(), ((), None))
  1095. self.assertEqual(ac_tester.vararg_with_only_defaults(b=2), ((), 2))
  1096. self.assertEqual(ac_tester.vararg_with_only_defaults(1, b=2), ((1, ), 2))
  1097. self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4), ((1, 2, 3, 4), None))
  1098. self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4, b=5), ((1, 2, 3, 4), 5))
  1099. def test_gh_32092_oob(self):
  1100. ac_tester.gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6)
  1101. def test_gh_32092_kw_pass(self):
  1102. ac_tester.gh_32092_kw_pass(1, 2, 3)
  1103. def test_gh_99233_refcount(self):
  1104. arg = '*A unique string is not referenced by anywhere else.*'
  1105. arg_refcount_origin = sys.getrefcount(arg)
  1106. ac_tester.gh_99233_refcount(arg)
  1107. arg_refcount_after = sys.getrefcount(arg)
  1108. self.assertEqual(arg_refcount_origin, arg_refcount_after)
  1109. def test_gh_99240_double_free(self):
  1110. expected_error = r'gh_99240_double_free\(\) argument 2 must be encoded string without null bytes, not str'
  1111. with self.assertRaisesRegex(TypeError, expected_error):
  1112. ac_tester.gh_99240_double_free('a', '\0b')
  1113. if __name__ == "__main__":
  1114. unittest.main()