fix(jambo): Update legacy typing to built in types (#9)

* Migrate from `typing_extensions` to `typing` for supported Python versions, and update code to use modern type hinting with unions and annotations.

* Update type hinting to use lowercase generics for Python 3.9+ compatibility.
This commit is contained in:
Thomas
2025-07-08 16:41:09 +02:00
committed by GitHub
parent 8dbe84fd1c
commit 9c598eeacc
19 changed files with 63 additions and 51 deletions

View File

@@ -1,7 +1,7 @@
from jambo.types.type_parser_options import TypeParserOptions
from pydantic import Field, TypeAdapter
from typing_extensions import Annotated, Any, Generic, Self, TypeVar, Unpack
from typing import Annotated, Any, Generic, Self, TypeVar, Unpack
from abc import ABC, abstractmethod
@@ -47,7 +47,7 @@ class GenericTypeParser(ABC, Generic[T]):
if not self._validate_default(parsed_type, parsed_properties):
raise ValueError(
f"Default value {properties.get('default')} is not valid for type {parsed_type.__name__}"
f"Default value {properties.get('default')} is not valid for type {parsed_type}"
)
return parsed_type, parsed_properties

View File

@@ -1,7 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Any, Unpack
from typing import Any, Unpack
class AllOfTypeParser(GenericTypeParser):

View File

@@ -2,11 +2,14 @@ from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from pydantic import Field
from typing_extensions import Annotated, Union, Unpack
from typing import Annotated, Unpack
from types import UnionType
from functools import reduce
from operator import or_
class AnyOfTypeParser(GenericTypeParser):
mapped_type = Union
mapped_type = UnionType
json_schema_type = "anyOf"
@@ -41,4 +44,6 @@ class AnyOfTypeParser(GenericTypeParser):
for t, v in sub_types
]
return Union[(*field_types,)], mapped_properties
union_type = reduce(or_, field_types)
return union_type, mapped_properties

View File

@@ -1,7 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Iterable, TypeVar, Unpack
from typing import Iterable, TypeVar, Unpack
import copy

View File

@@ -1,7 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Unpack
from typing import Unpack
class BooleanTypeParser(GenericTypeParser):

View File

@@ -3,7 +3,7 @@ from jambo.types.json_schema_type import JSONSchemaNativeTypes
from jambo.types.type_parser_options import TypeParserOptions
from pydantic import AfterValidator
from typing_extensions import Annotated, Any, Literal, Unpack
from typing import Annotated, Any, Literal, Unpack
class ConstTypeParser(GenericTypeParser):

View File

@@ -2,7 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
from jambo.types.json_schema_type import JSONSchemaNativeTypes
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Unpack
from typing import Unpack
from enum import Enum

View File

@@ -1,7 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Unpack
from typing import Unpack
class FloatTypeParser(GenericTypeParser):

View File

@@ -1,7 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Unpack
from typing import Unpack
class IntTypeParser(GenericTypeParser):

View File

@@ -1,7 +1,7 @@
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Unpack
from typing import Unpack
class NullTypeParser(GenericTypeParser):

View File

@@ -2,7 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from pydantic import BaseModel, ConfigDict, Field, create_model
from typing_extensions import Any, Unpack
from typing import Any, Unpack
class ObjectTypeParser(GenericTypeParser):

View File

@@ -1,12 +1,15 @@
from types import UnionType
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from pydantic import Field, BeforeValidator, TypeAdapter, ValidationError
from typing_extensions import Annotated, Union, Unpack, Any
from typing import Annotated, Unpack, Any
from functools import reduce
from operator import or_
class OneOfTypeParser(GenericTypeParser):
mapped_type = Union
mapped_type = UnionType
json_schema_type = "oneOf"
@@ -36,7 +39,7 @@ class OneOfTypeParser(GenericTypeParser):
for t, v in sub_types
]
union_type = Union[(*field_types,)]
union_type = reduce(or_, field_types)
discriminator = properties.get("discriminator")
if discriminator and isinstance(discriminator, dict):

View File

@@ -1,10 +1,12 @@
from __future__ import annotations
from jambo.parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Any, ForwardRef, Literal, TypeVar, Union, Unpack
from typing import Any, ForwardRef, Literal, TypeVar, Unpack
RefType = TypeVar("RefType", bound=Union[type, ForwardRef])
RefType = TypeVar("RefType", bound=type | ForwardRef)
RefStrategy = Literal["forward_ref", "def_ref"]

View File

@@ -2,7 +2,7 @@ from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
from pydantic import EmailStr, HttpUrl, IPvAnyAddress, FilePath
from typing_extensions import Unpack
from typing import Unpack
from datetime import date, datetime, time

View File

