Skip to content

Bump geopandas stubs to version 1.1.0 #14244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions stubs/geopandas/@tests/stubtest_allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ geopandas\.(geodataframe\.)?GeoDataFrame\.plot
geopandas\.io\._geoarrow
geopandas\._exports

# Not present in stub OK (do not work at runtime, to be removed from geopandas)
geopandas\.(geoseries\.)?GeoSeries\.append # https://github.com/geopandas/geopandas/pull/3460
geopandas\.(geoseries\.)?GeoSeries\.select # https://github.com/geopandas/geopandas/pull/3394

# Inconsistent (TODO)
geopandas\.(geoseries\.)?GeoSeries\.apply
geopandas\.(geoseries\.)?GeoSeries\.fillna
Expand Down
4 changes: 2 additions & 2 deletions stubs/geopandas/METADATA.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version = "1.0.1"
version = "1.1.0"
# Requires a version of numpy with a `py.typed` file
requires = ["numpy>=1.20", "pandas-stubs<2.2.3.250527", "types-shapely", "pyproj"]
requires = ["numpy>=1.20", "pandas-stubs", "types-shapely", "pyproj"]
upstream_repository = "https://github.com/geopandas/geopandas"

[tool.stubtest]
Expand Down
7 changes: 7 additions & 0 deletions stubs/geopandas/geopandas/accessors.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from typing import Any

import pandas as pd

class GeoSeriesAccessor:
def __init__(self, series: pd.Series[Any]) -> None: ... # Cannot use pd.Series[BaseGeometry]
def __getattr__(self, name: str) -> Any: ... # Delegate all attributes to the GeoSeries
46 changes: 30 additions & 16 deletions stubs/geopandas/geopandas/array.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import builtins
from _typeshed import Incomplete, Unused
from collections.abc import Callable, Sequence
from typing import Any, ClassVar, Literal, NoReturn, SupportsIndex, TypeVar, overload
from collections.abc import Callable, Collection, Sequence
from typing import Any, ClassVar, Final, Literal, NoReturn, SupportsIndex, TypeVar, overload
from typing_extensions import Self, TypeAlias, deprecated

import numpy as np
Expand All @@ -21,11 +21,14 @@ _Array2D: TypeAlias = np.ndarray[tuple[int, int], np.dtype[_ScalarType]]
_ArrayOrGeom: TypeAlias = GeometryArray | ArrayLike | Geometry

TransformerFromCRS = Transformer.from_crs
POLYGON_GEOM_TYPES: Final[set[str]]
LINE_GEOM_TYPES: Final[set[str]]
POINT_GEOM_TYPES: Final[set[str]]

