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"