diff --git a/README.md b/README.md index 4830a8f..8a76be8 100644 --- a/README.md +++ b/README.md @@ -79,17 +79,6 @@ This project is licensed under the MIT License. Yes No - - geopandas - geopandas - - PyPI, - GitHub - - Complete - Yes - Yes - ## Upstreamed stubs @@ -112,4 +101,9 @@ These stubs were included here in the past and have been moved to typeshed or to typeshed pip install types-shapely + + geopandas + typeshed + pip install types-geopandas + diff --git a/stubs/geopandas-stubs/_config.pyi b/stubs/geopandas-stubs/_config.pyi index b570abd..5de6c04 100644 --- a/stubs/geopandas-stubs/_config.pyi +++ b/stubs/geopandas-stubs/_config.pyi @@ -7,7 +7,7 @@ class Option(NamedTuple): default_value: Any doc: str validator: Callable[[object], Unused] - callback: Callable[[str, Any], Unused] | None + callback: Callable[[str, object], Unused] | None class Options: def __init__(self, options: SupportsItems[str, Option]) -> None: ... diff --git a/stubs/geopandas-stubs/array.pyi b/stubs/geopandas-stubs/array.pyi index fe63e7d..e750062 100644 --- a/stubs/geopandas-stubs/array.pyi +++ b/stubs/geopandas-stubs/array.pyi @@ -17,6 +17,7 @@ from geopandas.sindex import SpatialIndex _ScalarType = TypeVar("_ScalarType", bound=np.generic) _Array1D: TypeAlias = np.ndarray[tuple[int], np.dtype[_ScalarType]] +_Array2D: TypeAlias = np.ndarray[tuple[int, int], np.dtype[_ScalarType]] _ArrayOrGeom: TypeAlias = GeometryArray | ArrayLike | Geometry TransformerFromCRS = Transformer.from_crs @@ -89,14 +90,14 @@ class GeometryArray(ExtensionArray): @property def has_z(self) -> _Array1D[np.bool]: ... @property - def geom_type(self) -> _Array1D[np.int64]: ... + def geom_type(self) -> _Array1D[np.str_]: ... @property def area(self) -> _Array1D[np.float64]: ... @property def length(self) -> _Array1D[np.float64]: ... - def count_coordinates(self) -> _Array1D[np.int64]: ... - def count_geometries(self) -> _Array1D[np.int64]: ... - def count_interior_rings(self) -> _Array1D[np.int64]: ... + def count_coordinates(self) -> _Array1D[np.int32]: ... + def count_geometries(self) -> _Array1D[np.int32]: ... + def count_interior_rings(self) -> _Array1D[np.int32]: ... def get_precision(self) -> _Array1D[np.float64]: ... def get_geometry(self, index: SupportsIndex | ArrayLike) -> _Array1D[np.object_]: ... @property @@ -163,18 +164,19 @@ class GeometryArray(ExtensionArray): def snap(self, other: _ArrayOrGeom, tolerance: float | ArrayLike) -> GeometryArray: ... def shared_paths(self, other: _ArrayOrGeom) -> GeometryArray: ... def distance(self, other: _ArrayOrGeom) -> _Array1D[np.float64]: ... - def hausdorff_distance(self, other: _ArrayOrGeom, **kwargs: Any) -> _Array1D[np.float64]: ... + def hausdorff_distance(self, other: _ArrayOrGeom, **kwargs) -> _Array1D[np.float64]: ... def frechet_distance(self, other: _ArrayOrGeom, **kwargs) -> _Array1D[np.float64]: ... def buffer(self, distance: float | ArrayLike, resolution: int = 16, **kwargs) -> GeometryArray: ... - def interpolate(self, distance, normalized: bool = False) -> GeometryArray: ... + def interpolate(self, distance: float | ArrayLike, normalized: bool = False) -> GeometryArray: ... def simplify(self, tolerance: float | ArrayLike, preserve_topology: bool = True) -> GeometryArray: ... def project(self, other: _ArrayOrGeom, normalized: bool = False) -> _Array1D[np.float64]: ... def relate(self, other: _ArrayOrGeom) -> _Array1D[np.str_]: ... - def relate_pattern(self, other, pattern: str) -> _Array1D[np.bool]: ... + def relate_pattern(self, other: _ArrayOrGeom, pattern: str) -> _Array1D[np.bool]: ... + @deprecated("Use method `union_all` instead.") def unary_union(self) -> BaseGeometry: ... def union_all(self, method: Literal["coverage", "unary"] = "unary") -> BaseGeometry: ... def intersection_all(self) -> BaseGeometry: ... - def affine_transform(self, matrix: Incomplete) -> GeometryArray: ... + def affine_transform(self, matrix) -> GeometryArray: ... def translate(self, xoff: float = 0.0, yoff: float = 0.0, zoff: float = 0.0) -> GeometryArray: ... def rotate(self, angle: float, origin: _AffinityOrigin = "center", use_radians: bool = False) -> GeometryArray: ... def scale( @@ -192,7 +194,7 @@ class GeometryArray(ExtensionArray): @property def z(self) -> _Array1D[np.float64]: ... @property - def bounds(self) -> _Array1D[np.float64]: ... + def bounds(self) -> _Array2D[np.float64]: ... @property def total_bounds(self) -> _Array1D[np.float64]: ... @property @@ -215,7 +217,12 @@ class GeometryArray(ExtensionArray): limit: int | None = None, copy: bool = True, ) -> GeometryArray: ... - def astype(self, dtype: DTypeLike, copy: bool = True) -> GeometryArray | ExtensionArray | NDArray[Any]: ... + @overload + def astype(self, dtype: GeometryDtype, copy: bool = True) -> GeometryArray: ... + @overload + def astype(self, dtype: ExtensionDtype | Literal["string"], copy: bool = True) -> ExtensionArray: ... # type: ignore[overload-overlap] + @overload + def astype(self, dtype: DTypeLike, copy: bool = True) -> _Array1D[Incomplete]: ... def isna(self) -> _Array1D[np.bool]: ... def value_counts(self, dropna: bool = True) -> pd.Series[int]: ... def unique(self) -> GeometryArray: ... diff --git a/stubs/geopandas-stubs/base.pyi b/stubs/geopandas-stubs/base.pyi index 984cd17..9d08c97 100644 --- a/stubs/geopandas-stubs/base.pyi +++ b/stubs/geopandas-stubs/base.pyi @@ -1,4 +1,4 @@ -from _typeshed import Incomplete, SupportsGetItem +from _typeshed import SupportsGetItem from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence from typing import Any, Literal, Protocol, SupportsIndex, overload, type_check_only from typing_extensions import Self, TypeAlias, deprecated @@ -13,7 +13,7 @@ from pyproj import CRS from shapely import Geometry, MultiPolygon, Point, Polygon from shapely.geometry.base import BaseGeometry -from geopandas.array import GeometryArray +from geopandas.array import GeometryArray, _Array1D from geopandas.geodataframe import GeoDataFrame from geopandas.geoseries import GeoSeries from geopandas.sindex import SpatialIndex @@ -34,7 +34,7 @@ _BboxLike: TypeAlias = Sequence[float] | NDArray[np.floating[Any]] | Geometry | _MaskLike: TypeAlias = dict[str, Any] | Geometry | GeoDataFrame | GeoSeries # noqa: PYI047 # XXX: cannot use IndexOpsMixin[Geometry] because of IndexOpsMixin type variable bounds -_GeoListLike: TypeAlias = ArrayLike | Sequence[Geometry] | IndexOpsMixin[Incomplete] +_GeoListLike: TypeAlias = ArrayLike | Sequence[Geometry] | IndexOpsMixin[Any] _ConvertibleToGeoSeries: TypeAlias = Geometry | Mapping[int, Geometry] | Mapping[str, Geometry] | _GeoListLike # noqa: PYI047 # XXX: cannot use pd.Series[Geometry] because of pd.Series type variable bounds @@ -162,7 +162,7 @@ class GeoPandasBase: @property def bounds(self) -> pd.DataFrame: ... @property - def total_bounds(self) -> NDArray[np.float64]: ... + def total_bounds(self) -> _Array1D[np.float64]: ... @property def sindex(self) -> SpatialIndex: ... @property @@ -182,7 +182,7 @@ class GeoPandasBase: def relate_pattern(self, other: GeoSeries | Geometry, pattern: str, align: bool | None = None) -> pd.Series[bool]: ... def project(self, other: GeoSeries | Geometry, normalized: bool = False, align: bool | None = None) -> pd.Series[float]: ... def interpolate(self, distance: float | ArrayLike, normalized: bool = False) -> GeoSeries: ... - def affine_transform(self, matrix: Incomplete) -> GeoSeries: ... + def affine_transform(self, matrix) -> GeoSeries: ... def translate(self, xoff: float = 0.0, yoff: float = 0.0, zoff: float = 0.0) -> GeoSeries: ... def rotate(self, angle: float, origin: _AffinityOrigin = "center", use_radians: bool = False) -> GeoSeries: ... def scale( diff --git a/stubs/geopandas-stubs/geodataframe.pyi b/stubs/geopandas-stubs/geodataframe.pyi index 4d21f61..da23bfc 100644 --- a/stubs/geopandas-stubs/geodataframe.pyi +++ b/stubs/geopandas-stubs/geodataframe.pyi @@ -1,7 +1,7 @@ import io import os -from _typeshed import Incomplete, SupportsGetItem, SupportsRead, SupportsWrite -from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping +from _typeshed import Incomplete, SupportsGetItem, SupportsLenAndGetItem, SupportsRead, SupportsWrite +from collections.abc import Callable, Container, Hashable, Iterable, Iterator, Mapping from json import JSONEncoder from typing import Any, Literal, overload from typing_extensions import Self @@ -97,7 +97,12 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc] def crs(self, value: _ConvertibleToCRS | None) -> None: ... @classmethod def from_dict( # type: ignore[override] - cls, data: Mapping[Hashable, Any], geometry: _GeomCol | None = None, crs: _ConvertibleToCRS | None = None, **kwargs + # Mapping[Any, Any] because of invariance keys and arbitrary values + cls, + data: Mapping[Any, Any], + geometry: _GeomCol | None = None, + crs: _ConvertibleToCRS | None = None, + **kwargs, ) -> Self: ... # Keep inline with GeoSeries.from_file and geopandas.io.file._read_file @classmethod @@ -135,8 +140,8 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc] crs: _ConvertibleToCRS | None = None, index_col: str | list[str] | None = None, coerce_float: bool = True, - parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None, - params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None, + parse_dates: Container[str | Mapping[str, Any]] | Mapping[str, str | Mapping[str, Any]] | None = None, + params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None, *, chunksize: int, ) -> Iterator[GeoDataFrame]: ... @@ -150,8 +155,8 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc] crs: _ConvertibleToCRS | None = None, index_col: str | list[str] | None = None, coerce_float: bool = True, - parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None, - params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None, + parse_dates: Container[str | Mapping[str, Any]] | Mapping[str, str | Mapping[str, Any]] | None = None, + params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None, chunksize: None = None, ) -> GeoDataFrame: ... @classmethod @@ -245,7 +250,7 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc] layer: int | str | None = None, encoding: str | None = None, overwrite: bool | None = ..., - **kwargs: Any, # engine and driver dependent + **kwargs, # engine and driver dependent ) -> None: ... @overload def set_crs( diff --git a/stubs/geopandas-stubs/geoseries.pyi b/stubs/geopandas-stubs/geoseries.pyi index 01a0d5d..5466e14 100644 --- a/stubs/geopandas-stubs/geoseries.pyi +++ b/stubs/geopandas-stubs/geoseries.pyi @@ -68,7 +68,7 @@ class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-va ignore_geometry: Literal[False] = False, layer: int | str | None = None, encoding: str | None = None, - **kwargs: Any, # engine dependent + **kwargs, # engine dependent ) -> GeoSeries: ... @classmethod def from_wkb( @@ -143,7 +143,7 @@ class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-va layer: int | str | None = None, encoding: str | None = None, overwrite: bool | None = ..., - **kwargs: Any, # engine and driver dependent + **kwargs, # engine and driver dependent ) -> None: ... # *** TODO: compare `__getitem__` with pandas-stubs *** # def __getitem__(self, key): ... @@ -195,9 +195,9 @@ class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-va cls: type[json.JSONEncoder] | None = None, indent: None | int | str = None, separators: tuple[str, str] | None = None, - default: Callable[[Any], Any] | None = None, + default: Callable[..., Any] | None = None, # as typed in the json stdlib module sort_keys: bool = False, - **kwds: Any, + **kwds, ) -> str: ... @overload def to_wkb(self, hex: Literal[False] = False, **kwargs) -> pd.Series[bytes]: ... diff --git a/stubs/geopandas-stubs/io/file.pyi b/stubs/geopandas-stubs/io/file.pyi index b5759c0..e578326 100644 --- a/stubs/geopandas-stubs/io/file.pyi +++ b/stubs/geopandas-stubs/io/file.pyi @@ -36,7 +36,7 @@ def _read_file( ignore_geometry: Literal[True], layer: int | str | None = None, encoding: str | None = None, - **kwargs: Any, # depends on engine + **kwargs: Any, # depend on engine ) -> pd.DataFrame: ... class _Schema(TypedDict): diff --git a/stubs/geopandas-stubs/io/sql.pyi b/stubs/geopandas-stubs/io/sql.pyi index 10e650e..13c9b21 100644 --- a/stubs/geopandas-stubs/io/sql.pyi +++ b/stubs/geopandas-stubs/io/sql.pyi @@ -1,5 +1,6 @@ import sqlite3 -from collections.abc import Iterator, Mapping +from _typeshed import SupportsLenAndGetItem +from collections.abc import Container, Iterator, Mapping from contextlib import AbstractContextManager from typing import Any, Protocol, overload from typing_extensions import TypeAlias @@ -79,10 +80,10 @@ def _read_postgis( con: _SQLConnection, geom_col: str = "geom", crs: _ConvertibleToCRS | None = None, - index_col: str | list[str] | None = None, + index_col: str | Container[str] | None = None, coerce_float: bool = True, - parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None, - params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None, + parse_dates: Container[str | Mapping[str, Any]] | Mapping[str, str | Mapping[str, Any]] | None = None, + params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None, *, chunksize: int, ) -> Iterator[GeoDataFrame]: ... @@ -92,10 +93,10 @@ def _read_postgis( con: _SQLConnection, geom_col: str = "geom", crs: _ConvertibleToCRS | None = None, - index_col: str | list[str] | None = None, + index_col: str | Container[str] | None = None, coerce_float: bool = True, - parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None, - params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None, + parse_dates: Container[str | Mapping[str, Any]] | Mapping[str, str | Mapping[str, Any]] | None = None, + params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None, chunksize: None = None, ) -> GeoDataFrame: ... @overload @@ -104,9 +105,9 @@ def _read_postgis( con: _SQLConnection, geom_col: str = "geom", crs: _ConvertibleToCRS | None = None, - index_col: str | list[str] | None = None, + index_col: str | Container[str] | None = None, coerce_float: bool = True, - parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None, - params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None, + parse_dates: Container[str | Mapping[str, Any]] | Mapping[str, str | Mapping[str, Any]] | None = None, + params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None, chunksize: int | None = None, ) -> GeoDataFrame | Iterator[GeoDataFrame]: ... diff --git a/stubs/geopandas-stubs/plotting.pyi b/stubs/geopandas-stubs/plotting.pyi index e260b43..b1093f4 100644 --- a/stubs/geopandas-stubs/plotting.pyi +++ b/stubs/geopandas-stubs/plotting.pyi @@ -108,7 +108,7 @@ class GeoplotAccessor(PlotAccessor): mark_right: bool = True, include_bool: bool = False, backend: str | None = None, - **kwargs, + **kwargs: Any, ) -> Axes: ... @overload def __call__( @@ -150,7 +150,7 @@ class GeoplotAccessor(PlotAccessor): mark_right: bool = True, include_bool: bool = False, backend: str | None = None, - **kwargs, + **kwargs: Any, ) -> NDArray[np.object_]: ... # should be NDArray[Axes] but it is not supported @overload def __call__( @@ -192,7 +192,7 @@ class GeoplotAccessor(PlotAccessor): mark_right: bool = True, include_bool: bool = False, backend: str | None = None, - **kwargs, + **kwargs: Any, ) -> pd.Series[Axes]: ... # type: ignore[type-var] # pyright: ignore[reportInvalidTypeArguments] @overload def __call__( diff --git a/stubs/geopandas-stubs/sindex.pyi b/stubs/geopandas-stubs/sindex.pyi index 4ec5eab..645f736 100644 --- a/stubs/geopandas-stubs/sindex.pyi +++ b/stubs/geopandas-stubs/sindex.pyi @@ -1,9 +1,12 @@ -from typing import Final, Literal, overload +from collections.abc import Iterable +from typing import Any, Final, Literal, overload import numpy as np from numpy.typing import ArrayLike, NDArray from shapely import Geometry +from geopandas.array import _Array1D, _Array2D + PREDICATES: Final[set[str | None]] class SpatialIndex: @@ -11,14 +14,35 @@ class SpatialIndex: def __init__(self, geometry: NDArray[np.object_]) -> None: ... @property def valid_query_predicates(self) -> set[str | None]: ... + @overload + def query( + self, + geometry: Geometry | ArrayLike, + predicate: str | None = None, + sort: bool = False, + distance: float | ArrayLike | None = None, + output_format: Literal["tuple"] = "tuple", + ) -> NDArray[np.int64]: ... + @overload def query( self, geometry: Geometry | ArrayLike, predicate: str | None = None, sort: bool = False, distance: float | ArrayLike | None = None, - output_format: Literal["sparse", "dense", "tuple"] = "tuple", - ) -> NDArray[np.int_]: ... + *, + output_format: Literal["dense"], + ) -> NDArray[np.bool]: ... + @overload + def query( + self, + geometry: Geometry | ArrayLike, + predicate: str | None = None, + sort: bool = False, + distance: float | ArrayLike | None = None, + *, + output_format: Literal["sparse"], + ) -> Any: ... # returns scipy coo_array but we don't depend on scipy @overload def nearest( self, @@ -27,7 +51,7 @@ class SpatialIndex: max_distance: float | None = None, return_distance: Literal[False] = False, exclusive: bool = False, - ) -> NDArray[np.int_]: ... + ) -> _Array2D[np.int64]: ... @overload def nearest( self, @@ -37,7 +61,7 @@ class SpatialIndex: *, return_distance: Literal[True], exclusive: bool = False, - ) -> tuple[NDArray[np.int_], NDArray[np.float64]]: ... + ) -> tuple[_Array2D[np.int64], _Array1D[np.float64]]: ... @overload def nearest( self, @@ -46,8 +70,8 @@ class SpatialIndex: max_distance: float | None = None, return_distance: bool = False, exclusive: bool = False, - ) -> NDArray[np.int_] | tuple[NDArray[np.int_], NDArray[np.float64]]: ... - def intersection(self, coordinates) -> NDArray[np.int_]: ... + ) -> _Array2D[np.int64] | tuple[_Array2D[np.int64], _Array1D[np.float64]]: ... + def intersection(self, coordinates: Iterable[float]) -> _Array1D[np.int64]: ... @property def size(self) -> int: ... @property