class GeometryDtype(ExtensionDtype):
type: ClassVar[type[BaseGeometry]]
name: ClassVar[str]
na_value: float
na_value: None
@classmethod
def construct_from_string(cls, string: str) -> Self: ...
@classmethod
Expand All @@ -35,14 +38,14 @@ def isna(value: object) -> bool: ...
def from_shapely(data, crs: _ConvertibleToCRS | None = None) -> GeometryArray: ...
def to_shapely(geoms: GeometryArray) -> _Array1D[np.object_]: ...
def from_wkb(
data, crs: _ConvertibleToCRS | None = None, on_invalid: Literal["raise", "warn", "ignore"] = "raise"
data, crs: _ConvertibleToCRS | None = None, on_invalid: Literal["raise", "warn", "ignore", "fix"] = "raise"
) -> GeometryArray: ...
@overload
def to_wkb(geoms: GeometryArray, hex: Literal[False] = False, **kwargs) -> _Array1D[np.bytes_]: ...
@overload
def to_wkb(geoms: GeometryArray, hex: Literal[True], **kwargs) -> _Array1D[np.str_]: ...
def from_wkt(
data, crs: _ConvertibleToCRS | None = None, on_invalid: Literal["raise", "warn", "ignore"] = "raise"
data, crs: _ConvertibleToCRS | None = None, on_invalid: Literal["raise", "warn", "ignore", "fix"] = "raise"
) -> GeometryArray: ...
def to_wkt(geoms: GeometryArray, **kwargs) -> _Array1D[np.str_]: ...
def points_from_xy(
Expand Down Expand Up @@ -80,6 +83,8 @@ class GeometryArray(ExtensionArray):
@property
def is_valid(self) -> _Array1D[np.bool_]: ...
def is_valid_reason(self) -> _Array1D[np.object_]: ...
def is_valid_coverage(self, gap_width: float = 0.0) -> bool: ...
def invalid_coverage_edges(self, gap_width: float = 0.0) -> _Array1D[np.object_]: ...
@property
def is_empty(self) -> _Array1D[np.bool_]: ...
@property
Expand All @@ -93,6 +98,8 @@ class GeometryArray(ExtensionArray):
@property
def has_z(self) -> _Array1D[np.bool_]: ...
@property
def has_m(self) -> _Array1D[np.bool_]: ...
@property
def geom_type(self) -> _Array1D[np.str_]: ...
@property
def area(self) -> _Array1D[np.float64]: ...
Expand All @@ -108,6 +115,7 @@ class GeometryArray(ExtensionArray):
@property
def centroid(self) -> GeometryArray: ...
def concave_hull(self, ratio: float, allow_holes: bool) -> _Array1D[np.object_]: ...
def constrained_delaunay_triangles(self) -> GeometryArray: ...
@property
def convex_hull(self) -> GeometryArray: ...
@property
Expand All @@ -128,10 +136,13 @@ class GeometryArray(ExtensionArray):
def remove_repeated_points(self, tolerance: float | ArrayLike = 0.0) -> GeometryArray: ...
def representative_point(self) -> GeometryArray: ...
def minimum_bounding_circle(self) -> GeometryArray: ...
def maximum_inscribed_circle(self, tolerance: float | ArrayLike) -> GeometryArray: ...
def minimum_bounding_radius(self) -> _Array1D[np.float64]: ...
def minimum_clearance(self) -> _Array1D[np.float64]: ...
def minimum_clearance_line(self) -> GeometryArray: ...
def normalize(self) -> GeometryArray: ...
def make_valid(self) -> GeometryArray: ...
def orient_polygons(self, exterior_cw: bool = False) -> GeometryArray: ...
def make_valid(self, method: Literal["linework", "structure"] = "linework", keep_collapsed: bool = True) -> GeometryArray: ...
def reverse(self) -> GeometryArray: ...
def segmentize(self, max_segment_length: float | ArrayLike) -> GeometryArray: ...
def force_2d(self) -> GeometryArray: ...
Expand All @@ -156,8 +167,7 @@ class GeometryArray(ExtensionArray):
def within(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def dwithin(self, other: _ArrayOrGeom, distance: float) -> _Array1D[np.bool_]: ...
def geom_equals_exact(self, other: _ArrayOrGeom, tolerance: float | ArrayLike) -> _Array1D[np.bool_]: ...
@deprecated("Use method `geom_equals_exact` instead.")
def geom_almost_equals(self, other: _ArrayOrGeom, decimal: float) -> _Array1D[np.bool_]: ...
def geom_equals_identical(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def clip_by_rect(self, xmin: float, ymin: float, xmax: float, ymax: float) -> GeometryArray: ...
def difference(self, other: _ArrayOrGeom) -> GeometryArray: ...
def intersection(self, other: _ArrayOrGeom) -> GeometryArray: ...
Expand All @@ -172,14 +182,17 @@ class GeometryArray(ExtensionArray):
def buffer(self, distance: float | ArrayLike, resolution: int = 16, **kwargs) -> GeometryArray: ...
def interpolate(self, distance: float | ArrayLike, normalized: bool = False) -> GeometryArray: ...
def simplify(self, tolerance: float | ArrayLike, preserve_topology: bool = True) -> GeometryArray: ...
def simplify_coverage(self, tolerance: float | ArrayLike, simplify_boundary: 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: _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 union_all(
self, method: Literal["coverage", "unary", "disjoint_subset"] = "unary", grid_size: float | None = None
) -> BaseGeometry: ...
def intersection_all(self) -> BaseGeometry: ...
def affine_transform(self, matrix) -> GeometryArray: ...
def affine_transform(self, matrix: Collection[float]) -> 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(
Expand All @@ -197,21 +210,20 @@ class GeometryArray(ExtensionArray):
@property
def z(self) -> _Array1D[np.float64]: ...
@property
def m(self) -> _Array1D[np.float64]: ...
@property
def bounds(self) -> _Array2D[np.float64]: ...
@property
def total_bounds(self) -> _Array1D[np.float64]: ...
@property
def size(self) -> int: ...
@property
def shape(self) -> tuple[int]: ... # Always 1-D, this is not a mistake
def shape(self) -> tuple[int]: ... # Always 1-D, this is not mistaken for tuple[int, ...]
@property
def ndim(self) -> Literal[1]: ...
def copy(self, *args: Unused, **kwargs: Unused) -> GeometryArray: ...
def take(
self,
indices: Sequence[SupportsIndex] | NDArray[np.integer[Any]], # np.integer[Any] because precision is not important
allow_fill: bool = False,
fill_value: Geometry | None = None,
self, indices: Sequence[SupportsIndex] | NDArray[np.integer], allow_fill: bool = False, fill_value: Geometry | None = None
) -> GeometryArray: ...
def fillna(
self,
Expand Down Expand Up @@ -239,6 +251,8 @@ class GeometryArray(ExtensionArray):
def __ne__(self, other: object) -> _Array1D[np.bool_]: ... # type: ignore[override]
def __contains__(self, item: object) -> np.bool_: ...

# TODO: Improve `func` type with a callable protocol (with overloads for 2D and 3D geometries)
def transform(
data: NDArray[np.object_], func: Callable[[NDArray[np.float64], NDArray[np.float64]], NDArray[np.float64]]
data: NDArray[np.object_] | GeometryArray | pd.Series[Any], # Cannot use pd.Series[BaseGeometry]
func: Callable[..., NDArray[np.float64]],
) -> NDArray[np.object_]: ...
27 changes: 20 additions & 7 deletions stubs/geopandas/geopandas/base.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from _typeshed import Incomplete, SupportsGetItem
from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence
from collections.abc import Callable, Collection, Hashable, Iterable, Mapping, Sequence
from typing import Any, Literal, Protocol, SupportsIndex, overload, type_check_only
from typing_extensions import Self, TypeAlias, deprecated

Expand Down Expand Up @@ -64,6 +64,8 @@ class GeoPandasBase:
@property
def is_valid(self) -> pd.Series[bool]: ...
def is_valid_reason(self) -> pd.Series[str]: ...
def is_valid_coverage(self, *, gap_width: float = 0.0) -> bool: ...
def invalid_coverage_edges(self, *, gap_width: float = 0.0) -> GeoSeries: ...
@property
def is_empty(self) -> pd.Series[bool]: ...
def count_coordinates(self) -> pd.Series[int]: ...
Expand All @@ -79,13 +81,16 @@ class GeoPandasBase:
def is_closed(self) -> pd.Series[bool]: ...
@property
def has_z(self) -> pd.Series[bool]: ...
@property
def has_m(self) -> pd.Series[bool]: ...
def get_precision(self) -> pd.Series[float]: ...
def get_geometry(self, index: SupportsIndex | ArrayLike) -> GeoSeries: ...
@property
def boundary(self) -> GeoSeries: ...
@property
def centroid(self) -> GeoSeries: ...
def concave_hull(self, ratio: float = 0.0, allow_holes: bool = False) -> GeoSeries: ...
def constrained_delaunay_triangles(self) -> GeoSeries: ...
@property
def convex_hull(self) -> GeoSeries: ...
def delaunay_triangles(self, tolerance: float | ArrayLike = 0.0, only_edges: bool | ArrayLike = False) -> GeoSeries: ...
Expand Down Expand Up @@ -113,10 +118,13 @@ class GeoPandasBase:
) -> GeoSeries: ...
def representative_point(self) -> GeoSeries: ...
def minimum_bounding_circle(self) -> GeoSeries: ...
def maximum_inscribed_circle(self, *, tolerance: float | ArrayLike | None = None) -> GeoSeries: ...
def minimum_bounding_radius(self) -> pd.Series[float]: ...
def minimum_clearance(self) -> pd.Series[float]: ...
def minimum_clearance_line(self) -> GeoSeries: ...
def normalize(self) -> GeoSeries: ...
def make_valid(self) -> GeoSeries: ...
def orient_polygons(self, *, exterior_cw: bool = False) -> GeoSeries: ...
def make_valid(self, *, method: Literal["linework", "structure"] = "linework", keep_collapsed: bool = True) -> GeoSeries: ...
def reverse(self) -> GeoSeries: ...
def segmentize(self, max_segment_length: float | ArrayLike) -> GeoSeries: ...
def transform(
Expand All @@ -126,18 +134,20 @@ class GeoPandasBase:
def force_3d(self, z: float | ArrayLike = 0) -> GeoSeries: ...
def line_merge(self, directed: bool = False) -> GeoSeries: ...
@property
@deprecated("Use method `union_all` instead.")
def unary_union(self) -> BaseGeometry: ...
def union_all(self, method: Literal["coverage", "unary"] = "unary") -> BaseGeometry: ...
def union_all(
self, method: Literal["coverage", "unary", "disjoint_subset"] = "unary", *, grid_size: float | None = None
) -> BaseGeometry: ...
def intersection_all(self) -> BaseGeometry: ...
def contains(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def contains_properly(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def dwithin(self, other: GeoSeries | Geometry, distance: float | ArrayLike, align: bool | None = None) -> pd.Series[bool]: ...
def geom_equals(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
@deprecated("Use method `geom_equals_exact` instead.")
def geom_almost_equals(self, other: GeoSeries | Geometry, decimal: int = 6, align: bool | None = None) -> pd.Series[bool]: ...
def geom_equals_exact(
self, other: GeoSeries | Geometry, tolerance: float | ArrayLike, align: bool | None = None
) -> pd.Series[bool]: ...
def geom_equals_identical(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def crosses(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def disjoint(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def intersects(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
Expand Down Expand Up @@ -180,11 +190,12 @@ class GeoPandasBase:
**kwargs,
) -> GeoSeries: ...
def simplify(self, tolerance: float | ArrayLike, preserve_topology: bool = True) -> GeoSeries: ...
def simplify_coverage(self, tolerance: float | ArrayLike, *, simplify_boundary: bool = True) -> GeoSeries: ...
def relate(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[str]: ...
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) -> GeoSeries: ...
def affine_transform(self, matrix: Collection[float]) -> 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(
Expand All @@ -195,7 +206,9 @@ class GeoPandasBase:
) -> GeoSeries: ...
@property
def cx(self) -> SupportsGetItem[tuple[SupportsIndex | slice, SupportsIndex | slice], Self]: ...
def get_coordinates(self, include_z: bool = False, ignore_index: bool = False, index_parts: bool = False) -> pd.DataFrame: ...
def get_coordinates(
self, include_z: bool = False, ignore_index: bool = False, index_parts: bool = False, *, include_m: bool = False
) -> pd.DataFrame: ...
def hilbert_distance(
self, total_bounds: tuple[float, float, float, float] | Iterable[float] | None = None, level: int = 16
) -> pd.Series[int]: ...
Expand Down
22 changes: 11 additions & 11 deletions stubs/geopandas/geopandas/geodataframe.pyi
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import io
import os
from _typeshed import Incomplete, SupportsGetItem, SupportsLenAndGetItem, SupportsRead, SupportsWrite
from collections.abc import Callable, Container, Hashable, Iterable, Iterator, Mapping
from collections.abc import Callable, Container, Hashable, Iterable, Iterator, Mapping, Sequence
from json import JSONEncoder
from typing import Any, Literal, overload
from typing_extensions import Self

import pandas as pd
from numpy.typing import ArrayLike
from pandas._typing import AggFuncTypeFrame, AstypeArg, Axes, Axis, Dtype, GroupByObject, IndexLabel, Scalar
from pandas._typing import AggFuncTypeFrame, Axes, Axis, Dtype, GroupByObject, IndexLabel, Scalar
from pyproj import CRS

from ._decorator import doc
Expand Down Expand Up @@ -160,7 +160,9 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
chunksize: None = None,
) -> GeoDataFrame: ...
@classmethod
def from_arrow(cls, table, geometry: str | None = None) -> GeoDataFrame: ... # table: pyarrow.Table
def from_arrow(
cls, table, geometry: str | None = None, to_pandas_kwargs: Mapping[str, Incomplete] | None = None
) -> GeoDataFrame: ... # TODO: `table: pyarrow.Table | table-like`
def to_json( # type: ignore[override]
self,
na: str = "null",
Expand Down Expand Up @@ -306,16 +308,11 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
sort: bool = True,
observed: bool = False,
dropna: bool = True,
method: Literal["coverage", "unary"] = "unary",
method: Literal["coverage", "unary", "disjoint_subset"] = "unary",
grid_size: float | None = None,
**kwargs,
) -> GeoDataFrame: ...
def explode(self, column: IndexLabel | None = None, ignore_index: bool = False, index_parts: bool = False) -> Self: ...
def astype(
self,
dtype: AstypeArg | Mapping[Any, Dtype] | pd.Series[Any], # any because of mapping invariance and series typevar bounds
copy: bool | None = None,
errors: Literal["ignore", "raise"] = "raise",
) -> GeoDataFrame: ...
def to_postgis(
self,
name: str,
Expand All @@ -334,12 +331,15 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
def sjoin(
self,
df: GeoDataFrame,
# *args, **kwargs passed to geopandas.sjoin
how: Literal["left", "right", "inner"] = "inner",
predicate: str = "intersects",
lsuffix: str = "left",
rsuffix: str = "right",
*,
# **kwargs passed to geopandas.sjoin
distance: float | ArrayLike | None = None,
on_attribute: str | Sequence[str] | None = None,
**kwargs,
) -> GeoDataFrame: ...
def sjoin_nearest(
self,
Expand Down
Loading