Skip to content

Commit 6712b32

Browse files
author
Andrei Bratu
authored
SDK Decorators QA (#35)
Python 3.10 typing fix
1 parent e598da6 commit 6712b32

2 files changed

Lines changed: 89 additions & 94 deletions

File tree

src/humanloop/decorators/tool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def _build_function_parameters_property(func) -> _JSONSchemaFunctionParameters:
213213
)
214214

215215

216-
if sys.version_info >= (3, 10):
216+
if sys.version_info >= (3, 11):
217217
_PRIMITIVE_TYPES = Union[
218218
str,
219219
int,
@@ -223,7 +223,7 @@ def _build_function_parameters_property(func) -> _JSONSchemaFunctionParameters:
223223
Ellipsis, # type: ignore
224224
]
225225
else:
226-
# Ellipsis not supported in typing module before Python 3.10
226+
# Ellipsis not supported as type before Python 3.11
227227
_PRIMITIVE_TYPES = Union[
228228
str,
229229
int,

tests/decorators/test_tool_decorator.py

Lines changed: 87 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -463,106 +463,101 @@ def calculator(operation: str, num1: float, num2: float) -> float:
463463
assert hl_file_higher_order_fn["tool"]["source_code"] == hl_file_decorated_fn["tool"]["source_code"] # type: ignore
464464

465465

466-
def test_python310_syntax(
467-
opentelemetry_test_configuration: tuple[Tracer, InMemorySpanExporter],
468-
):
469-
if sys.version_info < (3, 10):
470-
pytest.skip("Requires Python 3.10")
471-
# GIVEN an OTel configuration
472-
tracer, _ = opentelemetry_test_configuration
466+
if sys.version_info >= (3, 10):
467+
# Testing that function parsing for Tool decorator
468+
# works with Python 3.10 and above syntax
473469

474-
# GIVEN a function annotated with @tool where a parameter uses `|` for Optional
475-
@tool(opentelemetry_tracer=tracer)
476-
def calculator(a: float, b: float | None = None) -> float:
477-
# NOTE: dummy function, only testing its signature not correctness
478-
if a is None:
479-
a = 0
480-
return a + b # type: ignore
470+
def test_python310_syntax(
471+
opentelemetry_test_configuration: tuple[Tracer, InMemorySpanExporter],
472+
):
473+
# GIVEN an OTel configuration
474+
tracer, _ = opentelemetry_test_configuration
481475

482-
# WHEN building the Tool kernel
483-
# THEN the JSON schema is correct
484-
assert calculator.json_schema == {
485-
"description": "",
486-
"name": "calculator",
487-
"parameters": {
488-
"properties": {
489-
"a": {"type": "number"},
490-
"b": {"type": ["number", "null"]},
476+
# GIVEN a function annotated with @tool where a parameter uses `|` for Optional
477+
@tool(opentelemetry_tracer=tracer)
478+
def calculator(a: float, b: float | None = None) -> float:
479+
# NOTE: dummy function, only testing its signature not correctness
480+
if a is None:
481+
a = 0
482+
return a + b # type: ignore
483+
484+
# WHEN building the Tool kernel
485+
# THEN the JSON schema is correct
486+
assert calculator.json_schema == {
487+
"description": "",
488+
"name": "calculator",
489+
"parameters": {
490+
"properties": {
491+
"a": {"type": "number"},
492+
"b": {"type": ["number", "null"]},
493+
},
494+
"required": ("a",),
495+
"type": "object",
496+
"additionalProperties": False,
491497
},
492-
"required": ("a",),
493-
"type": "object",
494-
"additionalProperties": False,
495-
},
496-
"strict": True,
497-
}
498-
499-
Validator.check_schema(calculator.json_schema)
500-
501-
502-
def test_python310_union_syntax(
503-
opentelemetry_test_configuration: tuple[Tracer, InMemorySpanExporter],
504-
):
505-
if sys.version_info < (3, 10):
506-
pytest.skip("Requires Python 3.10")
498+
"strict": True,
499+
}
507500

508-
# GIVEN an OTel configuration
509-
tracer, _ = opentelemetry_test_configuration
501+
Validator.check_schema(calculator.json_schema)
510502

511-
# GIVEN a function annotated with @tool where a parameter uses `|` for Union
512-
@tool(opentelemetry_tracer=tracer)
513-
def calculator(a: float, b: float | int | str) -> float:
514-
# NOTE: dummy function, only testing its signature not correctness
515-
return a + b # type: ignore
503+
def test_python310_union_syntax(
504+
opentelemetry_test_configuration: tuple[Tracer, InMemorySpanExporter],
505+
):
506+
# GIVEN an OTel configuration
507+
tracer, _ = opentelemetry_test_configuration
516508

517-
# WHEN building the Tool kernel
518-
# THEN the JSON schema is correct
519-
assert calculator.json_schema == {
520-
"description": "",
521-
"name": "calculator",
522-
"parameters": {
523-
"properties": {
524-
"a": {"type": "number"},
525-
"b": {"anyOf": [{"type": "number"}, {"type": "integer"}, {"type": "string"}]},
509+
# GIVEN a function annotated with @tool where a parameter uses `|` for Union
510+
@tool(opentelemetry_tracer=tracer)
511+
def calculator(a: float, b: float | int | str) -> float:
512+
# NOTE: dummy function, only testing its signature not correctness
513+
return a + b # type: ignore
514+
515+
# WHEN building the Tool kernel
516+
# THEN the JSON schema is correct
517+
assert calculator.json_schema == {
518+
"description": "",
519+
"name": "calculator",
520+
"parameters": {
521+
"properties": {
522+
"a": {"type": "number"},
523+
"b": {"anyOf": [{"type": "number"}, {"type": "integer"}, {"type": "string"}]},
524+
},
525+
"required": ("a", "b"),
526+
"type": "object",
527+
"additionalProperties": False,
526528
},
527-
"required": ("a", "b"),
528-
"type": "object",
529-
"additionalProperties": False,
530-
},
531-
"strict": True,
532-
}
533-
534-
Validator.check_schema(calculator.json_schema)
535-
529+
"strict": True,
530+
}
536531

537-
def test_python_list_ellipsis(
538-
opentelemetry_test_configuration: tuple[Tracer, InMemorySpanExporter],
539-
):
540-
if sys.version_info < (3, 10):
541-
pytest.skip("Requires Python 3.10")
542-
# GIVEN an OTel configuration
543-
tracer, _ = opentelemetry_test_configuration
532+
Validator.check_schema(calculator.json_schema)
544533

545-
# GIVEN a function annotated with @tool where a parameter uses `...`
546-
@tool(opentelemetry_tracer=tracer)
547-
def calculator(b: ...) -> float | None: # type: ignore
548-
# NOTE: dummy function, only testing its signature not correctness
549-
if isinstance(b, list):
550-
return sum(b)
551-
return None
534+
def test_python_list_ellipsis(
535+
opentelemetry_test_configuration: tuple[Tracer, InMemorySpanExporter],
536+
):
537+
# GIVEN an OTel configuration
538+
tracer, _ = opentelemetry_test_configuration
552539

553-
# WHEN building the Tool kernel
554-
# THEN the JSON schema is correct
555-
assert calculator.json_schema == {
556-
"description": "",
557-
"name": "calculator",
558-
"parameters": {
559-
"properties": {
560-
# THEN b is of any type
561-
"b": {"type": ["string", "integer", "number", "boolean", "object", "array", "null"]},
540+
# GIVEN a function annotated with @tool where a parameter uses `...`
541+
@tool(opentelemetry_tracer=tracer)
542+
def calculator(b: ...) -> float | None: # type: ignore
543+
# NOTE: dummy function, only testing its signature not correctness
544+
if isinstance(b, list):
545+
return sum(b)
546+
return None
547+
548+
# WHEN building the Tool kernel
549+
# THEN the JSON schema is correct
550+
assert calculator.json_schema == {
551+
"description": "",
552+
"name": "calculator",
553+
"parameters": {
554+
"properties": {
555+
# THEN b is of any type
556+
"b": {"type": ["string", "integer", "number", "boolean", "object", "array", "null"]},
557+
},
558+
"required": ("b",),
559+
"type": "object",
560+
"additionalProperties": False,
562561
},
563-
"required": ("b",),
564-
"type": "object",
565-
"additionalProperties": False,
566-
},
567-
"strict": True,
568-
}
562+
"strict": True,
563+
}

0 commit comments

Comments
 (0)