main
1from __future__ import annotations
2
3import pytest
4
5from openai._utils import required_args
6
7
8def test_too_many_positional_params() -> None:
9 @required_args(["a"])
10 def foo(a: str | None = None) -> str | None:
11 return a
12
13 with pytest.raises(TypeError, match=r"foo\(\) takes 1 argument\(s\) but 2 were given"):
14 foo("a", "b") # type: ignore
15
16
17def test_positional_param() -> None:
18 @required_args(["a"])
19 def foo(a: str | None = None) -> str | None:
20 return a
21
22 assert foo("a") == "a"
23 assert foo(None) is None
24 assert foo(a="b") == "b"
25
26 with pytest.raises(TypeError, match="Missing required argument: 'a'"):
27 foo()
28
29
30def test_keyword_only_param() -> None:
31 @required_args(["a"])
32 def foo(*, a: str | None = None) -> str | None:
33 return a
34
35 assert foo(a="a") == "a"
36 assert foo(a=None) is None
37 assert foo(a="b") == "b"
38
39 with pytest.raises(TypeError, match="Missing required argument: 'a'"):
40 foo()
41
42
43def test_multiple_params() -> None:
44 @required_args(["a", "b", "c"])
45 def foo(a: str = "", *, b: str = "", c: str = "") -> str | None:
46 return f"{a} {b} {c}"
47
48 assert foo(a="a", b="b", c="c") == "a b c"
49
50 error_message = r"Missing required arguments.*"
51
52 with pytest.raises(TypeError, match=error_message):
53 foo()
54
55 with pytest.raises(TypeError, match=error_message):
56 foo(a="a")
57
58 with pytest.raises(TypeError, match=error_message):
59 foo(b="b")
60
61 with pytest.raises(TypeError, match=error_message):
62 foo(c="c")
63
64 with pytest.raises(TypeError, match=r"Missing required argument: 'a'"):
65 foo(b="a", c="c")
66
67 with pytest.raises(TypeError, match=r"Missing required argument: 'b'"):
68 foo("a", c="c")
69
70
71def test_multiple_variants() -> None:
72 @required_args(["a"], ["b"])
73 def foo(*, a: str | None = None, b: str | None = None) -> str | None:
74 return a if a is not None else b
75
76 assert foo(a="foo") == "foo"
77 assert foo(b="bar") == "bar"
78 assert foo(a=None) is None
79 assert foo(b=None) is None
80
81 # TODO: this error message could probably be improved
82 with pytest.raises(
83 TypeError,
84 match=r"Missing required arguments; Expected either \('a'\) or \('b'\) arguments to be given",
85 ):
86 foo()
87
88
89def test_multiple_params_multiple_variants() -> None:
90 @required_args(["a", "b"], ["c"])
91 def foo(*, a: str | None = None, b: str | None = None, c: str | None = None) -> str | None:
92 if a is not None:
93 return a
94 if b is not None:
95 return b
96 return c
97
98 error_message = r"Missing required arguments; Expected either \('a' and 'b'\) or \('c'\) arguments to be given"
99
100 with pytest.raises(TypeError, match=error_message):
101 foo(a="foo")
102
103 with pytest.raises(TypeError, match=error_message):
104 foo(b="bar")
105
106 with pytest.raises(TypeError, match=error_message):
107 foo()
108
109 assert foo(a=None, b="bar") == "bar"
110 assert foo(c=None) is None
111 assert foo(c="foo") == "foo"