2013-10-19 04:09:25 -03:00
# Argument Clinic
# Copyright 2012-2013 by Larry Hastings.
# Licensed to the PSF under a contributor agreement.
2019-09-11 15:49:45 -03:00
from test import support , test_tools
2022-11-21 10:08:45 -04:00
from test . support import import_helper , os_helper
2018-09-03 18:17:20 -03:00
from unittest import TestCase
2013-10-19 04:09:25 -03:00
import collections
import inspect
2018-09-03 18:17:20 -03:00
import os . path
2014-01-16 18:15:03 -04:00
import sys
2013-10-19 04:09:25 -03:00
import unittest
2018-09-03 18:17:20 -03:00
2019-09-11 15:49:45 -03:00
test_tools . skip_if_missing ( ' clinic ' )
with test_tools . imports_under_tool ( ' clinic ' ) :
2018-09-03 18:17:20 -03:00
import clinic
from clinic import DSLParser
2013-10-19 04:09:25 -03:00
2014-02-01 02:03:12 -04:00
2013-10-19 04:09:25 -03:00
class FakeConverter :
def __init__ ( self , name , args ) :
self . name = name
self . args = args
class FakeConverterFactory :
def __init__ ( self , name ) :
self . name = name
def __call__ ( self , name , default , * * kwargs ) :
return FakeConverter ( self . name , kwargs )
class FakeConvertersDict :
def __init__ ( self ) :
self . used_converters = { }
def get ( self , name , default ) :
return self . used_converters . setdefault ( name , FakeConverterFactory ( name ) )
2018-09-03 18:17:20 -03:00
c = clinic . Clinic ( language = ' C ' , filename = " file " )
2014-01-17 21:47:17 -04:00
2013-10-19 04:09:25 -03:00
class FakeClinic :
def __init__ ( self ) :
self . converters = FakeConvertersDict ( )
self . legacy_converters = FakeConvertersDict ( )
2014-02-01 02:03:12 -04:00
self . language = clinic . CLanguage ( None )
2013-10-19 04:09:25 -03:00
self . filename = None
2018-09-03 18:17:20 -03:00
self . destination_buffers = { }
2013-10-19 04:09:25 -03:00
self . block_parser = clinic . BlockParser ( ' ' , self . language )
self . modules = collections . OrderedDict ( )
2014-02-01 02:03:12 -04:00
self . classes = collections . OrderedDict ( )
2013-10-19 04:09:25 -03:00
clinic . clinic = self
self . name = " FakeClinic "
2014-01-17 21:47:17 -04:00
self . line_prefix = self . line_suffix = ' '
self . destinations = { }
self . add_destination ( " block " , " buffer " )
self . add_destination ( " file " , " buffer " )
self . add_destination ( " suppress " , " suppress " )
d = self . destinations . get
self . field_destinations = collections . OrderedDict ( (
( ' docstring_prototype ' , d ( ' suppress ' ) ) ,
( ' docstring_definition ' , d ( ' block ' ) ) ,
( ' methoddef_define ' , d ( ' block ' ) ) ,
( ' impl_prototype ' , d ( ' block ' ) ) ,
( ' parser_prototype ' , d ( ' suppress ' ) ) ,
( ' parser_definition ' , d ( ' block ' ) ) ,
( ' impl_definition ' , d ( ' block ' ) ) ,
) )
def get_destination ( self , name ) :
d = self . destinations . get ( name )
if not d :
sys . exit ( " Destination does not exist: " + repr ( name ) )
return d
def add_destination ( self , name , type , * args ) :
if name in self . destinations :
sys . exit ( " Destination already exists: " + repr ( name ) )
self . destinations [ name ] = clinic . Destination ( name , type , self , * args )
2013-10-19 04:09:25 -03:00
def is_directive ( self , name ) :
return name == " module "
def directive ( self , name , args ) :
self . called_directives [ name ] = args
_module_and_class = clinic . Clinic . _module_and_class
2014-01-07 16:21:08 -04:00
class ClinicWholeFileTest ( TestCase ) :
def test_eol ( self ) :
# regression test:
# clinic's block parser didn't recognize
# the "end line" for the block if it
# didn't end in "\n" (as in, the last)
# byte of the file was '/'.
2016-07-27 22:11:04 -03:00
# so it would spit out an end line for you.
2014-01-07 16:21:08 -04:00
# and since you really already had one,
# the last line of the block got corrupted.
2018-09-03 18:17:20 -03:00
c = clinic . Clinic ( clinic . CLanguage ( None ) , filename = " file " )
2014-01-07 16:21:08 -04:00
raw = " /*[clinic] \n foo \n [clinic]*/ "
2023-05-05 09:38:38 -03:00
cooked , _ = c . parse ( raw )
lines = cooked . splitlines ( )
end_line = lines [ 2 ] . rstrip ( )
2014-01-07 16:21:08 -04:00
# this test is redundant, it's just here explicitly to catch
# the regression test so we don't forget what it looked like
self . assertNotEqual ( end_line , " [clinic]*/[clinic]*/ " )
self . assertEqual ( end_line , " [clinic]*/ " )
2013-10-19 04:09:25 -03:00
class ClinicGroupPermuterTest ( TestCase ) :
def _test ( self , l , m , r , output ) :
computed = clinic . permute_optional_groups ( l , m , r )
self . assertEqual ( output , computed )
def test_range ( self ) :
self . _test ( [ [ ' start ' ] ] , [ ' stop ' ] , [ [ ' step ' ] ] ,
(
( ' stop ' , ) ,
( ' start ' , ' stop ' , ) ,
( ' start ' , ' stop ' , ' step ' , ) ,
) )
def test_add_window ( self ) :
self . _test ( [ [ ' x ' , ' y ' ] ] , [ ' ch ' ] , [ [ ' attr ' ] ] ,
(
( ' ch ' , ) ,
( ' ch ' , ' attr ' ) ,
( ' x ' , ' y ' , ' ch ' , ) ,
( ' x ' , ' y ' , ' ch ' , ' attr ' ) ,
) )
def test_ludicrous ( self ) :
self . _test ( [ [ ' a1 ' , ' a2 ' , ' a3 ' ] , [ ' b1 ' , ' b2 ' ] ] , [ ' c1 ' ] , [ [ ' d1 ' , ' d2 ' ] , [ ' e1 ' , ' e2 ' , ' e3 ' ] ] ,
(
( ' c1 ' , ) ,
( ' b1 ' , ' b2 ' , ' c1 ' ) ,
( ' b1 ' , ' b2 ' , ' c1 ' , ' d1 ' , ' d2 ' ) ,
( ' a1 ' , ' a2 ' , ' a3 ' , ' b1 ' , ' b2 ' , ' c1 ' ) ,
( ' a1 ' , ' a2 ' , ' a3 ' , ' b1 ' , ' b2 ' , ' c1 ' , ' d1 ' , ' d2 ' ) ,
( ' a1 ' , ' a2 ' , ' a3 ' , ' b1 ' , ' b2 ' , ' c1 ' , ' d1 ' , ' d2 ' , ' e1 ' , ' e2 ' , ' e3 ' ) ,
) )
def test_right_only ( self ) :
self . _test ( [ ] , [ ] , [ [ ' a ' ] , [ ' b ' ] , [ ' c ' ] ] ,
(
( ) ,
( ' a ' , ) ,
( ' a ' , ' b ' ) ,
( ' a ' , ' b ' , ' c ' )
) )
def test_have_left_options_but_required_is_empty ( self ) :
def fn ( ) :
clinic . permute_optional_groups ( [ ' a ' ] , [ ] , [ ] )
2022-10-07 18:41:35 -03:00
self . assertRaises ( ValueError , fn )
2013-10-19 04:09:25 -03:00
class ClinicLinearFormatTest ( TestCase ) :
def _test ( self , input , output , * * kwargs ) :
computed = clinic . linear_format ( input , * * kwargs )
self . assertEqual ( output , computed )
def test_empty_strings ( self ) :
self . _test ( ' ' , ' ' )
def test_solo_newline ( self ) :
self . _test ( ' \n ' , ' \n ' )
def test_no_substitution ( self ) :
self . _test ( """
abc
""" , """
abc
""" )
def test_empty_substitution ( self ) :
self . _test ( """
abc
{ name }
def
""" , """
abc
def
""" , name= ' ' )
def test_single_line_substitution ( self ) :
self . _test ( """
abc
{ name }
def
""" , """
abc
GARGLE
def
""" , name= ' GARGLE ' )
def test_multiline_substitution ( self ) :
self . _test ( """
abc
{ name }
def
""" , """
abc
bingle
bungle
def
""" , name= ' bingle \n bungle \n ' )
class InertParser :
def __init__ ( self , clinic ) :
pass
def parse ( self , block ) :
pass
class CopyParser :
def __init__ ( self , clinic ) :
pass
def parse ( self , block ) :
block . output = block . input
class ClinicBlockParserTest ( TestCase ) :
def _test ( self , input , output ) :
2014-02-01 02:03:12 -04:00
language = clinic . CLanguage ( None )
2013-10-19 04:09:25 -03:00
blocks = list ( clinic . BlockParser ( input , language ) )
writer = clinic . BlockPrinter ( language )
for block in blocks :
writer . print_block ( block )
output = writer . f . getvalue ( )
assert output == input , " output != input! \n \n output " + repr ( output ) + " \n \n input " + repr ( input )
def round_trip ( self , input ) :
return self . _test ( input , input )
def test_round_trip_1 ( self ) :
self . round_trip ( """
verbatim text here
lah dee dah
""" )
def test_round_trip_2 ( self ) :
self . round_trip ( """
verbatim text here
lah dee dah
/ * [ inert ]
abc
[ inert ] * /
def
/ * [ inert checksum : 7 b18d017f89f61cf17d47f92749ea6930a3f1deb ] * /
xyz
""" )
def _test_clinic ( self , input , output ) :
2014-02-01 02:03:12 -04:00
language = clinic . CLanguage ( None )
2018-09-03 18:17:20 -03:00
c = clinic . Clinic ( language , filename = " file " )
2013-10-19 04:09:25 -03:00
c . parsers [ ' inert ' ] = InertParser ( c )
c . parsers [ ' copy ' ] = CopyParser ( c )
2023-05-05 09:38:38 -03:00
computed , _ = c . parse ( input )
2013-10-19 04:09:25 -03:00
self . assertEqual ( output , computed )
def test_clinic_1 ( self ) :
self . _test_clinic ( """
verbatim text here
lah dee dah
2014-01-16 15:32:01 -04:00
/ * [ copy input ]
2013-10-19 04:09:25 -03:00
def
2014-01-16 15:32:01 -04:00
[ copy start generated code ] * /
2013-10-19 04:09:25 -03:00
abc
2014-02-01 02:03:12 -04:00
/ * [ copy end generated code : output = 03 cfd743661f0797 input = 7 b18d017f89f61cf ] * /
2013-10-19 04:09:25 -03:00
xyz
""" , """
verbatim text here
lah dee dah
2014-01-16 15:32:01 -04:00
/ * [ copy input ]
2013-10-19 04:09:25 -03:00
def
2014-01-16 15:32:01 -04:00
[ copy start generated code ] * /
2013-10-19 04:09:25 -03:00
def
2014-02-01 02:03:12 -04:00
/ * [ copy end generated code : output = 7 b18d017f89f61cf input = 7 b18d017f89f61cf ] * /
2013-10-19 04:09:25 -03:00
xyz
""" )
class ClinicParserTest ( TestCase ) :
def test_trivial ( self ) :
parser = DSLParser ( FakeClinic ( ) )
block = clinic . Block ( " module os \n 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 ( " # \n module os \n 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 \n os.access \n path: int " )
self . assertEqual ( " access " , function . name )
2014-02-01 02:03:12 -04:00
self . assertEqual ( 2 , len ( function . parameters ) )
2013-10-19 04:09:25 -03:00
p = function . parameters [ ' path ' ]
self . assertEqual ( ' path ' , p . name )
self . assertIsInstance ( p . converter , clinic . int_converter )
def test_param_default ( self ) :
function = self . parse_function ( " module os \n os.access \n follow_symlinks: bool = True " )
p = function . parameters [ ' follow_symlinks ' ]
self . assertEqual ( True , p . default )
2014-01-16 18:15:03 -04:00
def test_param_with_continuations ( self ) :
function = self . parse_function ( " module os \n os.access \n follow_symlinks: \\ \n bool \\ \n = \\ \n True " )
p = function . parameters [ ' follow_symlinks ' ]
self . assertEqual ( True , p . default )
def test_param_default_expression ( self ) :
function = self . parse_function ( " module os \n os.access \n 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 \n os.access \n follow_symlinks: int = sys.maxsize " )
self . assertEqual ( s , " 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 " )
2013-10-19 04:09:25 -03:00
def test_param_no_docstring ( self ) :
function = self . parse_function ( """
module os
os . access
follow_symlinks : bool = True
2014-02-01 02:03:12 -04:00
something_else : str = ' ' """ )
2013-10-19 04:09:25 -03:00
p = function . parameters [ ' follow_symlinks ' ]
2014-02-01 02:03:12 -04:00
self . assertEqual ( 3 , len ( function . parameters ) )
2013-10-19 04:09:25 -03:00
self . assertIsInstance ( function . parameters [ ' something_else ' ] . converter , clinic . str_converter )
2014-02-01 02:03:12 -04:00
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 !
""" )
2013-10-19 04:09:25 -03:00
def disabled_test_converter_arguments ( self ) :
function = self . parse_function ( " module os \n os.access \n 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
path : str
Path to be examined
Perform a stat system call on the given path . """ )
self . assertEqual ( """
2014-02-09 02:15:29 -04:00
stat ( $ module , / , path )
- -
2013-10-19 04:09:25 -03:00
Perform a stat system call on the given path .
path
Path to be examined
""" .strip(), function.docstring)
def test_explicit_parameters_in_docstring ( self ) :
function = self . parse_function ( """
module foo
foo . bar
x : int
Documentation for x .
y : int
This is the documentation for foo .
Okay , we ' re done here.
""" )
self . assertEqual ( """
2014-02-09 02:15:29 -04:00
bar ( $ module , / , x , y )
- -
2013-10-19 04:09:25 -03:00
This is the documentation for foo .
x
Documentation for x .
Okay , we ' re done here.
""" .strip(), function.docstring)
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 !
""" )
2014-02-09 02:15:29 -04:00
self . assertEqual ( " stat($module, /, path) \n -- \n \n This/used to break Clinic! " , function . docstring )
2013-10-19 04:09:25 -03:00
def test_c_name ( self ) :
function = self . parse_function ( " module os \n 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 \n os.stat -> int " )
self . assertIsInstance ( function . return_converter , clinic . int_return_converter )
def test_star ( self ) :
function = self . parse_function ( " module os \n os.access \n * \n 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 \n window.border \n [ \n ls : int \n ] \n / \n " )
p = function . parameters [ ' ls ' ]
self . assertEqual ( 1 , p . group )
def test_left_group ( self ) :
function = self . parse_function ( """
module curses
2014-01-05 06:50:45 -04:00
curses . addch
2013-10-19 04:09:25 -03:00
[
y : int
Y - coordinate .
x : int
X - coordinate .
]
ch : char
Character to add .
[
attr : long
Attributes for the character .
]
/
""" )
for name , group in (
( ' 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 ( ) , """
2014-01-05 06:50:45 -04:00
addch ( [ y , x , ] ch , [ attr ] )
2013-10-19 04:09:25 -03:00
y
Y - coordinate .
x
X - coordinate .
ch
Character to add .
attr
Attributes for the character .
""" .strip())
def test_nested_groups ( self ) :
function = self . parse_function ( """
module curses
2014-01-05 06:50:45 -04:00
curses . imaginary
2013-10-19 04:09:25 -03:00
[
[
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 (
( ' 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 ( ) , """
2014-02-09 02:15:29 -04:00
imaginary ( [ [ y1 , y2 , ] x1 , x2 , ] ch , [ attr1 , attr2 , attr3 , [ attr4 , attr5 ,
attr6 ] ] )
2014-01-05 06:50:45 -04:00
2013-10-19 04:09:25 -03:00
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())
def parse_function_should_fail ( self , s ) :
with support . captured_stdout ( ) as stdout :
with self . assertRaises ( SystemExit ) :
self . parse_function ( 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 '
2014-02-01 02:03:12 -04:00
' Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b) \n ' ) )
2013-10-19 04:09:25 -03:00
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
]
""" )
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
]
""" )
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
""" )
def test_disallowed_grouping__empty_group_on_left ( self ) :
self . parse_function_should_fail ( """
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
]
""" )
def test_no_parameters ( self ) :
function = self . parse_function ( """
module foo
foo . bar
Docstring
""" )
2014-02-09 02:15:29 -04:00
self . assertEqual ( " bar($module, /) \n -- \n \n Docstring " , function . docstring )
2014-02-01 02:03:12 -04:00
self . assertEqual ( 1 , len ( function . parameters ) ) # self!
2013-10-19 04:09:25 -03:00
2014-02-09 02:15:29 -04:00
def test_init_with_no_parameters ( self ) :
function = self . parse_function ( """
module foo
class foo . Bar " unused " " notneeded "
foo . Bar . __init__
Docstring
""" , signatures_in_block=3, function_index=2)
# self is not in the signature
self . assertEqual ( " Bar() \n -- \n \n Docstring " , function . docstring )
# but it *is* a parameter
self . assertEqual ( 1 , len ( function . parameters ) )
2013-10-27 06:49:39 -03:00
def test_illegal_module_line ( self ) :
self . parse_function_should_fail ( """
module foo
foo . bar = > int
/
""" )
def test_illegal_c_basename ( self ) :
self . parse_function_should_fail ( """
module foo
foo . bar as 935
/
""" )
2013-10-19 04:09:25 -03:00
def test_single_star ( self ) :
self . parse_function_should_fail ( """
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
*
""" )
def test_parameters_required_after_star_without_initial_parameters_with_docstring ( self ) :
self . parse_function_should_fail ( """
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
*
""" )
def test_parameters_required_after_star_with_initial_parameters_and_docstring ( self ) :
self . parse_function_should_fail ( """
module foo
foo . bar
this : int
*
Docstring .
""" )
def test_single_slash ( self ) :
self . parse_function_should_fail ( """
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
/
""" )
def test_parameters_not_permitted_after_slash_for_now ( self ) :
self . parse_function_should_fail ( """
module foo
foo . bar
/
x : int
""" )
2022-11-24 15:56:50 -04:00
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: \n Too many var args \n " )
2013-10-19 04:09:25 -03:00
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 ( """
2014-02-09 02:15:29 -04:00
bar ( $ module , / , x , * , y )
- -
2013-10-19 04:09:25 -03:00
Not at column 0 !
x
Nested docstring here , goeth .
""" .strip(), function.docstring)
def test_directive ( self ) :
c = FakeClinic ( )
parser = DSLParser ( c )
parser . flag = False
parser . directives [ ' setflag ' ] = lambda : setattr ( parser , ' flag ' , True )
block = clinic . Block ( " setflag " )
parser . parse ( block )
self . assertTrue ( parser . flag )
def test_legacy_converters ( self ) :
block = self . parse ( ' module os \n os.access \n path: " s " ' )
module , function = block . signatures
self . assertIsInstance ( ( function . parameters [ ' path ' ] ) . converter , clinic . str_converter )
2023-05-21 20:00:47 -03:00
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 \n os.access \n path: 42 ' )
self . assertEqual ( s , expected_failure_message )
s = self . parse_function_should_fail ( ' module os \n os.access \n path: 42.42 ' )
self . assertEqual ( s , expected_failure_message )
s = self . parse_function_should_fail ( ' module os \n os.access \n path: 42j ' )
self . assertEqual ( s , expected_failure_message )
s = self . parse_function_should_fail ( ' module os \n os.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 \n os.access \n path: { " some " : " dictionary " } '
)
self . assertEqual ( s , expected_failure_message )
s = self . parse_function_should_fail (
' module os \n os.access \n path: [ " list " , " of " , " strings " ] '
)
self . assertEqual ( s , expected_failure_message )
s = self . parse_function_should_fail (
' module os \n os.access \n path: (x for x in range(42)) '
)
self . assertEqual ( s , expected_failure_message )
2023-05-12 05:34:00 -03:00
def test_unused_param ( self ) :
block = self . parse ( """
module foo
foo . func
fn : object
k : float
i : float ( unused = True )
/
*
flag : bool ( unused = True ) = False
""" )
sig = block . signatures [ 1 ] # Function index == 1
params = sig . parameters
conv = lambda fn : params [ fn ] . converter
dataset = (
{ " name " : " fn " , " unused " : False } ,
{ " name " : " k " , " unused " : False } ,
{ " name " : " i " , " unused " : True } ,
{ " name " : " flag " , " unused " : True } ,
)
for param in dataset :
name , unused = param . values ( )
with self . subTest ( name = name , unused = unused ) :
p = conv ( name )
# Verify that the unused flag is parsed correctly.
self . assertEqual ( unused , p . unused )
# Now, check that we'll produce correct code.
decl = p . simple_declaration ( in_parser = False )
if unused :
self . assertIn ( " Py_UNUSED " , decl )
else :
self . assertNotIn ( " Py_UNUSED " , decl )
# Make sure the Py_UNUSED macro is not used in the parser body.
parser_decl = p . simple_declaration ( in_parser = True )
self . assertNotIn ( " Py_UNUSED " , parser_decl )
2013-10-19 04:09:25 -03:00
def parse ( self , text ) :
c = FakeClinic ( )
parser = DSLParser ( c )
block = clinic . Block ( text )
parser . parse ( block )
return block
2014-02-09 02:15:29 -04:00
def parse_function ( self , text , signatures_in_block = 2 , function_index = 1 ) :
2013-10-19 04:09:25 -03:00
block = self . parse ( text )
s = block . signatures
2014-02-09 02:15:29 -04:00
self . assertEqual ( len ( s ) , signatures_in_block )
2013-10-19 04:09:25 -03:00
assert isinstance ( s [ 0 ] , clinic . Module )
2014-02-09 02:15:29 -04:00
assert isinstance ( s [ function_index ] , clinic . Function )
return s [ function_index ]
2013-10-19 04:09:25 -03:00
def test_scaffolding ( self ) :
# test repr on special values
self . assertEqual ( repr ( clinic . unspecified ) , ' <Unspecified> ' )
self . assertEqual ( repr ( clinic . NULL ) , ' <Null> ' )
# test that fail fails
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: \n The igloos are melting! \n ' )
2018-12-25 04:17:28 -04:00
class ClinicExternalTest ( TestCase ) :
maxDiff = None
def test_external ( self ) :
2020-11-18 10:36:27 -04:00
# bpo-42398: Test that the destination file is left unchanged if the
# content does not change. Moreover, check also that the file
# modification time does not change in this case.
2018-12-25 04:17:28 -04:00
source = support . findfile ( ' clinic.test ' )
with open ( source , ' r ' , encoding = ' utf-8 ' ) as f :
2020-11-18 10:36:27 -04:00
orig_contents = f . read ( )
with os_helper . temp_dir ( ) as tmp_dir :
testfile = os . path . join ( tmp_dir , ' clinic.test.c ' )
2018-12-25 04:17:28 -04:00
with open ( testfile , ' w ' , encoding = ' utf-8 ' ) as f :
2020-11-18 10:36:27 -04:00
f . write ( orig_contents )
old_mtime_ns = os . stat ( testfile ) . st_mtime_ns
clinic . parse_file ( testfile )
2018-12-25 04:17:28 -04:00
with open ( testfile , ' r ' , encoding = ' utf-8 ' ) as f :
2020-11-18 10:36:27 -04:00
new_contents = f . read ( )
new_mtime_ns = os . stat ( testfile ) . st_mtime_ns
self . assertEqual ( new_contents , orig_contents )
# Don't change the file modification time
# if the content does not change
self . assertEqual ( new_mtime_ns , old_mtime_ns )
2018-12-25 04:17:28 -04:00
2023-05-18 19:56:34 -03:00
try :
import _testclinic as ac_tester
except ImportError :
ac_tester = None
2022-11-21 10:08:45 -04:00
2023-05-18 19:56:34 -03:00
@unittest.skipIf ( ac_tester is None , " _testclinic is missing " )
2022-11-21 10:08:45 -04:00
class ClinicFunctionalTest ( unittest . TestCase ) :
locals ( ) . update ( ( name , getattr ( ac_tester , name ) )
for name in dir ( ac_tester ) if name . startswith ( ' test_ ' ) )
def test_objects_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . objects_converter ( )
self . assertEqual ( ac_tester . objects_converter ( 1 , 2 ) , ( 1 , 2 ) )
self . assertEqual ( ac_tester . objects_converter ( [ ] , ' whatever class ' ) , ( [ ] , ' whatever class ' ) )
self . assertEqual ( ac_tester . objects_converter ( 1 ) , ( 1 , None ) )
def test_bytes_object_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . bytes_object_converter ( 1 )
self . assertEqual ( ac_tester . bytes_object_converter ( b ' BytesObject ' ) , ( b ' BytesObject ' , ) )
def test_byte_array_object_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . byte_array_object_converter ( 1 )
byte_arr = bytearray ( b ' ByteArrayObject ' )
self . assertEqual ( ac_tester . byte_array_object_converter ( byte_arr ) , ( byte_arr , ) )
def test_unicode_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . unicode_converter ( 1 )
self . assertEqual ( ac_tester . unicode_converter ( ' unicode ' ) , ( ' unicode ' , ) )
def test_bool_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . bool_converter ( False , False , ' not a int ' )
self . assertEqual ( ac_tester . bool_converter ( ) , ( True , True , True ) )
self . assertEqual ( ac_tester . bool_converter ( ' ' , [ ] , 5 ) , ( False , False , True ) )
self . assertEqual ( ac_tester . bool_converter ( ( ' not empty ' , ) , { 1 : 2 } , 0 ) , ( True , True , False ) )
def test_char_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . char_converter ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . char_converter ( b ' ab ' )
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 ' ]
expected = tuple ( ord ( c ) for c in chars )
self . assertEqual ( ac_tester . char_converter ( ) , expected )
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 ' ]
expected = tuple ( ord ( c ) for c in chars )
self . assertEqual ( ac_tester . char_converter ( * chars ) , expected )
def test_unsigned_char_converter ( self ) :
from _testcapi import UCHAR_MAX
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_char_converter ( - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_char_converter ( UCHAR_MAX + 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_char_converter ( 0 , UCHAR_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . unsigned_char_converter ( [ ] )
self . assertEqual ( ac_tester . unsigned_char_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . unsigned_char_converter ( 0 , 0 , UCHAR_MAX + 1 ) , ( 0 , 0 , 0 ) )
self . assertEqual ( ac_tester . unsigned_char_converter ( 0 , 0 , ( UCHAR_MAX + 1 ) * 3 + 123 ) , ( 0 , 0 , 123 ) )
def test_short_converter ( self ) :
from _testcapi import SHRT_MIN , SHRT_MAX
with self . assertRaises ( OverflowError ) :
ac_tester . short_converter ( SHRT_MIN - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . short_converter ( SHRT_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . short_converter ( [ ] )
self . assertEqual ( ac_tester . short_converter ( - 1234 ) , ( - 1234 , ) )
self . assertEqual ( ac_tester . short_converter ( 4321 ) , ( 4321 , ) )
def test_unsigned_short_converter ( self ) :
from _testcapi import USHRT_MAX
with self . assertRaises ( ValueError ) :
ac_tester . unsigned_short_converter ( - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_short_converter ( USHRT_MAX + 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_short_converter ( 0 , USHRT_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . unsigned_short_converter ( [ ] )
self . assertEqual ( ac_tester . unsigned_short_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . unsigned_short_converter ( 0 , 0 , USHRT_MAX + 1 ) , ( 0 , 0 , 0 ) )
self . assertEqual ( ac_tester . unsigned_short_converter ( 0 , 0 , ( USHRT_MAX + 1 ) * 3 + 123 ) , ( 0 , 0 , 123 ) )
def test_int_converter ( self ) :
from _testcapi import INT_MIN , INT_MAX
with self . assertRaises ( OverflowError ) :
ac_tester . int_converter ( INT_MIN - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . int_converter ( INT_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . int_converter ( 1 , 2 , 3 )
with self . assertRaises ( TypeError ) :
ac_tester . int_converter ( [ ] )
self . assertEqual ( ac_tester . int_converter ( ) , ( 12 , 34 , 45 ) )
self . assertEqual ( ac_tester . int_converter ( 1 , 2 , ' 3 ' ) , ( 1 , 2 , ord ( ' 3 ' ) ) )
def test_unsigned_int_converter ( self ) :
from _testcapi import UINT_MAX
with self . assertRaises ( ValueError ) :
ac_tester . unsigned_int_converter ( - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_int_converter ( UINT_MAX + 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_int_converter ( 0 , UINT_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . unsigned_int_converter ( [ ] )
self . assertEqual ( ac_tester . unsigned_int_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . unsigned_int_converter ( 0 , 0 , UINT_MAX + 1 ) , ( 0 , 0 , 0 ) )
self . assertEqual ( ac_tester . unsigned_int_converter ( 0 , 0 , ( UINT_MAX + 1 ) * 3 + 123 ) , ( 0 , 0 , 123 ) )
def test_long_converter ( self ) :
from _testcapi import LONG_MIN , LONG_MAX
with self . assertRaises ( OverflowError ) :
ac_tester . long_converter ( LONG_MIN - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . long_converter ( LONG_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . long_converter ( [ ] )
self . assertEqual ( ac_tester . long_converter ( ) , ( 12 , ) )
self . assertEqual ( ac_tester . long_converter ( - 1234 ) , ( - 1234 , ) )
def test_unsigned_long_converter ( self ) :
from _testcapi import ULONG_MAX
with self . assertRaises ( ValueError ) :
ac_tester . unsigned_long_converter ( - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_long_converter ( ULONG_MAX + 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_long_converter ( 0 , ULONG_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . unsigned_long_converter ( [ ] )
self . assertEqual ( ac_tester . unsigned_long_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . unsigned_long_converter ( 0 , 0 , ULONG_MAX + 1 ) , ( 0 , 0 , 0 ) )
self . assertEqual ( ac_tester . unsigned_long_converter ( 0 , 0 , ( ULONG_MAX + 1 ) * 3 + 123 ) , ( 0 , 0 , 123 ) )
def test_long_long_converter ( self ) :
from _testcapi import LLONG_MIN , LLONG_MAX
with self . assertRaises ( OverflowError ) :
ac_tester . long_long_converter ( LLONG_MIN - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . long_long_converter ( LLONG_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . long_long_converter ( [ ] )
self . assertEqual ( ac_tester . long_long_converter ( ) , ( 12 , ) )
self . assertEqual ( ac_tester . long_long_converter ( - 1234 ) , ( - 1234 , ) )
def test_unsigned_long_long_converter ( self ) :
from _testcapi import ULLONG_MAX
with self . assertRaises ( ValueError ) :
ac_tester . unsigned_long_long_converter ( - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_long_long_converter ( ULLONG_MAX + 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . unsigned_long_long_converter ( 0 , ULLONG_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . unsigned_long_long_converter ( [ ] )
self . assertEqual ( ac_tester . unsigned_long_long_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . unsigned_long_long_converter ( 0 , 0 , ULLONG_MAX + 1 ) , ( 0 , 0 , 0 ) )
self . assertEqual ( ac_tester . unsigned_long_long_converter ( 0 , 0 , ( ULLONG_MAX + 1 ) * 3 + 123 ) , ( 0 , 0 , 123 ) )
def test_py_ssize_t_converter ( self ) :
from _testcapi import PY_SSIZE_T_MIN , PY_SSIZE_T_MAX
with self . assertRaises ( OverflowError ) :
ac_tester . py_ssize_t_converter ( PY_SSIZE_T_MIN - 1 )
with self . assertRaises ( OverflowError ) :
ac_tester . py_ssize_t_converter ( PY_SSIZE_T_MAX + 1 )
with self . assertRaises ( TypeError ) :
ac_tester . py_ssize_t_converter ( [ ] )
self . assertEqual ( ac_tester . py_ssize_t_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . py_ssize_t_converter ( 1 , 2 , None ) , ( 1 , 2 , 56 ) )
def test_slice_index_converter ( self ) :
from _testcapi import PY_SSIZE_T_MIN , PY_SSIZE_T_MAX
with self . assertRaises ( TypeError ) :
ac_tester . slice_index_converter ( [ ] )
self . assertEqual ( ac_tester . slice_index_converter ( ) , ( 12 , 34 , 56 ) )
self . assertEqual ( ac_tester . slice_index_converter ( 1 , 2 , None ) , ( 1 , 2 , 56 ) )
self . assertEqual ( ac_tester . slice_index_converter ( PY_SSIZE_T_MAX , PY_SSIZE_T_MAX + 1 , PY_SSIZE_T_MAX + 1234 ) ,
( PY_SSIZE_T_MAX , PY_SSIZE_T_MAX , PY_SSIZE_T_MAX ) )
self . assertEqual ( ac_tester . slice_index_converter ( PY_SSIZE_T_MIN , PY_SSIZE_T_MIN - 1 , PY_SSIZE_T_MIN - 1234 ) ,
( PY_SSIZE_T_MIN , PY_SSIZE_T_MIN , PY_SSIZE_T_MIN ) )
def test_size_t_converter ( self ) :
with self . assertRaises ( ValueError ) :
ac_tester . size_t_converter ( - 1 )
with self . assertRaises ( TypeError ) :
ac_tester . size_t_converter ( [ ] )
self . assertEqual ( ac_tester . size_t_converter ( ) , ( 12 , ) )
def test_float_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . float_converter ( [ ] )
self . assertEqual ( ac_tester . float_converter ( ) , ( 12.5 , ) )
self . assertEqual ( ac_tester . float_converter ( - 0.5 ) , ( - 0.5 , ) )
def test_double_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . double_converter ( [ ] )
self . assertEqual ( ac_tester . double_converter ( ) , ( 12.5 , ) )
self . assertEqual ( ac_tester . double_converter ( - 0.5 ) , ( - 0.5 , ) )
def test_py_complex_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . py_complex_converter ( [ ] )
self . assertEqual ( ac_tester . py_complex_converter ( complex ( 1 , 2 ) ) , ( complex ( 1 , 2 ) , ) )
self . assertEqual ( ac_tester . py_complex_converter ( complex ( ' -1-2j ' ) ) , ( complex ( ' -1-2j ' ) , ) )
self . assertEqual ( ac_tester . py_complex_converter ( - 0.5 ) , ( - 0.5 , ) )
self . assertEqual ( ac_tester . py_complex_converter ( 10 ) , ( 10 , ) )
def test_str_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . str_converter ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . str_converter ( ' a ' , ' b ' , ' c ' )
with self . assertRaises ( ValueError ) :
ac_tester . str_converter ( ' a ' , b ' b \0 b ' , ' c ' )
self . assertEqual ( ac_tester . str_converter ( ' a ' , b ' b ' , ' c ' ) , ( ' a ' , ' b ' , ' c ' ) )
self . assertEqual ( ac_tester . str_converter ( ' a ' , b ' b ' , b ' c ' ) , ( ' a ' , ' b ' , ' c ' ) )
self . assertEqual ( ac_tester . str_converter ( ' a ' , b ' b ' , ' c \0 c ' ) , ( ' a ' , ' b ' , ' c \0 c ' ) )
2022-11-24 10:01:26 -04:00
def test_str_converter_encoding ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . str_converter_encoding ( 1 )
self . assertEqual ( ac_tester . str_converter_encoding ( ' a ' , ' b ' , ' c ' ) , ( ' a ' , ' b ' , ' c ' ) )
with self . assertRaises ( TypeError ) :
ac_tester . str_converter_encoding ( ' a ' , b ' b \0 b ' , ' c ' )
self . assertEqual ( ac_tester . str_converter_encoding ( ' a ' , b ' b ' , bytearray ( [ ord ( ' c ' ) ] ) ) , ( ' a ' , ' b ' , ' c ' ) )
self . assertEqual ( ac_tester . str_converter_encoding ( ' a ' , b ' b ' , bytearray ( [ ord ( ' c ' ) , 0 , ord ( ' c ' ) ] ) ) ,
( ' a ' , ' b ' , ' c \x00 c ' ) )
self . assertEqual ( ac_tester . str_converter_encoding ( ' a ' , b ' b ' , b ' c \x00 c ' ) , ( ' a ' , ' b ' , ' c \x00 c ' ) )
2022-11-21 10:08:45 -04:00
def test_py_buffer_converter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . py_buffer_converter ( ' a ' , ' b ' )
self . assertEqual ( ac_tester . py_buffer_converter ( ' abc ' , bytearray ( [ 1 , 2 , 3 ] ) ) , ( b ' abc ' , b ' \x01 \x02 \x03 ' ) )
def test_keywords ( self ) :
self . assertEqual ( ac_tester . keywords ( 1 , 2 ) , ( 1 , 2 ) )
self . assertEqual ( ac_tester . keywords ( 1 , b = 2 ) , ( 1 , 2 ) )
self . assertEqual ( ac_tester . keywords ( a = 1 , b = 2 ) , ( 1 , 2 ) )
def test_keywords_kwonly ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . keywords_kwonly ( 1 , 2 )
self . assertEqual ( ac_tester . keywords_kwonly ( 1 , b = 2 ) , ( 1 , 2 ) )
self . assertEqual ( ac_tester . keywords_kwonly ( a = 1 , b = 2 ) , ( 1 , 2 ) )
def test_keywords_opt ( self ) :
self . assertEqual ( ac_tester . keywords_opt ( 1 ) , ( 1 , None , None ) )
self . assertEqual ( ac_tester . keywords_opt ( 1 , 2 ) , ( 1 , 2 , None ) )
self . assertEqual ( ac_tester . keywords_opt ( 1 , 2 , 3 ) , ( 1 , 2 , 3 ) )
self . assertEqual ( ac_tester . keywords_opt ( 1 , b = 2 ) , ( 1 , 2 , None ) )
self . assertEqual ( ac_tester . keywords_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 ) )
self . assertEqual ( ac_tester . keywords_opt ( a = 1 , c = 3 ) , ( 1 , None , 3 ) )
self . assertEqual ( ac_tester . keywords_opt ( a = 1 , b = 2 , c = 3 ) , ( 1 , 2 , 3 ) )
def test_keywords_opt_kwonly ( self ) :
self . assertEqual ( ac_tester . keywords_opt_kwonly ( 1 ) , ( 1 , None , None , None ) )
self . assertEqual ( ac_tester . keywords_opt_kwonly ( 1 , 2 ) , ( 1 , 2 , None , None ) )
with self . assertRaises ( TypeError ) :
ac_tester . keywords_opt_kwonly ( 1 , 2 , 3 )
self . assertEqual ( ac_tester . keywords_opt_kwonly ( 1 , b = 2 ) , ( 1 , 2 , None , None ) )
self . assertEqual ( ac_tester . keywords_opt_kwonly ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . keywords_opt_kwonly ( a = 1 , c = 3 ) , ( 1 , None , 3 , None ) )
self . assertEqual ( ac_tester . keywords_opt_kwonly ( a = 1 , b = 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
def test_keywords_kwonly_opt ( self ) :
self . assertEqual ( ac_tester . keywords_kwonly_opt ( 1 ) , ( 1 , None , None ) )
with self . assertRaises ( TypeError ) :
ac_tester . keywords_kwonly_opt ( 1 , 2 )
self . assertEqual ( ac_tester . keywords_kwonly_opt ( 1 , b = 2 ) , ( 1 , 2 , None ) )
self . assertEqual ( ac_tester . keywords_kwonly_opt ( a = 1 , c = 3 ) , ( 1 , None , 3 ) )
self . assertEqual ( ac_tester . keywords_kwonly_opt ( a = 1 , b = 2 , c = 3 ) , ( 1 , 2 , 3 ) )
def test_posonly_keywords ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords ( a = 1 , b = 2 )
self . assertEqual ( ac_tester . posonly_keywords ( 1 , 2 ) , ( 1 , 2 ) )
self . assertEqual ( ac_tester . posonly_keywords ( 1 , b = 2 ) , ( 1 , 2 ) )
def test_posonly_kwonly ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_kwonly ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_kwonly ( 1 , 2 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_kwonly ( a = 1 , b = 2 )
self . assertEqual ( ac_tester . posonly_kwonly ( 1 , b = 2 ) , ( 1 , 2 ) )
def test_posonly_keywords_kwonly ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly ( 1 , 2 , 3 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly ( a = 1 , b = 2 , c = 3 )
self . assertEqual ( ac_tester . posonly_keywords_kwonly ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 ) )
self . assertEqual ( ac_tester . posonly_keywords_kwonly ( 1 , b = 2 , c = 3 ) , ( 1 , 2 , 3 ) )
def test_posonly_keywords_opt ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_opt ( 1 )
self . assertEqual ( ac_tester . posonly_keywords_opt ( 1 , 2 ) , ( 1 , 2 , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt ( 1 , 2 , 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt ( 1 , 2 , 3 , 4 ) , ( 1 , 2 , 3 , 4 ) )
self . assertEqual ( ac_tester . posonly_keywords_opt ( 1 , b = 2 ) , ( 1 , 2 , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_opt ( a = 1 , b = 2 , c = 3 , d = 4 )
self . assertEqual ( ac_tester . posonly_keywords_opt ( 1 , b = 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
def test_posonly_opt_keywords_opt ( self ) :
self . assertEqual ( ac_tester . posonly_opt_keywords_opt ( 1 ) , ( 1 , None , None , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt ( 1 , 2 ) , ( 1 , 2 , None , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt ( 1 , 2 , 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt ( 1 , 2 , 3 , 4 ) , ( 1 , 2 , 3 , 4 ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_opt_keywords_opt ( 1 , b = 2 )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt ( 1 , 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_opt_keywords_opt ( a = 1 , b = 2 , c = 3 , d = 4 )
def test_posonly_kwonly_opt ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_kwonly_opt ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_kwonly_opt ( 1 , 2 )
self . assertEqual ( ac_tester . posonly_kwonly_opt ( 1 , b = 2 ) , ( 1 , 2 , None , None ) )
self . assertEqual ( ac_tester . posonly_kwonly_opt ( 1 , b = 2 , c = 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_kwonly_opt ( 1 , b = 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_kwonly_opt ( a = 1 , b = 2 , c = 3 , d = 4 )
def test_posonly_opt_kwonly_opt ( self ) :
self . assertEqual ( ac_tester . posonly_opt_kwonly_opt ( 1 ) , ( 1 , None , None , None ) )
self . assertEqual ( ac_tester . posonly_opt_kwonly_opt ( 1 , 2 ) , ( 1 , 2 , None , None ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_opt_kwonly_opt ( 1 , 2 , 3 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_opt_kwonly_opt ( 1 , b = 2 )
self . assertEqual ( ac_tester . posonly_opt_kwonly_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_opt_kwonly_opt ( 1 , 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
def test_posonly_keywords_kwonly_opt ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly_opt ( 1 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly_opt ( 1 , 2 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly_opt ( 1 , b = 2 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly_opt ( 1 , 2 , 3 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_kwonly_opt ( a = 1 , b = 2 , c = 3 )
self . assertEqual ( ac_tester . posonly_keywords_kwonly_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_kwonly_opt ( 1 , b = 2 , c = 3 ) , ( 1 , 2 , 3 , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_kwonly_opt ( 1 , 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 , None ) )
self . assertEqual ( ac_tester . posonly_keywords_kwonly_opt ( 1 , 2 , c = 3 , d = 4 , e = 5 ) , ( 1 , 2 , 3 , 4 , 5 ) )
def test_posonly_keywords_opt_kwonly_opt ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_opt_kwonly_opt ( 1 )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 ) , ( 1 , 2 , None , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , b = 2 ) , ( 1 , 2 , None , None , None ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 , 3 , 4 )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_keywords_opt_kwonly_opt ( a = 1 , b = 2 )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , b = 2 , c = 3 ) , ( 1 , 2 , 3 , None , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 , 3 , d = 4 ) , ( 1 , 2 , 3 , 4 , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 , None ) )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 , 3 , d = 4 , e = 5 ) , ( 1 , 2 , 3 , 4 , 5 ) )
self . assertEqual ( ac_tester . posonly_keywords_opt_kwonly_opt ( 1 , 2 , c = 3 , d = 4 , e = 5 ) , ( 1 , 2 , 3 , 4 , 5 ) )
def test_posonly_opt_keywords_opt_kwonly_opt ( self ) :
self . assertEqual ( ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 ) , ( 1 , None , None , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , 2 ) , ( 1 , 2 , None , None ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , b = 2 )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , 2 , 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , 2 , c = 3 ) , ( 1 , 2 , 3 , None ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , 2 , 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
self . assertEqual ( ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , 2 , c = 3 , d = 4 ) , ( 1 , 2 , 3 , 4 ) )
with self . assertRaises ( TypeError ) :
ac_tester . posonly_opt_keywords_opt_kwonly_opt ( 1 , 2 , 3 , 4 )
def test_keyword_only_parameter ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . keyword_only_parameter ( )
with self . assertRaises ( TypeError ) :
ac_tester . keyword_only_parameter ( 1 )
self . assertEqual ( ac_tester . keyword_only_parameter ( a = 1 ) , ( 1 , ) )
2022-11-24 15:56:50 -04:00
def test_posonly_vararg ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . posonly_vararg ( )
self . assertEqual ( ac_tester . posonly_vararg ( 1 , 2 ) , ( 1 , 2 , ( ) ) )
self . assertEqual ( ac_tester . posonly_vararg ( 1 , b = 2 ) , ( 1 , 2 , ( ) ) )
self . assertEqual ( ac_tester . posonly_vararg ( 1 , 2 , 3 , 4 ) , ( 1 , 2 , ( 3 , 4 ) ) )
2022-11-24 08:24:18 -04:00
def test_vararg_and_posonly ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . vararg_and_posonly ( )
with self . assertRaises ( TypeError ) :
ac_tester . vararg_and_posonly ( 1 , b = 2 )
self . assertEqual ( ac_tester . vararg_and_posonly ( 1 , 2 , 3 , 4 ) , ( 1 , ( 2 , 3 , 4 ) ) )
2022-11-24 15:56:50 -04:00
def test_vararg ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . vararg ( )
with self . assertRaises ( TypeError ) :
ac_tester . vararg ( 1 , b = 2 )
self . assertEqual ( ac_tester . vararg ( 1 , 2 , 3 , 4 ) , ( 1 , ( 2 , 3 , 4 ) ) )
def test_vararg_with_default ( self ) :
with self . assertRaises ( TypeError ) :
ac_tester . vararg_with_default ( )
self . assertEqual ( ac_tester . vararg_with_default ( 1 , b = False ) , ( 1 , ( ) , False ) )
self . assertEqual ( ac_tester . vararg_with_default ( 1 , 2 , 3 , 4 ) , ( 1 , ( 2 , 3 , 4 ) , False ) )
self . assertEqual ( ac_tester . vararg_with_default ( 1 , 2 , 3 , 4 , b = True ) , ( 1 , ( 2 , 3 , 4 ) , True ) )
def test_vararg_with_only_defaults ( self ) :
self . assertEqual ( ac_tester . vararg_with_only_defaults ( ) , ( ( ) , None ) )
self . assertEqual ( ac_tester . vararg_with_only_defaults ( b = 2 ) , ( ( ) , 2 ) )
self . assertEqual ( ac_tester . vararg_with_only_defaults ( 1 , b = 2 ) , ( ( 1 , ) , 2 ) )
self . assertEqual ( ac_tester . vararg_with_only_defaults ( 1 , 2 , 3 , 4 ) , ( ( 1 , 2 , 3 , 4 ) , None ) )
self . assertEqual ( ac_tester . vararg_with_only_defaults ( 1 , 2 , 3 , 4 , b = 5 ) , ( ( 1 , 2 , 3 , 4 ) , 5 ) )
def test_gh_32092_oob ( self ) :
ac_tester . gh_32092_oob ( 1 , 2 , 3 , 4 , kw1 = 5 , kw2 = 6 )
def test_gh_32092_kw_pass ( self ) :
ac_tester . gh_32092_kw_pass ( 1 , 2 , 3 )
2022-11-24 08:24:18 -04:00
def test_gh_99233_refcount ( self ) :
arg = ' *A unique string is not referenced by anywhere else.* '
arg_refcount_origin = sys . getrefcount ( arg )
ac_tester . gh_99233_refcount ( arg )
arg_refcount_after = sys . getrefcount ( arg )
self . assertEqual ( arg_refcount_origin , arg_refcount_after )
2022-11-24 10:01:26 -04:00
def test_gh_99240_double_free ( self ) :
expected_error = r ' gh_99240_double_free \ ( \ ) argument 2 must be encoded string without null bytes, not str '
with self . assertRaisesRegex ( TypeError , expected_error ) :
ac_tester . gh_99240_double_free ( ' a ' , ' \0 b ' )
2022-11-21 10:08:45 -04:00
2023-05-05 09:08:24 -03:00
def test_cloned_func_exception_message ( self ) :
incorrect_arg = - 1 # f1() and f2() accept a single str
with self . assertRaisesRegex ( TypeError , " clone_f1 " ) :
ac_tester . clone_f1 ( incorrect_arg )
with self . assertRaisesRegex ( TypeError , " clone_f2 " ) :
ac_tester . clone_f2 ( incorrect_arg )
def test_cloned_func_with_converter_exception_message ( self ) :
for name in " clone_with_conv_f1 " , " clone_with_conv_f2 " :
with self . subTest ( name = name ) :
func = getattr ( ac_tester , name )
self . assertEqual ( func ( ) , name )
2022-11-24 15:56:50 -04:00
2013-10-19 04:09:25 -03:00
if __name__ == " __main__ " :
unittest . main ( )