diff --git a/ci/make_geography_db.py b/ci/make_geography_db.py index 371c49f2f38b..6c7a3bdba4ca 100755 --- a/ci/make_geography_db.py +++ b/ci/make_geography_db.py @@ -19,12 +19,15 @@ import datetime import tempfile from pathlib import Path -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any import requests import sqlalchemy as sa import toolz +if TYPE_CHECKING: + from collections.abc import Mapping + SCHEMAS = { "countries": [ ("iso_alpha2", sa.TEXT), diff --git a/docs/backends/app/backend_info_app.py b/docs/backends/app/backend_info_app.py index a626d18b3173..bc30f8800b3e 100644 --- a/docs/backends/app/backend_info_app.py +++ b/docs/backends/app/backend_info_app.py @@ -3,7 +3,7 @@ import datetime import tempfile from pathlib import Path -from typing import List, Optional +from typing import Optional import pandas as pd import requests @@ -93,7 +93,7 @@ def get_all_operation_categories(): @st.cache_data(ttl=ONE_HOUR_IN_SECONDS) -def get_backend_names(categories: Optional[List[str]] = None): +def get_backend_names(categories: Optional[list[str]] = None): backend_expr = backend_info_table.mutate(category=_.categories.unnest()) if categories: backend_expr = backend_expr.filter(_.category.isin(categories)) diff --git a/ibis/backends/base/__init__.py b/ibis/backends/base/__init__.py index a63fb14e329a..17dd35418748 100644 --- a/ibis/backends/base/__init__.py +++ b/ibis/backends/base/__init__.py @@ -13,10 +13,6 @@ Any, Callable, ClassVar, - Iterable, - Iterator, - Mapping, - MutableMapping, ) import ibis @@ -28,6 +24,7 @@ from ibis.common.caching import RefCountedCache if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Mapping, MutableMapping from pathlib import Path import pandas as pd @@ -1109,7 +1106,7 @@ def _transpile_sql(self, query: str, *, dialect: str | None = None) -> str: return query -@functools.lru_cache(maxsize=None) +@functools.cache def _get_backend_names() -> frozenset[str]: """Return the set of known backend names. diff --git a/ibis/backends/base/df/scope.py b/ibis/backends/base/df/scope.py index 61a985766557..1d41da93464d 100644 --- a/ibis/backends/base/df/scope.py +++ b/ibis/backends/base/df/scope.py @@ -37,16 +37,18 @@ from __future__ import annotations from collections import namedtuple -from typing import TYPE_CHECKING, Any, Iterable, Tuple +from typing import TYPE_CHECKING, Any import pandas as pd from ibis.backends.base.df.timecontext import TimeContextRelation, compare_timecontext if TYPE_CHECKING: + from collections.abc import Iterable + from ibis.expr.operations import Node -TimeContext = Tuple[pd.Timestamp, pd.Timestamp] +TimeContext = tuple[pd.Timestamp, pd.Timestamp] ScopeItem = namedtuple("ScopeItem", ["timecontext", "value"]) diff --git a/ibis/backends/base/df/timecontext.py b/ibis/backends/base/df/timecontext.py index eacb1b435217..84608646ed88 100644 --- a/ibis/backends/base/df/timecontext.py +++ b/ibis/backends/base/df/timecontext.py @@ -43,7 +43,7 @@ import enum import functools -from typing import TYPE_CHECKING, Any, Tuple +from typing import TYPE_CHECKING, Any import pandas as pd @@ -51,7 +51,7 @@ import ibis.expr.operations as ops from ibis import config -TimeContext = Tuple[pd.Timestamp, pd.Timestamp] +TimeContext = tuple[pd.Timestamp, pd.Timestamp] if TYPE_CHECKING: diff --git a/ibis/backends/base/sql/__init__.py b/ibis/backends/base/sql/__init__.py index 8095c418c4d7..c14de468d789 100644 --- a/ibis/backends/base/sql/__init__.py +++ b/ibis/backends/base/sql/__init__.py @@ -4,7 +4,7 @@ import contextlib import os from functools import lru_cache -from typing import TYPE_CHECKING, Any, Iterable, Mapping +from typing import TYPE_CHECKING, Any import toolz @@ -17,6 +17,8 @@ from ibis.backends.base.sql.compiler import Compiler if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + import pandas as pd import pyarrow as pa diff --git a/ibis/backends/base/sql/alchemy/__init__.py b/ibis/backends/base/sql/alchemy/__init__.py index 7c1b64edbb3e..65e43d9764de 100644 --- a/ibis/backends/base/sql/alchemy/__init__.py +++ b/ibis/backends/base/sql/alchemy/__init__.py @@ -6,7 +6,7 @@ import getpass import warnings from operator import methodcaller -from typing import TYPE_CHECKING, Any, Iterable, Mapping +from typing import TYPE_CHECKING, Any import sqlalchemy as sa from sqlalchemy.ext.compiler import compiles @@ -41,6 +41,8 @@ from ibis.formats.pandas import PandasData if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + import pandas as pd import pyarrow as pa diff --git a/ibis/backends/base/sql/alchemy/datatypes.py b/ibis/backends/base/sql/alchemy/datatypes.py index e99569b7e99d..e9ba56472daf 100644 --- a/ibis/backends/base/sql/alchemy/datatypes.py +++ b/ibis/backends/base/sql/alchemy/datatypes.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Mapping +from typing import TYPE_CHECKING import sqlalchemy as sa import sqlalchemy.types as sat @@ -12,6 +12,9 @@ from ibis.common.collections import FrozenDict from ibis.formats import TypeMapper +if TYPE_CHECKING: + from collections.abc import Mapping + if geospatial_supported: import geoalchemy2 as ga diff --git a/ibis/backends/base/sql/compiler/query_builder.py b/ibis/backends/base/sql/compiler/query_builder.py index 6f632805856d..3fcb6657ccb3 100644 --- a/ibis/backends/base/sql/compiler/query_builder.py +++ b/ibis/backends/base/sql/compiler/query_builder.py @@ -1,7 +1,7 @@ from __future__ import annotations from io import StringIO -from typing import Iterable +from typing import TYPE_CHECKING import sqlglot as sg import toolz @@ -17,6 +17,9 @@ from ibis.common.grounds import Comparable from ibis.config import options +if TYPE_CHECKING: + from collections.abc import Iterable + class TableSetFormatter: _join_names = { diff --git a/ibis/backends/base/sql/compiler/translator.py b/ibis/backends/base/sql/compiler/translator.py index 3efdee3c8d0e..1d2df023c71b 100644 --- a/ibis/backends/base/sql/compiler/translator.py +++ b/ibis/backends/base/sql/compiler/translator.py @@ -2,13 +2,16 @@ import contextlib import itertools -from typing import Callable, Iterable, Iterator +from typing import TYPE_CHECKING, Callable import ibis import ibis.common.exceptions as com import ibis.expr.operations as ops from ibis.backends.base.sql.registry import operation_registry, quote_identifier +if TYPE_CHECKING: + from collections.abc import Iterable, Iterator + class QueryContext: """Records bits of information used during ibis AST to SQL translation. diff --git a/ibis/backends/base/sql/registry/geospatial.py b/ibis/backends/base/sql/registry/geospatial.py index 0957b66897b7..7e8fb4da5a96 100644 --- a/ibis/backends/base/sql/registry/geospatial.py +++ b/ibis/backends/base/sql/registry/geospatial.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Iterable, List, TypeVar +from collections.abc import Iterable +from typing import TYPE_CHECKING, TypeVar import ibis.expr.datatypes as dt from ibis.common import exceptions as ex @@ -13,12 +14,12 @@ NumberType = TypeVar("NumberType", int, float) # Geometry primitives (2D) PointType = Iterable[NumberType] -LineStringType = List[PointType] -PolygonType = List[LineStringType] +LineStringType = list[PointType] +PolygonType = list[LineStringType] # Multipart geometries (2D) -MultiPointType = List[PointType] -MultiLineStringType = List[LineStringType] -MultiPolygonType = List[PolygonType] +MultiPointType = list[PointType] +MultiLineStringType = list[LineStringType] +MultiPolygonType = list[PolygonType] def _format_point_value(value: PointType) -> str: diff --git a/ibis/backends/bigquery/__init__.py b/ibis/backends/bigquery/__init__.py index 1a647d45bb03..20e3e41c9265 100644 --- a/ibis/backends/bigquery/__init__.py +++ b/ibis/backends/bigquery/__init__.py @@ -4,7 +4,7 @@ import contextlib import warnings -from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping +from typing import TYPE_CHECKING, Any, Callable from urllib.parse import parse_qs, urlparse import google.auth.credentials @@ -35,6 +35,8 @@ from ibis.backends.bigquery.udf import udf # noqa: F401 if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + import pyarrow as pa from google.cloud.bigquery.table import RowIterator diff --git a/ibis/backends/bigquery/tests/conftest.py b/ibis/backends/bigquery/tests/conftest.py index 909afdb3c41e..b5fbd5a37d84 100644 --- a/ibis/backends/bigquery/tests/conftest.py +++ b/ibis/backends/bigquery/tests/conftest.py @@ -5,7 +5,7 @@ import functools import io import os -from typing import TYPE_CHECKING, Any, Mapping +from typing import TYPE_CHECKING, Any import google.api_core.exceptions as gexc import google.auth @@ -22,6 +22,8 @@ from ibis.backends.tests.data import json_types, non_null_array_types, struct_types, win if TYPE_CHECKING: + from collections.abc import Mapping + import ibis.expr.types as ir DATASET_ID = "ibis_gbq_testing" diff --git a/ibis/backends/bigquery/udf/__init__.py b/ibis/backends/bigquery/udf/__init__.py index 6c0597baf7f9..5249d419d42b 100644 --- a/ibis/backends/bigquery/udf/__init__.py +++ b/ibis/backends/bigquery/udf/__init__.py @@ -3,7 +3,7 @@ import collections import inspect import itertools -from typing import Callable, Iterable, Literal, Mapping +from typing import TYPE_CHECKING, Callable, Literal import ibis.expr.datatypes as dt import ibis.expr.rules as rlz @@ -12,6 +12,9 @@ from ibis.backends.bigquery.udf.core import PythonToJavaScriptTranslator from ibis.legacy.udf.validate import validate_output_type +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + __all__ = ("udf",) _udf_name_cache: dict[str, Iterable[int]] = collections.defaultdict(itertools.count) diff --git a/ibis/backends/clickhouse/__init__.py b/ibis/backends/clickhouse/__init__.py index 8c4193aee44f..a216c381d258 100644 --- a/ibis/backends/clickhouse/__init__.py +++ b/ibis/backends/clickhouse/__init__.py @@ -4,7 +4,7 @@ import json from contextlib import closing, suppress from functools import partial -from typing import TYPE_CHECKING, Any, Iterable, Iterator, Literal, Mapping +from typing import TYPE_CHECKING, Any, Literal import clickhouse_connect as cc import pyarrow as pa @@ -25,6 +25,7 @@ from ibis.backends.clickhouse.datatypes import parse, serialize if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Mapping from pathlib import Path import pandas as pd diff --git a/ibis/backends/clickhouse/compiler/core.py b/ibis/backends/clickhouse/compiler/core.py index e03851ee6216..b485f83c8cf8 100644 --- a/ibis/backends/clickhouse/compiler/core.py +++ b/ibis/backends/clickhouse/compiler/core.py @@ -41,7 +41,7 @@ from __future__ import annotations -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any import sqlglot as sg @@ -49,6 +49,9 @@ import ibis.expr.types as ir from ibis.backends.clickhouse.compiler.relations import translate_rel +if TYPE_CHECKING: + from collections.abc import Mapping + def translate(op: ops.TableNode, params: Mapping[ir.Value, Any]) -> sg.exp.Expression: """Translate an ibis operation to a sqlglot expression. diff --git a/ibis/backends/clickhouse/compiler/values.py b/ibis/backends/clickhouse/compiler/values.py index b31ba134301d..19f67e02fe72 100644 --- a/ibis/backends/clickhouse/compiler/values.py +++ b/ibis/backends/clickhouse/compiler/values.py @@ -5,7 +5,7 @@ import functools from functools import partial from operator import add, mul, sub -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any import sqlglot as sg from sqlglot.dialects.dialect import rename_func @@ -19,6 +19,9 @@ from ibis.backends.base.sql.registry import helpers from ibis.backends.clickhouse.datatypes import serialize +if TYPE_CHECKING: + from collections.abc import Mapping + # TODO: Ideally we can translate bottom up a la `relations.py` # TODO: Find a way to remove all the dialect="clickhouse" kwargs diff --git a/ibis/backends/clickhouse/datatypes.py b/ibis/backends/clickhouse/datatypes.py index be378798316a..0ae2714afba5 100644 --- a/ibis/backends/clickhouse/datatypes.py +++ b/ibis/backends/clickhouse/datatypes.py @@ -1,7 +1,7 @@ from __future__ import annotations import functools -from typing import TYPE_CHECKING, Literal, Mapping +from typing import TYPE_CHECKING, Literal import sqlglot as sg from sqlglot.expressions import ColumnDef, DataType @@ -12,6 +12,8 @@ from ibis.formats.parser import TypeParser if TYPE_CHECKING: + from collections.abc import Mapping + from sqlglot.expressions import DataTypeSize, Expression diff --git a/ibis/backends/clickhouse/tests/conftest.py b/ibis/backends/clickhouse/tests/conftest.py index e6938d49fef2..325df7756c39 100644 --- a/ibis/backends/clickhouse/tests/conftest.py +++ b/ibis/backends/clickhouse/tests/conftest.py @@ -2,7 +2,7 @@ import contextlib import os -from typing import TYPE_CHECKING, Any, Callable, Iterable +from typing import TYPE_CHECKING, Any, Callable import pytest @@ -16,6 +16,7 @@ ) if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path CLICKHOUSE_HOST = os.environ.get("IBIS_TEST_CLICKHOUSE_HOST", "localhost") diff --git a/ibis/backends/conftest.py b/ibis/backends/conftest.py index c9ee5f5fbc35..115c273d3d16 100644 --- a/ibis/backends/conftest.py +++ b/ibis/backends/conftest.py @@ -5,9 +5,9 @@ import importlib.metadata import itertools import sys -from functools import lru_cache +from functools import cache from pathlib import Path -from typing import Any, Iterable +from typing import TYPE_CHECKING, Any import _pytest import numpy as np @@ -23,6 +23,9 @@ from ibis.backends.base import CanCreateDatabase, CanCreateSchema, _get_backend_names from ibis.conftest import WINDOWS +if TYPE_CHECKING: + from collections.abc import Iterable + TEST_TABLES = { "functional_alltypes": ibis.schema( { @@ -327,7 +330,7 @@ def pytest_collection_modifyitems(session, config, items): item.add_marker(marker) -@lru_cache(maxsize=None) +@cache def _get_backends_to_test( keep: tuple[str, ...] = (), discard: tuple[str, ...] = (), diff --git a/ibis/backends/dask/__init__.py b/ibis/backends/dask/__init__.py index 0c30b7367b5c..88ef89a9cdf6 100644 --- a/ibis/backends/dask/__init__.py +++ b/ibis/backends/dask/__init__.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Mapping, MutableMapping +from typing import TYPE_CHECKING, Any import dask import dask.dataframe as dd @@ -19,6 +19,9 @@ from ibis.backends.pandas.core import _apply_schema from ibis.formats.pandas import DaskData +if TYPE_CHECKING: + from collections.abc import Mapping, MutableMapping + # Make sure that the pandas backend options have been loaded ibis.pandas # noqa: B018 diff --git a/ibis/backends/dask/aggcontext.py b/ibis/backends/dask/aggcontext.py index cea156eabceb..b2c20b1fba3b 100644 --- a/ibis/backends/dask/aggcontext.py +++ b/ibis/backends/dask/aggcontext.py @@ -1,7 +1,7 @@ from __future__ import annotations import operator -from typing import TYPE_CHECKING, Any, Callable, Dict, Tuple, Union +from typing import TYPE_CHECKING, Any, Callable, Union import dask.dataframe as dd @@ -53,8 +53,8 @@ def dask_window_agg_built_in( windowed: dd.rolling.Rolling, function: str, max_lookback: int, - *args: Tuple[Any], - **kwargs: Dict[str, Any], + *args: tuple[Any], + **kwargs: dict[str, Any], ) -> dd.Series: """Apply window aggregation with built-in aggregators.""" assert isinstance(function, str) diff --git a/ibis/backends/dask/core.py b/ibis/backends/dask/core.py index 8d4dbec2b178..df5b04a1b44a 100644 --- a/ibis/backends/dask/core.py +++ b/ibis/backends/dask/core.py @@ -111,7 +111,7 @@ from __future__ import annotations import functools -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any import dask.dataframe as dd from multipledispatch import Dispatcher @@ -135,6 +135,9 @@ is_computable_input_arg, ) +if TYPE_CHECKING: + from collections.abc import Mapping + is_computable_input.register(dd.core.Scalar)(is_computable_input_arg) diff --git a/ibis/backends/dask/execution/util.py b/ibis/backends/dask/execution/util.py index 16cd38405e31..925ae2edc04d 100644 --- a/ibis/backends/dask/execution/util.py +++ b/ibis/backends/dask/execution/util.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Tuple, Type, Union +from typing import TYPE_CHECKING, Any, Callable, Union import dask.dataframe as dd import dask.delayed @@ -21,10 +21,10 @@ from ibis.backends.pandas.trace import TraceTwoLevelDispatcher from ibis.expr.operations.sortkeys import SortKey -DispatchRule = Tuple[Tuple[Union[Type, Tuple], ...], Callable] +DispatchRule = tuple[tuple[Union[type, tuple], ...], Callable] -TypeRegistrationDict = Dict[ - Union[Type[ops.Node], Tuple[Type[ops.Node], ...]], List[DispatchRule] +TypeRegistrationDict = dict[ + Union[type[ops.Node], tuple[type[ops.Node], ...]], list[DispatchRule] ] diff --git a/ibis/backends/datafusion/__init__.py b/ibis/backends/datafusion/__init__.py index 3fc073e55f9d..3bb608a0b32c 100644 --- a/ibis/backends/datafusion/__init__.py +++ b/ibis/backends/datafusion/__init__.py @@ -3,7 +3,7 @@ import re from functools import lru_cache from pathlib import Path -from typing import TYPE_CHECKING, Any, Mapping +from typing import TYPE_CHECKING, Any import datafusion import pyarrow as pa @@ -27,6 +27,8 @@ SessionConfig = None if TYPE_CHECKING: + from collections.abc import Mapping + import pandas as pd diff --git a/ibis/backends/druid/__init__.py b/ibis/backends/druid/__init__.py index b6c4d025f3e5..83acf5d72140 100644 --- a/ibis/backends/druid/__init__.py +++ b/ibis/backends/druid/__init__.py @@ -5,7 +5,7 @@ import contextlib import json import warnings -from typing import Any, Iterable +from typing import TYPE_CHECKING, Any import sqlalchemy as sa @@ -14,6 +14,9 @@ from ibis.backends.base.sql.alchemy import BaseAlchemyBackend from ibis.backends.druid.compiler import DruidCompiler +if TYPE_CHECKING: + from collections.abc import Iterable + class Backend(BaseAlchemyBackend): name = "druid" diff --git a/ibis/backends/druid/datatypes.py b/ibis/backends/druid/datatypes.py index 9932380b1a96..362c0577f3ef 100644 --- a/ibis/backends/druid/datatypes.py +++ b/ibis/backends/druid/datatypes.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Mapping +from typing import TYPE_CHECKING import sqlalchemy as sa import sqlalchemy.types as sat @@ -12,6 +12,9 @@ from ibis.common.collections import FrozenDict from ibis.formats.parser import TypeParser +if TYPE_CHECKING: + from collections.abc import Mapping + class DruidDateTime(sat.TypeDecorator): impl = sa.TIMESTAMP diff --git a/ibis/backends/druid/tests/conftest.py b/ibis/backends/druid/tests/conftest.py index f31899cdf925..88704efd5141 100644 --- a/ibis/backends/druid/tests/conftest.py +++ b/ibis/backends/druid/tests/conftest.py @@ -6,7 +6,7 @@ import time from concurrent.futures import ThreadPoolExecutor, as_completed from itertools import chain, repeat -from typing import TYPE_CHECKING, Any, Iterable +from typing import TYPE_CHECKING, Any import pytest from requests import Session @@ -15,6 +15,7 @@ from ibis.backends.tests.base import RoundHalfToEven, ServiceBackendTest if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path DRUID_URL = os.environ.get( diff --git a/ibis/backends/duckdb/__init__.py b/ibis/backends/duckdb/__init__.py index bff3ac89cc43..a945c8a429c4 100644 --- a/ibis/backends/duckdb/__init__.py +++ b/ibis/backends/duckdb/__init__.py @@ -11,10 +11,6 @@ from typing import ( TYPE_CHECKING, Any, - Iterable, - Iterator, - Mapping, - MutableMapping, ) import duckdb @@ -38,6 +34,8 @@ from ibis.formats.pandas import PandasData if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Mapping, MutableMapping + import pandas as pd import torch diff --git a/ibis/backends/duckdb/registry.py b/ibis/backends/duckdb/registry.py index a8cf8a946782..de339710d292 100644 --- a/ibis/backends/duckdb/registry.py +++ b/ibis/backends/duckdb/registry.py @@ -2,7 +2,7 @@ import operator from functools import partial -from typing import TYPE_CHECKING, Any, Mapping +from typing import TYPE_CHECKING, Any import duckdb import numpy as np @@ -35,6 +35,8 @@ from ibis.common.exceptions import UnsupportedOperationError if TYPE_CHECKING: + from collections.abc import Mapping + from ibis.backends.base.sql.alchemy.datatypes import StructType operation_registry = { diff --git a/ibis/backends/duckdb/tests/conftest.py b/ibis/backends/duckdb/tests/conftest.py index 9aee00cb8b1a..4aed87dbd343 100644 --- a/ibis/backends/duckdb/tests/conftest.py +++ b/ibis/backends/duckdb/tests/conftest.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Iterator +from typing import TYPE_CHECKING import pytest @@ -10,6 +10,8 @@ from ibis.conftest import SANDBOXED if TYPE_CHECKING: + from collections.abc import Iterator + from ibis.backends.base import BaseBackend diff --git a/ibis/backends/mssql/__init__.py b/ibis/backends/mssql/__init__.py index d5687a3df58a..a416b3288235 100644 --- a/ibis/backends/mssql/__init__.py +++ b/ibis/backends/mssql/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Iterable, Literal, Mapping +from typing import TYPE_CHECKING, Any, Literal import sqlalchemy as sa import toolz @@ -13,6 +13,8 @@ from ibis.backends.mssql.datatypes import _type_from_result_set_info if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + import ibis.expr.schema as sch import ibis.expr.types as ir diff --git a/ibis/backends/mssql/tests/conftest.py b/ibis/backends/mssql/tests/conftest.py index ec5ba3b6a8d6..6f8ef88d58c6 100644 --- a/ibis/backends/mssql/tests/conftest.py +++ b/ibis/backends/mssql/tests/conftest.py @@ -1,7 +1,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Any, Iterable +from typing import TYPE_CHECKING, Any import pytest import sqlalchemy as sa @@ -11,6 +11,7 @@ from ibis.backends.tests.base import RoundHalfToEven, ServiceBackendTest if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path MSSQL_USER = os.environ.get("IBIS_TEST_MSSQL_USER", "sa") diff --git a/ibis/backends/mysql/__init__.py b/ibis/backends/mysql/__init__.py index 9d5c845a4c93..47639cf41a97 100644 --- a/ibis/backends/mysql/__init__.py +++ b/ibis/backends/mysql/__init__.py @@ -4,7 +4,7 @@ import re import warnings -from typing import TYPE_CHECKING, Iterable, Literal +from typing import TYPE_CHECKING, Literal import sqlalchemy as sa from sqlalchemy.dialects import mysql @@ -15,6 +15,8 @@ from ibis.backends.mysql.datatypes import MySQLDateTime, _type_from_cursor_info if TYPE_CHECKING: + from collections.abc import Iterable + import ibis.expr.datatypes as dt diff --git a/ibis/backends/mysql/tests/conftest.py b/ibis/backends/mysql/tests/conftest.py index 32831153ca57..d2e77d47704a 100644 --- a/ibis/backends/mysql/tests/conftest.py +++ b/ibis/backends/mysql/tests/conftest.py @@ -1,7 +1,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Any, Iterable +from typing import TYPE_CHECKING, Any import pytest import sqlalchemy as sa @@ -12,6 +12,7 @@ from ibis.backends.tests.base import RoundHalfToEven, ServiceBackendTest if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path MYSQL_USER = os.environ.get("IBIS_TEST_MYSQL_USER", "ibis") diff --git a/ibis/backends/oracle/__init__.py b/ibis/backends/oracle/__init__.py index 9e72a900bd52..ae9cfd91629b 100644 --- a/ibis/backends/oracle/__init__.py +++ b/ibis/backends/oracle/__init__.py @@ -5,6 +5,7 @@ import atexit import contextlib import sys +from typing import TYPE_CHECKING, Any import oracledb @@ -21,8 +22,6 @@ sys.modules["cx_Oracle"] = oracledb -from typing import TYPE_CHECKING, Any, Iterable # noqa: E402 - import sqlalchemy as sa # noqa: E402 import ibis.expr.datatypes as dt # noqa: E402 @@ -39,6 +38,8 @@ from ibis.backends.oracle.registry import operation_registry # noqa: E402 if TYPE_CHECKING: + from collections.abc import Iterable + import ibis.expr.schema as sch diff --git a/ibis/backends/oracle/tests/conftest.py b/ibis/backends/oracle/tests/conftest.py index 298e247cd128..0d140ebaa7aa 100644 --- a/ibis/backends/oracle/tests/conftest.py +++ b/ibis/backends/oracle/tests/conftest.py @@ -5,7 +5,7 @@ import itertools import os import subprocess -from typing import TYPE_CHECKING, Any, Iterable +from typing import TYPE_CHECKING, Any import pytest import sqlalchemy as sa @@ -14,6 +14,7 @@ from ibis.backends.tests.base import RoundHalfToEven, ServiceBackendTest if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path ORACLE_USER = os.environ.get("IBIS_TEST_ORACLE_USER", "ibis") diff --git a/ibis/backends/pandas/__init__.py b/ibis/backends/pandas/__init__.py index ab579c0d9354..97bf9f0961fa 100644 --- a/ibis/backends/pandas/__init__.py +++ b/ibis/backends/pandas/__init__.py @@ -2,7 +2,7 @@ import importlib from functools import lru_cache -from typing import Any, Mapping, MutableMapping +from typing import TYPE_CHECKING, Any import pandas as pd import pyarrow as pa @@ -16,6 +16,9 @@ from ibis.formats.pandas import PandasData, PandasSchema from ibis.formats.pyarrow import PyArrowData +if TYPE_CHECKING: + from collections.abc import Mapping, MutableMapping + class BasePandasBackend(BaseBackend): """Base class for backends based on pandas.""" diff --git a/ibis/backends/pandas/aggcontext.py b/ibis/backends/pandas/aggcontext.py index f160bc4c841e..f58b6d7bc2b3 100644 --- a/ibis/backends/pandas/aggcontext.py +++ b/ibis/backends/pandas/aggcontext.py @@ -220,7 +220,7 @@ import functools import itertools import operator -from typing import TYPE_CHECKING, Any, Callable, Iterator +from typing import TYPE_CHECKING, Any, Callable import pandas as pd from pandas.core.groupby import SeriesGroupBy @@ -236,6 +236,8 @@ ) if TYPE_CHECKING: + from collections.abc import Iterator + import numpy as np diff --git a/ibis/backends/pandas/core.py b/ibis/backends/pandas/core.py index 128db82d64cd..ef29b2bb29cc 100644 --- a/ibis/backends/pandas/core.py +++ b/ibis/backends/pandas/core.py @@ -110,7 +110,7 @@ import datetime import functools import numbers -from typing import Any, Callable, Iterable, Mapping +from typing import TYPE_CHECKING, Any, Callable import numpy as np import pandas as pd @@ -132,6 +132,9 @@ ) from ibis.backends.pandas.trace import trace +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + integer_types = np.integer, int floating_types = (numbers.Real,) numeric_types = integer_types + floating_types diff --git a/ibis/backends/pandas/execution/arrays.py b/ibis/backends/pandas/execution/arrays.py index 234d4c49936a..167e74885b63 100644 --- a/ibis/backends/pandas/execution/arrays.py +++ b/ibis/backends/pandas/execution/arrays.py @@ -2,7 +2,7 @@ import operator from functools import partial -from typing import Any, Collection +from typing import TYPE_CHECKING, Any import numpy as np import pandas as pd @@ -12,6 +12,9 @@ from ibis.backends.pandas.core import execute from ibis.backends.pandas.dispatch import execute_node +if TYPE_CHECKING: + from collections.abc import Collection + @execute_node.register(ops.ArrayColumn, tuple) def execute_array_column(op, cols, **kwargs): diff --git a/ibis/backends/pandas/execution/selection.py b/ibis/backends/pandas/execution/selection.py index 8beec3355713..b1f8a0ee6659 100644 --- a/ibis/backends/pandas/execution/selection.py +++ b/ibis/backends/pandas/execution/selection.py @@ -5,7 +5,7 @@ import functools import operator from collections import defaultdict -from typing import TYPE_CHECKING, Any, Iterable +from typing import TYPE_CHECKING, Any import pandas as pd from toolz import concatv, first @@ -20,6 +20,8 @@ from ibis.backends.pandas.execution.util import coerce_to_output if TYPE_CHECKING: + from collections.abc import Iterable + from ibis.backends.base.df.timecontext import TimeContext diff --git a/ibis/backends/polars/__init__.py b/ibis/backends/polars/__init__.py index b29438d6b44b..c13c10c5bb24 100644 --- a/ibis/backends/polars/__init__.py +++ b/ibis/backends/polars/__init__.py @@ -2,7 +2,7 @@ from functools import lru_cache from pathlib import Path -from typing import TYPE_CHECKING, Any, Iterable, Mapping, MutableMapping +from typing import TYPE_CHECKING, Any import polars as pl @@ -18,6 +18,8 @@ from ibis.util import gen_name, normalize_filename if TYPE_CHECKING: + from collections.abc import Iterable, Mapping, MutableMapping + import pandas as pd import pyarrow as pa diff --git a/ibis/backends/polars/compiler.py b/ibis/backends/polars/compiler.py index 8766d4336f8e..3a6a0cac7e9f 100644 --- a/ibis/backends/polars/compiler.py +++ b/ibis/backends/polars/compiler.py @@ -4,8 +4,8 @@ import functools import math import operator +from collections.abc import Mapping from functools import partial -from typing import Mapping import numpy as np import pandas as pd diff --git a/ibis/backends/postgres/__init__.py b/ibis/backends/postgres/__init__.py index cdea9ed43cda..862bc3b519bb 100644 --- a/ibis/backends/postgres/__init__.py +++ b/ibis/backends/postgres/__init__.py @@ -4,7 +4,7 @@ import inspect import textwrap -from typing import TYPE_CHECKING, Callable, Iterable, Literal +from typing import TYPE_CHECKING, Callable, Literal import sqlalchemy as sa @@ -17,6 +17,8 @@ from ibis.common.exceptions import InvalidDecoratorError if TYPE_CHECKING: + from collections.abc import Iterable + import ibis.expr.datatypes as dt diff --git a/ibis/backends/postgres/datatypes.py b/ibis/backends/postgres/datatypes.py index 855e34867284..33b9ab1a97a8 100644 --- a/ibis/backends/postgres/datatypes.py +++ b/ibis/backends/postgres/datatypes.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Mapping +from typing import TYPE_CHECKING import sqlalchemy as sa import sqlalchemy.dialects.postgresql as psql @@ -11,6 +11,9 @@ from ibis.common.collections import FrozenDict from ibis.formats.parser import TypeParser +if TYPE_CHECKING: + from collections.abc import Mapping + class PostgresTypeParser(TypeParser): __slots__ = () diff --git a/ibis/backends/postgres/tests/conftest.py b/ibis/backends/postgres/tests/conftest.py index 95c4e147f218..bb8237e4379e 100644 --- a/ibis/backends/postgres/tests/conftest.py +++ b/ibis/backends/postgres/tests/conftest.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import os -from typing import TYPE_CHECKING, Any, Iterable +from typing import TYPE_CHECKING, Any import pytest import sqlalchemy as sa @@ -24,6 +24,7 @@ from ibis.backends.tests.base import RoundHalfToEven, ServiceBackendTest if TYPE_CHECKING: + from collections.abc import Iterable from pathlib import Path PG_USER = os.environ.get( diff --git a/ibis/backends/postgres/udf.py b/ibis/backends/postgres/udf.py index b29eb6b32fd9..c0d793d87976 100644 --- a/ibis/backends/postgres/udf.py +++ b/ibis/backends/postgres/udf.py @@ -4,7 +4,7 @@ import inspect import itertools from textwrap import dedent -from typing import Any, Callable, MutableMapping, Sequence +from typing import TYPE_CHECKING, Any, Callable import sqlalchemy as sa from sqlalchemy.dialects.postgresql import dialect @@ -17,6 +17,9 @@ from ibis.backends.postgres.datatypes import PostgresType from ibis.legacy.udf.validate import validate_output_type +if TYPE_CHECKING: + from collections.abc import MutableMapping, Sequence + _udf_name_cache: MutableMapping[str, Any] = collections.defaultdict(itertools.count) _postgres_dialect = dialect() diff --git a/ibis/backends/pyspark/client.py b/ibis/backends/pyspark/client.py index 69d72fe5f50b..55293dde023d 100644 --- a/ibis/backends/pyspark/client.py +++ b/ibis/backends/pyspark/client.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Iterable, Mapping +from typing import TYPE_CHECKING, Any import sqlglot as sg @@ -10,6 +10,8 @@ from ibis.backends.pyspark import ddl if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + import pandas as pd diff --git a/ibis/backends/snowflake/__init__.py b/ibis/backends/snowflake/__init__.py index 5ca44f08c116..0c97b13d10ef 100644 --- a/ibis/backends/snowflake/__init__.py +++ b/ibis/backends/snowflake/__init__.py @@ -12,7 +12,7 @@ import textwrap import warnings from pathlib import Path -from typing import TYPE_CHECKING, Any, Iterable, Iterator, Mapping +from typing import TYPE_CHECKING, Any import pyarrow as pa import sqlalchemy as sa @@ -38,6 +38,8 @@ from ibis.backends.snowflake.registry import operation_registry if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Mapping + import pandas as pd import ibis.expr.schema as sch diff --git a/ibis/backends/sqlite/__init__.py b/ibis/backends/sqlite/__init__.py index 87a3a167558b..d87b556a1f15 100644 --- a/ibis/backends/sqlite/__init__.py +++ b/ibis/backends/sqlite/__init__.py @@ -16,7 +16,7 @@ import inspect import sqlite3 -from typing import TYPE_CHECKING, Iterator +from typing import TYPE_CHECKING import sqlalchemy as sa import toolz @@ -33,6 +33,7 @@ from ibis.backends.sqlite.datatypes import ISODATETIME, SqliteType, parse if TYPE_CHECKING: + from collections.abc import Iterator from pathlib import Path import ibis.expr.operations as ops diff --git a/ibis/backends/tests/base.py b/ibis/backends/tests/base.py index c67eda75f29c..15351fe0d8f0 100644 --- a/ibis/backends/tests/base.py +++ b/ibis/backends/tests/base.py @@ -5,7 +5,7 @@ import inspect import subprocess from pathlib import Path -from typing import TYPE_CHECKING, Any, Iterable, Iterator, Mapping +from typing import TYPE_CHECKING, Any import numpy as np import pandas as pd @@ -15,6 +15,8 @@ from filelock import FileLock if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Mapping + import ibis.expr.types as ir diff --git a/ibis/backends/tests/test_register.py b/ibis/backends/tests/test_register.py index 1426be80acb2..13605bb0dbce 100644 --- a/ibis/backends/tests/test_register.py +++ b/ibis/backends/tests/test_register.py @@ -5,7 +5,7 @@ import gzip import os from pathlib import Path -from typing import TYPE_CHECKING, Iterator +from typing import TYPE_CHECKING import pytest from pytest import param @@ -14,6 +14,8 @@ from ibis.backends.conftest import TEST_TABLES if TYPE_CHECKING: + from collections.abc import Iterator + import pyarrow as pa pytestmark = pytest.mark.notimpl(["druid", "oracle"]) diff --git a/ibis/backends/trino/__init__.py b/ibis/backends/trino/__init__.py index db2186673a5e..08c1135fdf88 100644 --- a/ibis/backends/trino/__init__.py +++ b/ibis/backends/trino/__init__.py @@ -6,7 +6,7 @@ import contextlib import warnings from functools import cached_property -from typing import TYPE_CHECKING, Any, Iterator, Mapping +from typing import TYPE_CHECKING, Any import pandas as pd import sqlalchemy as sa @@ -25,6 +25,8 @@ from ibis.backends.trino.datatypes import ROW, TrinoType, parse if TYPE_CHECKING: + from collections.abc import Iterator, Mapping + import pyarrow as pa import ibis.expr.schema as sch diff --git a/ibis/backends/trino/datatypes.py b/ibis/backends/trino/datatypes.py index d3254c1bd478..4e711d9dcfe4 100644 --- a/ibis/backends/trino/datatypes.py +++ b/ibis/backends/trino/datatypes.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Mapping +from typing import TYPE_CHECKING, Any import sqlalchemy.types as sat import trino.client @@ -13,6 +13,9 @@ from ibis.common.collections import FrozenDict from ibis.formats.parser import TypeParser +if TYPE_CHECKING: + from collections.abc import Mapping + class ROW(_ROW): _result_is_tuple = hasattr(trino.client, "NamedRowTuple") diff --git a/ibis/backends/trino/tests/conftest.py b/ibis/backends/trino/tests/conftest.py index 87c1270a879c..3b89b8e51354 100644 --- a/ibis/backends/trino/tests/conftest.py +++ b/ibis/backends/trino/tests/conftest.py @@ -1,7 +1,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Any, Iterable, Iterator +from typing import TYPE_CHECKING, Any import pandas as pd import pytest @@ -13,6 +13,7 @@ from ibis.backends.tests.data import struct_types if TYPE_CHECKING: + from collections.abc import Iterable, Iterator from pathlib import Path TRINO_USER = os.environ.get( diff --git a/ibis/common/bases.py b/ibis/common/bases.py index 20f219ed7da5..ac237ab74b2d 100644 --- a/ibis/common/bases.py +++ b/ibis/common/bases.py @@ -1,13 +1,15 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod -from typing import TYPE_CHECKING, Any, Mapping +from typing import TYPE_CHECKING, Any from weakref import WeakValueDictionary from ibis.common.caching import WeakCache from ibis.common.collections import FrozenDict if TYPE_CHECKING: + from collections.abc import Mapping + from typing_extensions import Self diff --git a/ibis/common/caching.py b/ibis/common/caching.py index 7ca559340329..e22ecaa40d85 100644 --- a/ibis/common/caching.py +++ b/ibis/common/caching.py @@ -3,7 +3,8 @@ import functools import weakref from collections import Counter, defaultdict -from typing import TYPE_CHECKING, Any, Callable, MutableMapping +from collections.abc import MutableMapping +from typing import TYPE_CHECKING, Any, Callable from bidict import bidict diff --git a/ibis/common/collections.py b/ibis/common/collections.py index 4451d9a5f130..0af615eaf4e9 100644 --- a/ibis/common/collections.py +++ b/ibis/common/collections.py @@ -1,9 +1,9 @@ from __future__ import annotations -from collections.abc import Iterator +from collections.abc import Hashable, Iterator, Mapping from itertools import tee from types import MappingProxyType -from typing import TYPE_CHECKING, Any, Hashable, Mapping, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from public import public diff --git a/ibis/common/egraph.py b/ibis/common/egraph.py index c1b1b833a72c..a9cb3bbf140e 100644 --- a/ibis/common/egraph.py +++ b/ibis/common/egraph.py @@ -3,15 +3,8 @@ import collections import itertools import math -from typing import ( - Any, - Hashable, - Iterable, - Iterator, - Mapping, - Set, - TypeVar, -) +from collections.abc import Hashable, Iterable, Iterator, Mapping +from typing import Any, TypeVar from ibis.common.graph import Node from ibis.util import promote_list @@ -19,7 +12,7 @@ K = TypeVar("K", bound=Hashable) -class DisjointSet(Mapping[K, Set[K]]): +class DisjointSet(Mapping[K, set[K]]): """Disjoint set data structure. Also known as union-find data structure. It is a data structure that keeps diff --git a/ibis/common/graph.py b/ibis/common/graph.py index f36119fbca29..2bfe95278f40 100644 --- a/ibis/common/graph.py +++ b/ibis/common/graph.py @@ -3,8 +3,8 @@ from abc import abstractmethod from collections import deque -from collections.abc import Hashable, Iterable, Iterator -from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Sequence +from collections.abc import Hashable, Iterable, Iterator, Sequence +from typing import TYPE_CHECKING, Any, Callable, Optional from ibis.common.collections import frozendict from ibis.common.patterns import NoMatch, pattern @@ -256,7 +256,7 @@ def fn(node, _, **kwargs): return self.map(fn, filter=filter)[self] -class Graph(Dict[Node, Sequence[Node]]): +class Graph(dict[Node, Sequence[Node]]): """A mapping-like graph data structure for easier graph traversal and manipulation. The data structure is a mapping of nodes to their children. The children are diff --git a/ibis/common/grounds.py b/ibis/common/grounds.py index 6854b2e259c8..1070084c6a04 100644 --- a/ibis/common/grounds.py +++ b/ibis/common/grounds.py @@ -5,7 +5,6 @@ from typing import ( Any, ClassVar, - Tuple, Union, get_origin, ) @@ -104,9 +103,9 @@ def __or__(self, other): class Annotable(Base, metaclass=AnnotableMeta): """Base class for objects with custom validation rules.""" - __argnames__: ClassVar[Tuple[str, ...]] + __argnames__: ClassVar[tuple[str, ...]] __attributes__: ClassVar[FrozenDict[str, Annotation]] - __match_args__: ClassVar[Tuple[str, ...]] + __match_args__: ClassVar[tuple[str, ...]] __signature__: ClassVar[Signature] @classmethod @@ -152,7 +151,7 @@ def __eq__(self, other) -> bool: ) @property - def __args__(self) -> Tuple[Any, ...]: + def __args__(self) -> tuple[Any, ...]: return tuple(getattr(self, name) for name in self.__argnames__) def copy(self, **overrides: Any) -> Annotable: @@ -202,7 +201,7 @@ def args(self): return self.__args__ @property - def argnames(self) -> Tuple[str, ...]: + def argnames(self) -> tuple[str, ...]: return self.__argnames__ def copy(self, **overrides) -> Self: diff --git a/ibis/common/patterns.py b/ibis/common/patterns.py index a198abf84d38..7e10518a1c13 100644 --- a/ibis/common/patterns.py +++ b/ibis/common/patterns.py @@ -9,19 +9,19 @@ from enum import Enum from inspect import Parameter from itertools import chain -from typing import Any as AnyType from typing import ( + Annotated, ForwardRef, Generic, # noqa: F401 Literal, Optional, - Tuple, TypeVar, Union, ) +from typing import Any as AnyType import toolz -from typing_extensions import Annotated, GenericMeta, Self, get_args, get_origin +from typing_extensions import GenericMeta, Self, get_args, get_origin from ibis.common.bases import Singleton, Slotted from ibis.common.collections import RewindableIterator, frozendict @@ -170,7 +170,7 @@ def from_typehint(cls, annot: type, allow_coercion: bool = True) -> Pattern: # in case of Callable without args we check for the Callable # protocol only return InstanceOf(Callable) - elif issubclass(origin, Tuple): + elif issubclass(origin, tuple): # construct validators for the tuple elements, but need to treat # variadic tuples differently, e.g. tuple[int, ...] is a variadic # tuple of integers, while tuple[int] is a tuple with a single int diff --git a/ibis/common/tests/test_annotations.py b/ibis/common/tests/test_annotations.py index bc5db5067399..db9d9d5bb41b 100644 --- a/ibis/common/tests/test_annotations.py +++ b/ibis/common/tests/test_annotations.py @@ -1,10 +1,9 @@ from __future__ import annotations import inspect -from typing import Union +from typing import Annotated, Union import pytest -from typing_extensions import Annotated # noqa: TCH002 from ibis.common.annotations import ( Argument, diff --git a/ibis/common/tests/test_egraph.py b/ibis/common/tests/test_egraph.py index be67e5844eb4..b31c527bac17 100644 --- a/ibis/common/tests/test_egraph.py +++ b/ibis/common/tests/test_egraph.py @@ -1,7 +1,7 @@ from __future__ import annotations import itertools -from typing import Any, Tuple +from typing import Any import pytest @@ -167,7 +167,7 @@ def test_enode_roundtrip(): class MySecondNode(Concrete, Node): a: int - b: Tuple[int, ...] + b: tuple[int, ...] def test_enode_roundtrip_with_variadic_arg(): @@ -187,7 +187,7 @@ class MyInt(Concrete, Node): class MyThirdNode(Concrete, Node): a: int - b: Tuple[MyInt, ...] + b: tuple[MyInt, ...] def test_enode_roundtrip_with_nested_arg(): diff --git a/ibis/common/tests/test_grounds.py b/ibis/common/tests/test_grounds.py index 4daf02281fe2..6e699172ad9e 100644 --- a/ibis/common/tests/test_grounds.py +++ b/ibis/common/tests/test_grounds.py @@ -3,7 +3,8 @@ import copy import pickle import weakref -from typing import Callable, Generic, Mapping, Optional, Sequence, Tuple, TypeVar, Union +from collections.abc import Mapping, Sequence +from typing import Callable, Generic, Optional, TypeVar, Union import pytest @@ -156,7 +157,7 @@ def __len__(self): class ConsMap(Map[K, V]): - head: Tuple[K, V] + head: tuple[K, V] rest: Map[K, V] def __getitem__(self, key): @@ -1000,12 +1001,12 @@ class Test2(Test, something="value", value="something"): def test_argument_order_using_optional_annotations(): class Case1(Annotable): - results: Optional[Tuple[int]] = () + results: Optional[tuple[int]] = () default: Optional[int] = None class SimpleCase1(Case1): base: int - cases: Optional[Tuple[int]] = () + cases: Optional[tuple[int]] = () class Case2(Annotable): results = optional(TupleOf(is_int), default=()) diff --git a/ibis/common/tests/test_patterns.py b/ibis/common/tests/test_patterns.py index ed3e6c264cc6..6f52ad279c3a 100644 --- a/ibis/common/tests/test_patterns.py +++ b/ibis/common/tests/test_patterns.py @@ -3,25 +3,23 @@ import re import sys from collections.abc import Callable as CallableABC +from collections.abc import Sequence from dataclasses import dataclass -from typing import ( - Any as AnyType, -) -from typing import ( +from typing import ( # noqa: UP035 + Annotated, Callable, - Dict, Generic, List, Literal, Optional, - Sequence, - Tuple, TypeVar, Union, ) +from typing import ( + Any as AnyType, +) import pytest -from typing_extensions import Annotated from ibis.common.annotations import ValidationError from ibis.common.collections import FrozenDict @@ -849,14 +847,14 @@ def test_pattern_decorator(): (Optional[Union[str, int]], Option(AnyOf(InstanceOf(str), InstanceOf(int)))), (Union[int, str], AnyOf(InstanceOf(int), InstanceOf(str))), (Annotated[int, Min(3)], AllOf(InstanceOf(int), Min(3))), - (List[int], SequenceOf(InstanceOf(int), list)), + (list[int], SequenceOf(InstanceOf(int), list)), ( - Tuple[int, float, str], + tuple[int, float, str], TupleOf((InstanceOf(int), InstanceOf(float), InstanceOf(str))), ), - (Tuple[int, ...], TupleOf(InstanceOf(int))), + (tuple[int, ...], TupleOf(InstanceOf(int))), ( - Dict[str, float], + dict[str, float], DictOf(InstanceOf(str), InstanceOf(float)), ), (FrozenDict[str, int], FrozenDictOf(InstanceOf(str), InstanceOf(int))), @@ -949,7 +947,7 @@ def test_pattern_coercible_checks_type(): assert v.match(1, context={}) is NoMatch -class DoubledList(Coercible, List[T]): +class DoubledList(Coercible, list[T]): @classmethod def __coerce__(cls, obj): return cls(list(obj) * 2) @@ -960,11 +958,11 @@ def test_pattern_coercible_sequence_type(): with pytest.raises(TypeError, match=r"Sequence\(\) takes no arguments"): s.match([1, 2, 3], context={}) - s = Pattern.from_typehint(List[PlusOne]) + s = Pattern.from_typehint(list[PlusOne]) assert s == SequenceOf(CoercedTo(PlusOne), type=list) assert s.match([1, 2, 3], context={}) == [PlusOne(2), PlusOne(3), PlusOne(4)] - s = Pattern.from_typehint(Tuple[PlusOne, ...]) + s = Pattern.from_typehint(tuple[PlusOne, ...]) assert s == TupleOf(CoercedTo(PlusOne)) assert s.match([1, 2, 3], context={}) == (PlusOne(2), PlusOne(3), PlusOne(4)) @@ -985,7 +983,7 @@ def __coerce__(cls, other): assert pattern(Any()) == Any() assert pattern(int) == InstanceOf(int) assert pattern(MyNegativeInt) == CoercedTo(MyNegativeInt) - assert pattern(List[int]) == ListOf(InstanceOf(int)) + assert pattern(List[int]) == ListOf(InstanceOf(int)) # noqa: UP006 assert pattern([int, str, 1]) == PatternSequence( [InstanceOf(int), InstanceOf(str), EqualTo(1)] ) diff --git a/ibis/common/typing.py b/ibis/common/typing.py index 9b2851f254d8..e0fde6bc87ea 100644 --- a/ibis/common/typing.py +++ b/ibis/common/typing.py @@ -4,16 +4,13 @@ from itertools import zip_longest from typing import ( Any, - Dict, Generic, # noqa: F401 Optional, - Tuple, TypeVar, get_args, get_origin, ) - -from typing_extensions import get_type_hints as _get_type_hints +from typing import get_type_hints as _get_type_hints from ibis.common.caching import memoize @@ -26,8 +23,8 @@ T = TypeVar("T") U = TypeVar("U") -Namespace = Dict[str, Any] -VarTuple = Tuple[T, ...] +Namespace = dict[str, Any] +VarTuple = tuple[T, ...] @memoize @@ -180,9 +177,9 @@ def evaluate_annotations( Examples -------- - >>> annots = {'a': 'Dict[str, float]', 'b': 'int'} + >>> annots = {'a': 'dict[str, float]', 'b': 'int'} >>> evaluate_annotations(annots, __name__) - {'a': typing.Dict[str, float], 'b': } + {'a': dict[str, float], 'b': } """ module = sys.modules.get(module_name, None) globalns = getattr(module, "__dict__", None) diff --git a/ibis/config.py b/ibis/config.py index c8c455c6246b..308db061402a 100644 --- a/ibis/config.py +++ b/ibis/config.py @@ -1,10 +1,9 @@ from __future__ import annotations import contextlib -from typing import Any, Callable, Optional +from typing import Annotated, Any, Callable, Optional from public import public -from typing_extensions import Annotated import ibis.common.exceptions as com from ibis.common.grounds import Annotable diff --git a/ibis/examples/gen_registry.py b/ibis/examples/gen_registry.py index 51dd20fe2fcd..91ef3ac23306 100755 --- a/ibis/examples/gen_registry.py +++ b/ibis/examples/gen_registry.py @@ -11,7 +11,7 @@ import zipfile from collections import Counter, defaultdict from pathlib import Path -from typing import Iterable, Mapping +from typing import TYPE_CHECKING import pooch import requests @@ -19,6 +19,9 @@ import ibis +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + EXAMPLES_DIRECTORY = Path(__file__).parent diff --git a/ibis/expr/analysis.py b/ibis/expr/analysis.py index e1c53d9d21be..46cfd8fdedf1 100644 --- a/ibis/expr/analysis.py +++ b/ibis/expr/analysis.py @@ -3,7 +3,7 @@ import functools import operator from collections import defaultdict -from typing import Iterable, Iterator, Mapping +from typing import TYPE_CHECKING import toolz @@ -16,6 +16,9 @@ from ibis.common.exceptions import IbisTypeError, IntegrityError from ibis.common.patterns import Call, Object, Variable +if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Mapping + p = Object.namespace(ops) c = Call.namespace(ops) diff --git a/ibis/expr/api.py b/ibis/expr/api.py index 741a931e2c08..48acba6f4584 100644 --- a/ibis/expr/api.py +++ b/ibis/expr/api.py @@ -6,7 +6,7 @@ import functools import numbers import operator -from typing import TYPE_CHECKING, Any, Iterable, NamedTuple, Sequence, TypeVar +from typing import TYPE_CHECKING, Any, NamedTuple, TypeVar import ibis.expr.builders as bl import ibis.expr.datatypes as dt @@ -36,6 +36,7 @@ from ibis.util import experimental if TYPE_CHECKING: + from collections.abc import Iterable, Sequence from pathlib import Path import numpy as np diff --git a/ibis/expr/datatypes/cast.py b/ibis/expr/datatypes/cast.py index 9a642100cd6a..70d3789d9706 100644 --- a/ibis/expr/datatypes/cast.py +++ b/ibis/expr/datatypes/cast.py @@ -1,7 +1,7 @@ from __future__ import annotations import functools -from typing import Iterator +from typing import TYPE_CHECKING from multipledispatch import Dispatcher from public import public @@ -9,6 +9,9 @@ import ibis.expr.datatypes.core as dt from ibis.common.exceptions import IbisTypeError +if TYPE_CHECKING: + from collections.abc import Iterator + castable = Dispatcher("castable") diff --git a/ibis/expr/datatypes/core.py b/ibis/expr/datatypes/core.py index b10e3e23ed6f..eab4ce681369 100644 --- a/ibis/expr/datatypes/core.py +++ b/ibis/expr/datatypes/core.py @@ -5,13 +5,13 @@ import numbers import uuid as pyuuid from abc import abstractmethod -from collections.abc import Iterator, Mapping, Sequence +from collections.abc import Iterable, Iterator, Mapping, Sequence from numbers import Integral, Real -from typing import Any, Generic, Iterable, Literal, NamedTuple, Optional, TypeVar +from typing import Any, Generic, Literal, NamedTuple, Optional, TypeVar, get_type_hints import toolz from public import public -from typing_extensions import Self, get_args, get_origin, get_type_hints +from typing_extensions import Self, get_args, get_origin from ibis.common.annotations import attribute from ibis.common.collections import FrozenDict, MapSet diff --git a/ibis/expr/datatypes/tests/test_core.py b/ibis/expr/datatypes/tests/test_core.py index 3a8c85e032ac..b3c501fee1aa 100644 --- a/ibis/expr/datatypes/tests/test_core.py +++ b/ibis/expr/datatypes/tests/test_core.py @@ -5,10 +5,9 @@ import sys import uuid # noqa: TCH003 from dataclasses import dataclass -from typing import Dict, List, NamedTuple, Tuple +from typing import Annotated, NamedTuple import pytest -from typing_extensions import Annotated import ibis.expr.datatypes as dt from ibis.common.annotations import ValidationError @@ -223,9 +222,9 @@ class PyStruct: h: datetime.datetime i: datetime.timedelta j: decimal.Decimal - k: List[int] - l: Dict[str, int] # noqa: E741 - n: Tuple[str] + k: list[int] + l: dict[str, int] # noqa: E741 + n: tuple[str] o: uuid.UUID p: None q: MyStruct diff --git a/ibis/expr/datatypes/value.py b/ibis/expr/datatypes/value.py index 95af432611b6..d9b981348e7b 100644 --- a/ibis/expr/datatypes/value.py +++ b/ibis/expr/datatypes/value.py @@ -7,7 +7,8 @@ import ipaddress import json import uuid -from typing import Any, Mapping, NamedTuple, Sequence +from collections.abc import Mapping, Sequence +from typing import Any, NamedTuple import toolz from public import public diff --git a/ibis/expr/format.py b/ibis/expr/format.py index c0d1b9466809..e403fabd92fb 100644 --- a/ibis/expr/format.py +++ b/ibis/expr/format.py @@ -4,7 +4,7 @@ import itertools import textwrap import types -from typing import Mapping, Sequence +from collections.abc import Mapping, Sequence from public import public diff --git a/ibis/expr/operations/temporal.py b/ibis/expr/operations/temporal.py index fb85470646a3..bf61667d7f67 100644 --- a/ibis/expr/operations/temporal.py +++ b/ibis/expr/operations/temporal.py @@ -1,9 +1,9 @@ from __future__ import annotations import operator +from typing import Annotated from public import public -from typing_extensions import Annotated import ibis.expr.datatypes as dt import ibis.expr.rules as rlz diff --git a/ibis/expr/operations/tests/test_core.py b/ibis/expr/operations/tests/test_core.py index 0edf5b8cf281..c0b9717c1005 100644 --- a/ibis/expr/operations/tests/test_core.py +++ b/ibis/expr/operations/tests/test_core.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Optional, Tuple +from typing import Optional import pytest @@ -41,7 +41,7 @@ class NamedValue(Base): class Values(Base): - lst: Tuple[ops.Node, ...] + lst: tuple[ops.Node, ...] one = NamedValue(value=1, name=Name("one")) diff --git a/ibis/expr/sql.py b/ibis/expr/sql.py index c24ebe980bd7..75b4845c5aaa 100644 --- a/ibis/expr/sql.py +++ b/ibis/expr/sql.py @@ -2,7 +2,7 @@ import operator from functools import singledispatch -from typing import IO, Dict +from typing import IO import sqlglot as sg import sqlglot.expressions as sge @@ -18,7 +18,7 @@ from ibis.util import experimental -class Catalog(Dict[str, sch.Schema]): +class Catalog(dict[str, sch.Schema]): """A catalog of tables and their schemas.""" typemap = { diff --git a/ibis/expr/tests/test_schema.py b/ibis/expr/tests/test_schema.py index 759c3aa69693..7d926a1ee198 100644 --- a/ibis/expr/tests/test_schema.py +++ b/ibis/expr/tests/test_schema.py @@ -2,7 +2,7 @@ import contextlib from dataclasses import dataclass -from typing import Dict, List, NamedTuple, Tuple +from typing import NamedTuple import numpy as np import pandas.testing as tm @@ -235,12 +235,12 @@ class FooSchema: a: int b: str c: float - d: Tuple[str] - e: List[int] - f: Dict[str, int] + d: tuple[str] + e: list[int] + f: dict[str, int] g: BarSchema - h: List[BarSchema] - j: Dict[str, BarSchema] + h: list[BarSchema] + j: dict[str, BarSchema] foo_schema = sch.Schema( @@ -271,12 +271,12 @@ class NamedFoo(NamedTuple): a: int b: str c: float - d: Tuple[str] - e: List[int] - f: Dict[str, int] + d: tuple[str] + e: list[int] + f: dict[str, int] g: NamedBar - h: List[NamedBar] - j: Dict[str, NamedBar] + h: list[NamedBar] + j: dict[str, NamedBar] def test_schema_from_namedtuple(): @@ -294,16 +294,16 @@ class DataFooBase: a: int b: str c: float - d: Tuple[str] + d: tuple[str] @dataclass class DataFoo(DataFooBase): - e: List[int] - f: Dict[str, int] + e: list[int] + f: dict[str, int] g: DataBar - h: List[DataBar] - j: Dict[str, DataBar] + h: list[DataBar] + j: dict[str, DataBar] def test_schema_from_dataclass(): diff --git a/ibis/formats/parser.py b/ibis/formats/parser.py index 1e0bffc6b064..1522a5d00181 100644 --- a/ibis/formats/parser.py +++ b/ibis/formats/parser.py @@ -1,7 +1,7 @@ from __future__ import annotations import abc -from typing import Mapping +from typing import TYPE_CHECKING import sqlglot as sg from sqlglot.expressions import ColumnDef, DataType, DataTypeSize @@ -10,6 +10,9 @@ import ibis.expr.datatypes as dt from ibis.common.collections import FrozenDict +if TYPE_CHECKING: + from collections.abc import Mapping + SQLGLOT_TYPE_TO_IBIS_TYPE = { DataType.Type.BIGDECIMAL: dt.Decimal(76, 38), DataType.Type.BIGINT: dt.int64, diff --git a/ibis/selectors.py b/ibis/selectors.py index 9ff14eba2a11..e73c5b031a8d 100644 --- a/ibis/selectors.py +++ b/ibis/selectors.py @@ -52,7 +52,8 @@ import inspect import operator import re -from typing import Callable, Iterable, Mapping, Optional, Sequence, Union +from collections.abc import Iterable, Mapping, Sequence +from typing import Callable, Optional, Union from public import public diff --git a/ibis/tests/expr/test_table.py b/ibis/tests/expr/test_table.py index 9ff502b69e12..49d7ac1d6e5b 100644 --- a/ibis/tests/expr/test_table.py +++ b/ibis/tests/expr/test_table.py @@ -3,7 +3,6 @@ import datetime import pickle import re -from typing import List import numpy as np import pandas as pd @@ -1467,7 +1466,7 @@ def test_unbound_table_name(): class MyTable: a: int b: str - c: List[float] + c: list[float] def test_unbound_table_using_class_definition(): diff --git a/ibis/util.py b/ibis/util.py index 83d1caa940c1..05f1fe6cc925 100644 --- a/ibis/util.py +++ b/ibis/util.py @@ -18,8 +18,6 @@ TYPE_CHECKING, Any, Callable, - Iterator, - Sequence, TypeVar, ) from uuid import uuid4 @@ -27,6 +25,7 @@ import toolz if TYPE_CHECKING: + from collections.abc import Iterator, Sequence from numbers import Real from pathlib import Path diff --git a/pyproject.toml b/pyproject.toml index 552c83c38ff4..092ecc0631b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -452,7 +452,7 @@ ignore = [ "UP007", # Optional[str] -> str | None ] exclude = ["*_py310.py", "ibis/tests/*/snapshots/*"] -target-version = "py38" +target-version = "py39" # none of these codes will be automatically fixed by ruff unfixable = [ "T201", # print statements