unit tests for the positional only argument syntax specified in pep 570 import dis import pickle import unittest from test support import checksyntaxerror def globalposonlyfa b return a b def globalposonlyandnormala b return a b def globalposonlydefaultsa1 b2 return a b class positionalonlytestcaseunittest testcase def assertraisessyntaxerrorself codestr regexinvalid syntax with self assertraisesregexsyntaxerror regex compilecodestr n test single def testinvalidsyntaxerrorsself checksyntaxerrorself def fa b 5 c pass parameter without a default follows parameter with a default checksyntaxerrorself def fa 5 b c pass parameter without a default follows parameter with a default checksyntaxerrorself def fa 5 b1 c d2 pass parameter without a default follows parameter with a default checksyntaxerrorself def fa 5 b pass parameter without a default follows parameter with a default checksyntaxerrorself def fa b 5 c pass parameter without a default follows parameter with a default checksyntaxerrorself def fargs pass checksyntaxerrorself def fargs a pass checksyntaxerrorself def fkwargs pass checksyntaxerrorself def f a 1 pass checksyntaxerrorself def f a pass checksyntaxerrorself def f pass checksyntaxerrorself def f a pass checksyntaxerrorself def f a pass checksyntaxerrorself def fa a pass duplicate argument a in function definition checksyntaxerrorself def fa a pass duplicate argument a in function definition checksyntaxerrorself def fa b2 c pass checksyntaxerrorself def fa c pass checksyntaxerrorself def fa c d pass checksyntaxerrorself def fa c d e pass checksyntaxerrorself def fa c d e pass def testinvalidsyntaxerrorsasyncself checksyntaxerrorself async def fa b 5 c pass parameter without a default follows parameter with a default checksyntaxerrorself async def fa 5 b c pass parameter without a default follows parameter with a default checksyntaxerrorself async def fa 5 b1 c d2 pass parameter without a default follows parameter with a default checksyntaxerrorself async def fa 5 b pass parameter without a default follows parameter with a default checksyntaxerrorself async def fa b 5 c pass parameter without a default follows parameter with a default checksyntaxerrorself async def fargs pass checksyntaxerrorself async def fargs a pass checksyntaxerrorself async def fkwargs pass checksyntaxerrorself async def f a 1 pass checksyntaxerrorself async def f a pass checksyntaxerrorself async def f pass checksyntaxerrorself async def f a pass checksyntaxerrorself async def f a pass checksyntaxerrorself async def fa a pass duplicate argument a in function definition checksyntaxerrorself async def fa a pass duplicate argument a in function definition checksyntaxerrorself async def fa b2 c pass checksyntaxerrorself async def fa c pass checksyntaxerrorself async def fa c d pass checksyntaxerrorself async def fa c d e pass checksyntaxerrorself async def fa c d e pass def testoptionalpositionalonlyargsself def fa b10 c100 return a b c self assertequalf1 2 3 6 self assertequalf1 2 c3 6 with self assertraisesregextypeerror rf got some positionalonly arguments passed as keyword arguments b f1 b2 c3 self assertequalf1 2 103 with self assertraisesregextypeerror rf got some positionalonly arguments passed as keyword arguments b f1 b2 self assertequalf1 c2 13 def fa1 b10 c100 return a b c self assertequalf1 2 3 6 self assertequalf1 2 c3 6 with self assertraisesregextypeerror rf got some positionalonly arguments passed as keyword arguments b f1 b2 c3 self assertequalf1 2 103 with self assertraisesregextypeerror rf got some positionalonly arguments passed as keyword arguments b f1 b2 self assertequalf1 c2 13 def testsyntaxformanypositionalonlyself more than 255 positional only arguments should compile ok fundef def fs n passn join id i for i in range300 compilefundef test single def testposonlydefinitionself def fa b c d e1 f g2 pass self assertequal5 f code coargcount 3 posonly 2 standard args self assertequal3 f code coposonlyargcount self assertequal1 f defaults def fa b c1 d2 e3 f g4 pass self assertequal5 f code coargcount 3 posonly 2 standard args self assertequal3 f code coposonlyargcount self assertequal1 2 3 f defaults def testposonlycallviaunpackingself def fa b return a b self assertequalf1 2 3 def testusepositionalaskeywordself def fa pass expected rf got some positionalonly arguments passed as keyword arguments a with self assertraisesregextypeerror expected fa1 def fa b pass expected rf got some positionalonly arguments passed as keyword arguments a with self assertraisesregextypeerror expected fa1 b2 def fa b pass expected rf got some positionalonly arguments passed as keyword arguments a b with self assertraisesregextypeerror expected fa1 b2 def testpositionalonlyandarginvalidcallsself def fa b c pass with self assertraisesregextypeerror rf missing 1 required positional argument c f1 2 with self assertraisesregextypeerror rf missing 2 required positional arguments b and c f1 with self assertraisesregextypeerror rf missing 3 required positional arguments a b and c f with self assertraisesregextypeerror rf takes 3 positional arguments but 4 were given f1 2 3 4 def testpositionalonlyandoptionalarginvalidcallsself def fa b c3 pass f1 2 does not raise with self assertraisesregextypeerror rf missing 1 required positional argument b f1 with self assertraisesregextypeerror rf missing 2 required positional arguments a and b f with self assertraisesregextypeerror rf takes from 2 to 3 positional arguments but 4 were given f1 2 3 4 def testpositionalonlyandkwonlyargsinvalidcallsself def fa b c d e pass f1 2 3 d1 e2 does not raise with self assertraisesregextypeerror rmissing 1 required keywordonly argument d f1 2 3 e2 with self assertraisesregextypeerror rmissing 2 required keywordonly arguments d and e f1 2 3 with self assertraisesregextypeerror rf missing 1 required positional argument c f1 2 with self assertraisesregextypeerror rf missing 2 required positional arguments b and c f1 with self assertraisesregextypeerror r missing 3 required positional arguments a b and c f with self assertraisesregextypeerror rf takes 3 positional arguments but 6 positional arguments rand 2 keywordonly arguments were given f1 2 3 4 5 6 d7 e8 with self assertraisesregextypeerror rf got an unexpected keyword argument f f1 2 3 d1 e4 f56 def testpositionalonlyinvalidcallsself def fa b pass f1 2 does not raise with self assertraisesregextypeerror rf missing 1 required positional argument b f1 with self assertraisesregextypeerror rf missing 2 required positional arguments a and b f with self assertraisesregextypeerror rf takes 2 positional arguments but 3 were given f1 2 3 def testpositionalonlywithoptionalinvalidcallsself def fa b2 pass f1 does not raise with self assertraisesregextypeerror rf missing 1 required positional argument a f with self assertraisesregextypeerror rf takes from 1 to 2 positional arguments but 3 were given f1 2 3 def testnostandardargsusageself def fa b c pass f1 2 c3 with self assertraisestypeerror f1 b2 c3 def testchangedefaultposonlyself def fa b2 c3 return a b c self assertequal2 3 f defaults f defaults 1 2 3 self assertequalf1 2 3 6 def testlambdasself x lambda a b a b self assertequalx1 2 3 self assertequalx1 b2 3 x lambda a b2 a b self assertequalx1 3 x lambda a b a b self assertequalx1 2 3 x lambda a b a b self assertequalx1 2 3 def testinvalidsyntaxlambdaself checksyntaxerrorself lambda a b 5 c none parameter without a default follows parameter with a default checksyntaxerrorself lambda a 5 b c none parameter without a default follows parameter with a default checksyntaxerrorself lambda a 5 b1 c d2 none parameter without a default follows parameter with a default checksyntaxerrorself lambda a 5 b none parameter without a default follows parameter with a default checksyntaxerrorself lambda a b 5 c none parameter without a default follows parameter with a default checksyntaxerrorself lambda args none checksyntaxerrorself lambda args a none checksyntaxerrorself lambda kwargs none checksyntaxerrorself lambda a 1 none checksyntaxerrorself lambda a none checksyntaxerrorself lambda none checksyntaxerrorself lambda a none checksyntaxerrorself lambda a none checksyntaxerrorself lambda a a none duplicate argument a in function definition checksyntaxerrorself lambda a a none duplicate argument a in function definition checksyntaxerrorself lambda a b none checksyntaxerrorself lambda a b c none checksyntaxerrorself lambda a b c d none checksyntaxerrorself lambda a b c none def testposonlymethodsself class example def fself a b return a b self assertequalexample f1 2 1 2 self assertequalexample fexample 1 2 1 2 self assertraisestypeerror example f 1 2 expected rf got some positionalonly arguments passed as keyword arguments b with self assertraisesregextypeerror expected example f1 b2 def testmodulefunctionself with self assertraisesregextypeerror rf missing 2 required positional arguments a and b globalposonlyf def testclosuresself def fx y def gx2 y2 return x y x2 y2 return g self assertequalf1 23 4 10 with self assertraisesregextypeerror rg missing 1 required positional argument y2 f1 23 with self assertraisesregextypeerror rg takes 2 positional arguments but 3 were given f1 23 4 5 def fx y def gx2 y2 return x y x2 y2 return g self assertequalf1 23 4 10 def fx y def gx2 y2 return x y x2 y2 return g self assertequalf1 23 4 10 with self assertraisesregextypeerror rg missing 1 required positional argument y2 f1 23 with self assertraisesregextypeerror rg takes 2 positional arguments but 3 were given f1 23 4 5 def testannotationsinclosuresself def innerhasposonly def fx int return f assert innerhasposonly annotations x int class something def methodself def fx int return f assert something method annotations x int def multiplelevels def innerhasposonly def fx int return f return innerhasposonly assert multiplelevels annotations x int def testsamekeywordaspositionalwithkwargsself def fsomething kwargs return something kwargs self assertequalf42 something42 42 something 42 with self assertraisesregextypeerror rf missing 1 required positional argument something fsomething42 self assertequalf42 42 def testmanglingself class x def fself a42 return a def f2self a42 b43 return a b def f3self a42 b43 c44 return a b c self assertequalx f 42 self assertequalx f2 42 43 self assertequalx f3 42 43 44 def testtoomanyargumentsself more than 255 positionalonly arguments should compile ok fundef def fs n passn join id i for i in range300 compilefundef test single def testserializationself pickledposonly pickle dumpsglobalposonlyf pickledoptional pickle dumpsglobalposonlyandnormal pickleddefaults pickle dumpsglobalposonlydefaults unpickledposonly pickle loadspickledposonly unpickledoptional pickle loadspickledoptional unpickleddefaults pickle loadspickleddefaults self assertequalunpickledposonly1 2 1 2 expected rglobalposonlyf got some positionalonly arguments rpassed as keyword arguments a b with self assertraisesregextypeerror expected unpickledposonlya1 b2 self assertequalunpickledoptional1 2 1 2 expected rglobalposonlyandnormal got some positionalonly arguments rpassed as keyword arguments a with self assertraisesregextypeerror expected unpickledoptionala1 b2 self assertequalunpickleddefaults 1 2 expected rglobalposonlydefaults got some positionalonly arguments rpassed as keyword arguments a with self assertraisesregextypeerror expected unpickleddefaultsa1 b2 def testasyncself async def fa1 b2 return a b with self assertraisesregextypeerror rf got some positionalonly arguments passed as keyword arguments a fa1 b2 def checkcallargs kwargs try coro fargs kwargs coro sendnone except stopiteration as e result e value self assertequalresult 1 2 checkcall1 2 checkcall1 b2 checkcall1 checkcall def testgeneratorself def fa1 b2 yield a b with self assertraisesregextypeerror rf got some positionalonly arguments passed as keyword arguments a fa1 b2 gen f1 2 self assertequalnextgen 1 2 gen f1 b2 self assertequalnextgen 1 2 gen f1 self assertequalnextgen 1 2 gen f self assertequalnextgen 1 2 def testsuperself sentinel object class a def methodself return sentinel class ca def methodself return super method self assertequalc method sentinel def testannotationsconstantfoldself def g def fx not int is int without constant folding we end up with compareopis isop 0 with constant folding we should expect a isop 1 codes i opname i argval for i in dis getinstructionsg self assertnotin unarynot none codes self assertin isop 1 codes if name main unittest main more than 255 positional only arguments should compile ok 3 posonly 2 standard args 3 posonly 2 standard args does not raise does not raise does not raise does not raise more than 255 positional only arguments should compile ok without constant folding we end up with compare_op is is_op 0 with constant folding we should expect a is_op 1
import dis
import pickle
import unittest

