diff --git a/python/cog/command/ast_openapi_schema.py b/python/cog/command/ast_openapi_schema.py index f482e03bfa..018c5bd6af 100644 --- a/python/cog/command/ast_openapi_schema.py +++ b/python/cog/command/ast_openapi_schema.py @@ -336,12 +336,6 @@ def get_value(node: ast.AST) -> "AstVal": """Return the value of constant or list of constants""" if isinstance(node, ast.Constant): return node.value - # DeprecationWarning: ast.Str | ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead - if sys.version_info < (3, 8): - if isinstance(node, (ast.Str, ast.Bytes)): - return node.s - if isinstance(node, ast.Num): - return node.n if isinstance(node, (ast.List, ast.Tuple)): return [get_value(e) for e in node.elts] if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub): @@ -536,10 +530,7 @@ def extract_info(code: str) -> "JSONDict": # pylint: disable=too-many-branches, msg = "unknown argument for Input" raise ValueError(msg) kws[kw.arg] = to_serializable(get_value(kw.value)) - elif isinstance(default, (ast.Constant, ast.List, ast.Tuple)) or ( - # DeprecationWarning: ast.Str | ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead - sys.version_info < (3, 8) and isinstance(default, (ast.Str, ast.Num)) - ): + elif isinstance(default, (ast.Constant, ast.List, ast.Tuple)): kws = {"default": to_serializable(get_value(default))} # could be None elif default == ...: # no default kws = {} diff --git a/python/cog/env_property.py b/python/cog/env_property.py index 0853f5255b..be613756d7 100644 --- a/python/cog/env_property.py +++ b/python/cog/env_property.py @@ -1,22 +1,10 @@ import os from functools import wraps -from typing import Any, Callable, Optional, TypeVar, Union +from typing import Any, Callable, Optional, TypeVar, Union, get_args, get_origin R = TypeVar("R") -def _get_origin(typ: Any) -> Any: - if hasattr(typ, "__origin__"): - return typ.__origin__ - return None - - -def _get_args(typ: Any) -> Any: - if hasattr(typ, "__args__"): - return typ.__args__ - return () - - def env_property( env_var: str, ) -> Callable[[Callable[[Any], R]], Callable[[Any], R]]: @@ -29,10 +17,10 @@ def wrapper(*args: Any, **kwargs: Any) -> R: if result is not None: expected_type = func.__annotations__.get("return", str) if ( - _get_origin(expected_type) is Optional - or _get_origin(expected_type) is Union + get_origin(expected_type) is Optional + or get_origin(expected_type) is Union ): - expected_type = _get_args(expected_type)[0] + expected_type = get_args(expected_type)[0] return expected_type(result) result = func(*args, **kwargs) return result diff --git a/python/cog/predictor.py b/python/cog/predictor.py index d0b04fb235..4eef0fe481 100644 --- a/python/cog/predictor.py +++ b/python/cog/predictor.py @@ -14,18 +14,14 @@ Callable, Dict, List, + Literal, Optional, Type, Union, cast, + get_args, + get_origin, ) - -try: - from typing import Literal, get_args, get_origin -except ImportError: # Python < 3.8 - from typing_compat import get_args, get_origin # type: ignore - from typing_extensions import Literal - from unittest.mock import patch import pydantic diff --git a/python/cog/schema.py b/python/cog/schema.py index efdad2d0d7..c8624da8bf 100644 --- a/python/cog/schema.py +++ b/python/cog/schema.py @@ -56,7 +56,7 @@ class Config: if PYDANTIC_V2: from pydantic.networks import UrlConstraints from pydantic_core import Url - from typing_extensions import Annotated + from typing_extensions import Annotated # added to typing in python 3.9 WebhookUrl = Annotated[ Url, UrlConstraints(allowed_schemes=["http", "https"], max_length=65536) diff --git a/python/cog/server/helpers.py b/python/cog/server/helpers.py index 74cc59b2bd..9636677817 100644 --- a/python/cog/server/helpers.py +++ b/python/cog/server/helpers.py @@ -13,7 +13,7 @@ from typing import Any, BinaryIO, Callable, Dict, List, Sequence, TextIO, Union import pydantic -from typing_extensions import Self +from typing_extensions import Self # added to typing in python 3.11 from ..types import PYDANTIC_V2 from .errors import CogRuntimeError, CogTimeoutError diff --git a/python/cog/server/telemetry.py b/python/cog/server/telemetry.py index 2d67a30fad..ad146c69c2 100644 --- a/python/cog/server/telemetry.py +++ b/python/cog/server/telemetry.py @@ -1,9 +1,6 @@ from contextlib import contextmanager from contextvars import ContextVar -from typing import Generator, Optional - -# TypedDict was added in 3.8 -from typing_extensions import TypedDict +from typing import Generator, Optional, TypedDict # See: https://www.w3.org/TR/trace-context/ diff --git a/python/cog/server/useragent.py b/python/cog/server/useragent.py index 61a94dfdf4..9223b0566b 100644 --- a/python/cog/server/useragent.py +++ b/python/cog/server/useragent.py @@ -1,18 +1,9 @@ -import sys +from importlib.metadata import version def _get_version() -> str: try: - if sys.version_info >= (3, 8): - from importlib.metadata import ( - version, # pylint: disable=import-outside-toplevel - ) - - return version("cog") - else: - import pkg_resources # pylint: disable=import-outside-toplevel - - return pkg_resources.get_distribution("cog").version + return version("cog") except Exception: # pylint: disable=broad-exception-caught return "unknown" diff --git a/python/cog/types.py b/python/cog/types.py index 9ac128806b..e1aacc696b 100644 --- a/python/cog/types.py +++ b/python/cog/types.py @@ -14,13 +14,14 @@ List, Optional, Type, + TypedDict, TypeVar, Union, ) import pydantic import requests -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired # added to typing in python 3.11 if pydantic.__version__.startswith("1."): PYDANTIC_V2 = False diff --git a/python/tests/server/test_http_input.py b/python/tests/server/test_http_input.py index fffd7b9155..7553d29c00 100644 --- a/python/tests/server/test_http_input.py +++ b/python/tests/server/test_http_input.py @@ -225,7 +225,7 @@ def test_choices_str(client): @uses_predictor("input_choices_iterable") -def test_choices_str(client): +def test_choices_str_iterable(client): resp = client.post("/predictions", json={"input": {"text": "foo"}}) assert resp.status_code == 200 resp = client.post("/predictions", json={"input": {"text": "baz"}}) diff --git a/python/tests/server/test_worker.py b/python/tests/server/test_worker.py index c43aebeeb1..de79d74000 100644 --- a/python/tests/server/test_worker.py +++ b/python/tests/server/test_worker.py @@ -2,8 +2,8 @@ import os import threading import time -from typing import TYPE_CHECKING, Any, Dict, List, Optional import uuid +from typing import TYPE_CHECKING, Any, Dict, List, Optional import pytest from attrs import define, evolve, field, frozen diff --git a/test-integration/test_integration/test_predict.py b/test-integration/test_integration/test_predict.py index f795537bb5..4065b69927 100644 --- a/test-integration/test_integration/test_predict.py +++ b/test-integration/test_integration/test_predict.py @@ -1,8 +1,6 @@ -import os import pathlib import shutil import subprocess -import sys from pathlib import Path import httpx diff --git a/test-integration/test_integration/util.py b/test-integration/test_integration/util.py index 4af50ba851..4016a64a52 100644 --- a/test-integration/test_integration/util.py +++ b/test-integration/test_integration/util.py @@ -9,7 +9,6 @@ import time import httpx - from packaging.version import VERSION_PATTERN # From the SemVer spec: https://semver.org/