@@ -1,4 +1,6 @@
from typing_extensions import Dict, List, Literal, TypedDict, Union
from __future__ import annotations
from typing import Literal, TypedDict
from types import NoneType
@@ -19,7 +21,7 @@ JSONSchemaNativeTypes: tuple[type, ...] = (
)
JSONType = Union[str, int, float, bool, None, Dict[str, "JSONType"], List["JSONType"]]
JSONType = str | int | float | bool | None | dict[str, "JSONType"] | list["JSONType"]
class JSONSchema(TypedDict, total=False):
@@ -27,23 +29,23 @@ class JSONSchema(TypedDict, total=False):
title: str
description: str
default: JSONType
examples: List[JSONType]
examples: list[JSONType]
# Type definitions
type: Union[JSONSchemaType, List[JSONSchemaType]]
type: JSONSchemaType | list[JSONSchemaType]
# Object-specific keywords
properties: Dict[str, "JSONSchema"]
required: List[str]
additionalProperties: Union[bool, "JSONSchema"]
properties: dict[str, "JSONSchema"]
required: list[str]
additionalProperties: bool | "JSONSchema"
minProperties: int
maxProperties: int
patternProperties: Dict[str, "JSONSchema"]
dependencies: Dict[str, Union[List[str], "JSONSchema"]]
patternProperties: dict[str, "JSONSchema"]
dependencies: dict[str, list[str] | "JSONSchema"]
# Array-specific keywords
items: Union["JSONSchema", List["JSONSchema"]]
additionalItems: Union[bool, "JSONSchema"]
items: "JSONSchema" | list["JSONSchema"]
additionalItems: bool | "JSONSchema"
minItems: int
maxItems: int
uniqueItems: bool
@@ -62,7 +64,7 @@ class JSONSchema(TypedDict, total=False):
multipleOf: float
# Enum and const
enum: List[JSONType]
enum: list[JSONType]
const: JSONType
# Conditionals
@@ -71,23 +73,23 @@ class JSONSchema(TypedDict, total=False):
else_: "JSONSchema" # 'else' is also a reserved word
# Combination keywords
allOf: List["JSONSchema"]
anyOf: List["JSONSchema"]
oneOf: List["JSONSchema"]
allOf: list["JSONSchema"]
anyOf: list["JSONSchema"]
oneOf: list["JSONSchema"]
not_: "JSONSchema" # 'not' is a reserved word
# Fix forward references
JSONSchema.__annotations__["properties"] = Dict[str, JSONSchema]
JSONSchema.__annotations__["items"] = Union[JSONSchema, List[JSONSchema]]
JSONSchema.__annotations__["additionalItems"] = Union[bool, JSONSchema]
JSONSchema.__annotations__["additionalProperties"] = Union[bool, JSONSchema]
JSONSchema.__annotations__["patternProperties"] = Dict[str, JSONSchema]
JSONSchema.__annotations__["dependencies"] = Dict[str, Union[List[str], JSONSchema]]
JSONSchema.__annotations__["properties"] = dict[str, JSONSchema]
JSONSchema.__annotations__["items"] = JSONSchema | list[JSONSchema]
JSONSchema.__annotations__["additionalItems"] = bool | JSONSchema
JSONSchema.__annotations__["additionalProperties"] = bool | JSONSchema
JSONSchema.__annotations__["patternProperties"] = dict[str, JSONSchema]
JSONSchema.__annotations__["dependencies"] = dict[str, list[str] | JSONSchema]
JSONSchema.__annotations__["if_"] = JSONSchema
JSONSchema.__annotations__["then"] = JSONSchema
JSONSchema.__annotations__["else_"] = JSONSchema
JSONSchema.__annotations__["allOf"] = List[JSONSchema]
JSONSchema.__annotations__["anyOf"] = List[JSONSchema]
JSONSchema.__annotations__["oneOf"] = List[JSONSchema]
JSONSchema.__annotations__["allOf"] = list[JSONSchema]
JSONSchema.__annotations__["anyOf"] = list[JSONSchema]
JSONSchema.__annotations__["oneOf"] = list[JSONSchema]
JSONSchema.__annotations__["not_"] = JSONSchema

View File

@@ -1,6 +1,6 @@
from jambo.types.json_schema_type import JSONSchema
from typing_extensions import TypedDict
from typing import TypedDict
class TypeParserOptions(TypedDict):

View File

@@ -1,6 +1,6 @@
from jambo.parser.anyof_type_parser import AnyOfTypeParser
from typing_extensions import Annotated, Union, get_args, get_origin
from typing import Annotated, get_args, get_origin
from unittest import TestCase
@@ -42,7 +42,7 @@ class TestAnyOfTypeParser(TestCase):
)
# check union type has string and int
self.assertEqual(get_origin(type_parsing), Union)
self.assertEqual(get_origin(type_parsing), type(str | int))
type_1, type_2 = get_args(type_parsing)
@@ -67,7 +67,7 @@ class TestAnyOfTypeParser(TestCase):
)
# check union type has string and int
self.assertEqual(get_origin(type_parsing), Union)
self.assertEqual(get_origin(type_parsing), type(str | int))
type_1, type_2 = get_args(type_parsing)

View File

@@ -1,6 +1,6 @@
from jambo.parser import ArrayTypeParser
from typing_extensions import get_args
from typing import get_args
from unittest import TestCase

View File

@@ -1,6 +1,6 @@
from jambo.parser import ConstTypeParser
from typing_extensions import Annotated, Literal, get_args, get_origin
from typing import Annotated, Literal, get_args, get_origin
from unittest import TestCase