from test.support import check_syntax_error


def global_pos_only_f(a, b, /):
    return a, b

def global_pos_only_and_normal(a, /, b):
    return a, b

def global_pos_only_defaults(a=1, /, b=2):
    return a, b

class PositionalOnlyTestCase(unittest.TestCase):

    def assertRaisesSyntaxError(self, codestr, regex="invalid syntax"):
        with self.assertRaisesRegex(SyntaxError, regex):
            compile(codestr + "\n", "<test>", "single")

    def test_invalid_syntax_errors(self):
        check_syntax_error(self, "def f(a, b = 5, /, c): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "def f(a = 5, b, /, c): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "def f(a = 5, b, /): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "def f(a, /, b = 5, c): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "def f(*args, /): pass")
        check_syntax_error(self, "def f(*args, a, /): pass")
        check_syntax_error(self, "def f(**kwargs, /): pass")
        check_syntax_error(self, "def f(/, a = 1): pass")
        check_syntax_error(self, "def f(/, a): pass")
        check_syntax_error(self, "def f(/): pass")
        check_syntax_error(self, "def f(*, a, /): pass")
        check_syntax_error(self, "def f(*, /, a): pass")
        check_syntax_error(self, "def f(a, /, a): pass", "duplicate argument 'a' in function definition")
        check_syntax_error(self, "def f(a, /, *, a): pass", "duplicate argument 'a' in function definition")
        check_syntax_error(self, "def f(a, b/2, c): pass")
        check_syntax_error(self, "def f(a, /, c, /): pass")
        check_syntax_error(self, "def f(a, /, c, /, d): pass")
        check_syntax_error(self, "def f(a, /, c, /, d, *, e): pass")
        check_syntax_error(self, "def f(a, *, c, /, d, e): pass")

    def test_invalid_syntax_errors_async(self):
        check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "async def f(a = 5, b, /): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "async def f(a, /, b = 5, c): pass", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "async def f(*args, /): pass")
        check_syntax_error(self, "async def f(*args, a, /): pass")
        check_syntax_error(self, "async def f(**kwargs, /): pass")
        check_syntax_error(self, "async def f(/, a = 1): pass")
        check_syntax_error(self, "async def f(/, a): pass")
        check_syntax_error(self, "async def f(/): pass")
        check_syntax_error(self, "async def f(*, a, /): pass")
        check_syntax_error(self, "async def f(*, /, a): pass")
        check_syntax_error(self, "async def f(a, /, a): pass", "duplicate argument 'a' in function definition")
        check_syntax_error(self, "async def f(a, /, *, a): pass", "duplicate argument 'a' in function definition")
        check_syntax_error(self, "async def f(a, b/2, c): pass")
        check_syntax_error(self, "async def f(a, /, c, /): pass")
        check_syntax_error(self, "async def f(a, /, c, /, d): pass")
        check_syntax_error(self, "async def f(a, /, c, /, d, *, e): pass")
        check_syntax_error(self, "async def f(a, *, c, /, d, e): pass")

    def test_optional_positional_only_args(self):
        def f(a, b=10, /, c=100):
            return a + b + c

        self.assertEqual(f(1, 2, 3), 6)
        self.assertEqual(f(1, 2, c=3), 6)
        with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"):
            f(1, b=2, c=3)

        self.assertEqual(f(1, 2), 103)
        with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"):
            f(1, b=2)
        self.assertEqual(f(1, c=2), 13)

        def f(a=1, b=10, /, c=100):
            return a + b + c

        self.assertEqual(f(1, 2, 3), 6)
        self.assertEqual(f(1, 2, c=3), 6)
        with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"):
            f(1, b=2, c=3)

        self.assertEqual(f(1, 2), 103)
        with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"):
            f(1, b=2)
        self.assertEqual(f(1, c=2), 13)

    def test_syntax_for_many_positional_only(self):
        
        fundef = "def f(%s, /):\n  pass\n" % ', '.join('i%d' % i for i in range(300))
        compile(fundef, "<test>", "single")

    def test_pos_only_definition(self):
        def f(a, b, c, /, d, e=1, *, f, g=2):
            pass

        self.assertEqual(5, f.__code__.co_argcount)  
        self.assertEqual(3, f.__code__.co_posonlyargcount)
        self.assertEqual((1,), f.__defaults__)

        def f(a, b, c=1, /, d=2, e=3, *, f, g=4):
            pass

        self.assertEqual(5, f.__code__.co_argcount)  
        self.assertEqual(3, f.__code__.co_posonlyargcount)
        self.assertEqual((1, 2, 3), f.__defaults__)

    def test_pos_only_call_via_unpacking(self):
        def f(a, b, /):
            return a + b

        self.assertEqual(f(*[1, 2]), 3)

    def test_use_positional_as_keyword(self):
        def f(a, /):
            pass
        expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'"
        with self.assertRaisesRegex(TypeError, expected):
            f(a=1)

        def f(a, /, b):
            pass
        expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'"
        with self.assertRaisesRegex(TypeError, expected):
            f(a=1, b=2)

        def f(a, b, /):
            pass
        expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'a, b'"
        with self.assertRaisesRegex(TypeError, expected):
            f(a=1, b=2)

    def test_positional_only_and_arg_invalid_calls(self):
        def f(a, b, /, c):
            pass
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'c'"):
            f(1, 2)
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'b' and 'c'"):
            f(1)
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 3 required positional arguments: 'a', 'b', and 'c'"):
            f()
        with self.assertRaisesRegex(TypeError, r"f\(\) takes 3 positional arguments but 4 were given"):
            f(1, 2, 3, 4)

    def test_positional_only_and_optional_arg_invalid_calls(self):
        def f(a, b, /, c=3):
            pass
        f(1, 2)  
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'b'"):
            f(1)
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'a' and 'b'"):
            f()
        with self.assertRaisesRegex(TypeError, r"f\(\) takes from 2 to 3 positional arguments but 4 were given"):
            f(1, 2, 3, 4)

    def test_positional_only_and_kwonlyargs_invalid_calls(self):
        def f(a, b, /, c, *, d, e):
            pass
        f(1, 2, 3, d=1, e=2)  
        with self.assertRaisesRegex(TypeError, r"missing 1 required keyword-only argument: 'd'"):
            f(1, 2, 3, e=2)
        with self.assertRaisesRegex(TypeError, r"missing 2 required keyword-only arguments: 'd' and 'e'"):
            f(1, 2, 3)
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'c'"):
            f(1, 2)
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'b' and 'c'"):
            f(1)
        with self.assertRaisesRegex(TypeError, r" missing 3 required positional arguments: 'a', 'b', and 'c'"):
            f()
        with self.assertRaisesRegex(TypeError, r"f\(\) takes 3 positional arguments but 6 positional arguments "
                                               r"\(and 2 keyword-only arguments\) were given"):
            f(1, 2, 3, 4, 5, 6, d=7, e=8)
        with self.assertRaisesRegex(TypeError, r"f\(\) got an unexpected keyword argument 'f'"):
            f(1, 2, 3, d=1, e=4, f=56)

    def test_positional_only_invalid_calls(self):
        def f(a, b, /):
            pass
        f(1, 2)  
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'b'"):
            f(1)
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'a' and 'b'"):
            f()
        with self.assertRaisesRegex(TypeError, r"f\(\) takes 2 positional arguments but 3 were given"):
            f(1, 2, 3)

    def test_positional_only_with_optional_invalid_calls(self):
        def f(a, b=2, /):
            pass
        f(1)  
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'a'"):
            f()

        with self.assertRaisesRegex(TypeError, r"f\(\) takes from 1 to 2 positional arguments but 3 were given"):
            f(1, 2, 3)

    def test_no_standard_args_usage(self):
        def f(a, b, /, *, c):
            pass

        f(1, 2, c=3)
        with self.assertRaises(TypeError):
            f(1, b=2, c=3)

    def test_change_default_pos_only(self):
        def f(a, b=2, /, c=3):
            return a + b + c

        self.assertEqual((2,3), f.__defaults__)
        f.__defaults__ = (1, 2, 3)
        self.assertEqual(f(1, 2, 3), 6)

    def test_lambdas(self):
        x = lambda a, /, b: a + b
        self.assertEqual(x(1,2), 3)
        self.assertEqual(x(1,b=2), 3)

        x = lambda a, /, b=2: a + b
        self.assertEqual(x(1), 3)

        x = lambda a, b, /: a + b
        self.assertEqual(x(1, 2), 3)

        x = lambda a, b, /, : a + b
        self.assertEqual(x(1, 2), 3)

    def test_invalid_syntax_lambda(self):
        check_syntax_error(self, "lambda a, b = 5, /, c: None", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "lambda a = 5, b, /, c: None", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "lambda a = 5, b=1, /, c, *, d=2: None", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "lambda a = 5, b, /: None", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "lambda a, /, b = 5, c: None", "parameter without a default follows parameter with a default")
        check_syntax_error(self, "lambda *args, /: None")
        check_syntax_error(self, "lambda *args, a, /: None")
        check_syntax_error(self, "lambda **kwargs, /: None")
        check_syntax_error(self, "lambda /, a = 1: None")
        check_syntax_error(self, "lambda /, a: None")
        check_syntax_error(self, "lambda /: None")
        check_syntax_error(self, "lambda *, a, /: None")
        check_syntax_error(self, "lambda *, /, a: None")
        check_syntax_error(self, "lambda a, /, a: None", "duplicate argument 'a' in function definition")
        check_syntax_error(self, "lambda a, /, *, a: None", "duplicate argument 'a' in function definition")
        check_syntax_error(self, "lambda a, /, b, /: None")
        check_syntax_error(self, "lambda a, /, b, /, c: None")
        check_syntax_error(self, "lambda a, /, b, /, c, *, d: None")
        check_syntax_error(self, "lambda a, *, b, /, c: None")

    def test_posonly_methods(self):
        class Example:
            def f(self, a, b, /):
                return a, b

        self.assertEqual(Example().f(1, 2), (1, 2))
        self.assertEqual(Example.f(Example(), 1, 2), (1, 2))
        self.assertRaises(TypeError, Example.f, 1, 2)
        expected = r"f\(\) got some positional-only arguments passed as keyword arguments: 'b'"
        with self.assertRaisesRegex(TypeError, expected):
            Example().f(1, b=2)

    def test_module_function(self):
        with self.assertRaisesRegex(TypeError, r"f\(\) missing 2 required positional arguments: 'a' and 'b'"):
            global_pos_only_f()


    def test_closures(self):
        def f(x,y):
            def g(x2,/,y2):
                return x + y + x2 + y2
            return g

        self.assertEqual(f(1,2)(3,4), 10)
        with self.assertRaisesRegex(TypeError, r"g\(\) missing 1 required positional argument: 'y2'"):
            f(1,2)(3)
        with self.assertRaisesRegex(TypeError, r"g\(\) takes 2 positional arguments but 3 were given"):
            f(1,2)(3,4,5)

        def f(x,/,y):
            def g(x2,y2):
                return x + y + x2 + y2
            return g

        self.assertEqual(f(1,2)(3,4), 10)

        def f(x,/,y):
            def g(x2,/,y2):
                return x + y + x2 + y2
            return g

        self.assertEqual(f(1,2)(3,4), 10)
        with self.assertRaisesRegex(TypeError, r"g\(\) missing 1 required positional argument: 'y2'"):
            f(1,2)(3)
        with self.assertRaisesRegex(TypeError, r"g\(\) takes 2 positional arguments but 3 were given"):
            f(1,2)(3,4,5)

    def test_annotations_in_closures(self):

        def inner_has_pos_only():
            def f(x: int, /): ...
            return f

        assert inner_has_pos_only().__annotations__ == {'x': int}

        class Something:
            def method(self):
                def f(x: int, /): ...
                return f

        assert Something().method().__annotations__ == {'x': int}

        def multiple_levels():
            def inner_has_pos_only():
                def f(x: int, /): ...
                return f
            return inner_has_pos_only()

        assert multiple_levels().__annotations__ == {'x': int}

    def test_same_keyword_as_positional_with_kwargs(self):
        def f(something,/,**kwargs):
            return (something, kwargs)

        self.assertEqual(f(42, something=42), (42, {'something': 42}))

        with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'something'"):
            f(something=42)

        self.assertEqual(f(42), (42, {}))

    def test_mangling(self):
        class X:
            def f(self, __a=42, /):
                return __a

            def f2(self, __a=42, /, __b=43):
                return (__a, __b)

            def f3(self, __a=42, /, __b=43, *, __c=44):
                return (__a, __b, __c)

        self.assertEqual(X().f(), 42)
        self.assertEqual(X().f2(), (42, 43))
        self.assertEqual(X().f3(), (42, 43, 44))

    def test_too_many_arguments(self):
        
        fundef = "def f(%s, /):\n  pass\n" % ', '.join('i%d' % i for i in range(300))
        compile(fundef, "<test>", "single")

    def test_serialization(self):
        pickled_posonly = pickle.dumps(global_pos_only_f)
        pickled_optional = pickle.dumps(global_pos_only_and_normal)
        pickled_defaults = pickle.dumps(global_pos_only_defaults)

        unpickled_posonly = pickle.loads(pickled_posonly)
        unpickled_optional = pickle.loads(pickled_optional)
        unpickled_defaults = pickle.loads(pickled_defaults)

        self.assertEqual(unpickled_posonly(1,2), (1,2))
        expected = r"global_pos_only_f\(\) got some positional-only arguments "\
                   r"passed as keyword arguments: 'a, b'"
        with self.assertRaisesRegex(TypeError, expected):
            unpickled_posonly(a=1,b=2)

        self.assertEqual(unpickled_optional(1,2), (1,2))
        expected = r"global_pos_only_and_normal\(\) got some positional-only arguments "\
                   r"passed as keyword arguments: 'a'"
        with self.assertRaisesRegex(TypeError, expected):
            unpickled_optional(a=1,b=2)

        self.assertEqual(unpickled_defaults(), (1,2))
        expected = r"global_pos_only_defaults\(\) got some positional-only arguments "\
                   r"passed as keyword arguments: 'a'"
        with self.assertRaisesRegex(TypeError, expected):
            unpickled_defaults(a=1,b=2)

    def test_async(self):

        async def f(a=1, /, b=2):
            return a, b

        with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'"):
            f(a=1, b=2)

        def _check_call(*args, **kwargs):
            try:
                coro = f(*args, **kwargs)
                coro.send(None)
            except StopIteration as e:
                result = e.value
            self.assertEqual(result, (1, 2))

        _check_call(1, 2)
        _check_call(1, b=2)
        _check_call(1)
        _check_call()

    def test_generator(self):

        def f(a=1, /, b=2):
            yield a, b

        with self.assertRaisesRegex(TypeError, r"f\(\) got some positional-only arguments passed as keyword arguments: 'a'"):
            f(a=1, b=2)

        gen = f(1, 2)
        self.assertEqual(next(gen), (1, 2))
        gen = f(1, b=2)
        self.assertEqual(next(gen), (1, 2))
        gen = f(1)
        self.assertEqual(next(gen), (1, 2))
        gen = f()
        self.assertEqual(next(gen), (1, 2))

    def test_super(self):

        sentinel = object()

        class A:
            def method(self):
                return sentinel

        class C(A):
            def method(self, /):
                return super().method()

        self.assertEqual(C().method(), sentinel)

    def test_annotations_constant_fold(self):
        def g():
            def f(x: not (int is int), /): ...

        
        
        
        codes = [(i.opname, i.argval) for i in dis.get_instructions(g)]
        self.assertNotIn(('UNARY_NOT', None), codes)
        self.assertIn(('IS_OP', 1), codes)


if __name__ == "__main__":
    unittest.main()