Skip to content

Commit

Permalink
Add geopandas tests (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
hamdanal authored May 26, 2024
1 parent 5ecdeae commit ad88a76
Show file tree
Hide file tree
Showing 10 changed files with 364 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repos:
- id: mixed-line-ending
- id: check-case-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.3 # must match requirements-tests.txt
rev: v0.4.5 # must match requirements-tests.txt
hooks:
- id: ruff
- id: ruff-format
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ This project is licensed under the MIT License.
</th>
<th>Complete</th>
<th>Yes</th>
<th>Partially</th>
<th>Yes</th>
</tr>
<tr>
<th>shapely</th>
Expand Down
10 changes: 5 additions & 5 deletions requirements-tests.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Tools
# -----
ruff==0.4.3 # must match .pre-commit-config.yaml
ruff==0.4.5 # must match .pre-commit-config.yaml
pytest>=8.0
mypy==1.10.0
pyright==1.1.361
pyright==1.1.364

# Runtime dependencies
# --------------------
Expand All @@ -15,10 +15,10 @@ geopandas>=0.14.4,<1.0
# shapely
pyproj>=3.6.1
# geopandas
pandas-stubs>=2.2.1.240316
pandas-stubs>=2.2.2.240514
matplotlib>=3.8.0
folium>=0.15.1
rtree>=1.1.0
folium>=0.16.0
rtree>=1.2.0
# netfields and psqlextra
django-types>=0.19.1
djangorestframework-types>=0.8.0
Expand Down
127 changes: 100 additions & 27 deletions stubs/geopandas-stubs/geodataframe.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from _typeshed import Incomplete, SupportsGetItem, SupportsRead, SupportsWrite
from collections.abc import Callable, Generator, Hashable, Iterable, Mapping, Sequence
from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping, Sequence
from json import JSONEncoder
from typing import Any, Literal, Protocol, overload, type_check_only
from typing_extensions import Self, TypeAlias, deprecated

Expand All @@ -21,7 +22,8 @@ from geopandas.plotting import GeoplotAccessor
from geopandas.tools.clip import _Mask as _ClipMask

# XXX: cannot use pd.Series[Geometry] because of pd.Series type variable bounds
_GeometryColumn: TypeAlias = Hashable | Sequence[Geometry] | NDArray[np.object_] | pd.Series[Any] | GeometryArray | GeoSeries
_GeomSeq: TypeAlias = Sequence[Geometry] | NDArray[np.object_] | pd.Series[Any] | GeometryArray | GeoSeries
_GeomCol: TypeAlias = Hashable | _GeomSeq # name of column or column values
_ConvertibleToDataFrame: TypeAlias = (
ListLikeU | pd.DataFrame | dict[Any, Any] | Iterable[ListLikeU | tuple[Hashable, ListLikeU] | dict[Any, Any]]
)
Expand All @@ -44,7 +46,7 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
dtype: Dtype | None = None,
copy: bool | None = None,
*,
geometry: _GeometryColumn | None = None,
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
) -> Self: ...
@overload
Expand All @@ -56,7 +58,7 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
dtype: Dtype | None = None,
copy: bool | None = None,
*,
geometry: _GeometryColumn | None = None,
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
) -> Self: ...
def __init__(
Expand All @@ -67,25 +69,35 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
dtype: Dtype | None = None,
copy: bool | None = None,
*,
geometry: _GeometryColumn | None = None,
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
) -> None: ...
def __setattr__(self, attr: str, val: Any) -> None: ...
@property
def geometry(self) -> GeoSeries: ...
@geometry.setter
def geometry(self, col: _GeometryColumn) -> None: ...
def geometry(self, col: _GeomSeq) -> None: ...
@overload
def set_geometry(
self, col: _GeometryColumn, drop: bool = False, inplace: bool = False, crs: _ConvertibleToCRS | None = None
): ...
def rename_geometry(self, col: Hashable, inplace: bool = False) -> Self: ...
self, col: _GeomCol, drop: bool = False, inplace: Literal[False] = False, crs: _ConvertibleToCRS | None = None
) -> Self: ...
@overload
def set_geometry(
self, col: _GeomCol, drop: bool = False, *, inplace: Literal[True], crs: _ConvertibleToCRS | None = None
) -> None: ...
@overload
def set_geometry(self, col: _GeomCol, drop: bool, inplace: Literal[True], crs: _ConvertibleToCRS | None = None) -> None: ...
@overload
def rename_geometry(self, col: Hashable, inplace: Literal[False] = False) -> Self: ...
@overload
def rename_geometry(self, col: Hashable, inplace: Literal[True]) -> None: ...
@property
def crs(self) -> CRS | None: ...
@crs.setter
def crs(self, value: _ConvertibleToCRS) -> None: ...
def crs(self, value: _ConvertibleToCRS | None) -> None: ...
@classmethod
def from_dict( # type: ignore[override]
cls, data: Mapping[Hashable, Any], geometry: _GeometryColumn | None = None, crs: _ConvertibleToCRS | None = None, **kwargs
cls, data: Mapping[Hashable, Any], geometry: _GeomCol | None = None, crs: _ConvertibleToCRS | None = None, **kwargs
) -> Self: ...
@classmethod
def from_file(
Expand All @@ -97,7 +109,7 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
rows: int | slice | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
ignore_geometry: Literal[False] = False,
**kwargs: Any, # depends on engine
**kwargs, # engine dependent
) -> Self: ...
@classmethod
def from_features(
Expand All @@ -124,7 +136,7 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None,
*,
chunksize: int,
) -> Generator[GeoDataFrame, None, None]: ...
) -> Iterator[GeoDataFrame]: ...
@overload
@classmethod
def from_postgis(
Expand All @@ -140,15 +152,48 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
chunksize: None = None,
) -> GeoDataFrame: ...
def to_json( # type: ignore[override]
self, na: str = "null", show_bbox: bool = False, drop_id: bool = False, to_wgs84: bool = False, **kwargs
self,
na: str = "null",
show_bbox: bool = False,
drop_id: bool = False,
to_wgs84: bool = False,
*,
# json.dumps kwargs
skipkeys: bool = False,
ensure_ascii: bool = True,
check_circular: bool = True,
allow_nan: bool = True,
cls: type[JSONEncoder] | None = None,
indent: int | str | None = None,
separators: tuple[str, str] | None = None,
default: Callable[[Any], Any] | None = None,
sort_keys: bool = False,
**kwargs,
) -> str: ...
@property
def __geo_interface__(self) -> dict[str, Any]: ...
def iterfeatures(
self, na: str = "null", show_bbox: bool = False, drop_id: bool = False
) -> Generator[dict[str, Any], None, None]: ...
def to_wkb(self, hex: bool = False, **kwargs) -> pd.DataFrame: ...
def to_wkt(self, **kwargs) -> pd.DataFrame: ...
def iterfeatures(self, na: str = "null", show_bbox: bool = False, drop_id: bool = False) -> Iterator[dict[str, Any]]: ...
def to_wkb(
self,
hex: bool = False,
*,
# shapely kwargs
output_dimension: int = ...,
byte_order: int = ...,
include_srid: bool = ...,
flavor: Literal["iso", "extended"] = ...,
**kwargs,
) -> pd.DataFrame: ...
def to_wkt(
self,
*,
# shapely kwargs
rounding_precision: int = ...,
trim: bool = ...,
output_dimension: int = ...,
old_3d: bool = ...,
**kwargs,
) -> pd.DataFrame: ...
def to_parquet( # type: ignore[override]
self,
path: str | os.PathLike[str] | SupportsWrite[Incomplete],
Expand Down Expand Up @@ -184,15 +229,35 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
overwrite: bool | Incomplete = ..., # TODO can it be None? (accepted by fiona, not sure about pyogrio)
**kwargs: Any, # engine and driver dependent
) -> None: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS | None = None, epsg: int | None = None, inplace: bool = False, allow_override: bool = False
self, crs: _ConvertibleToCRS, epsg: int | None = None, inplace: bool = False, allow_override: bool = False
) -> Self: ...
def to_crs(self, crs: _ConvertibleToCRS | None = None, epsg: int | None = None, inplace: bool = False) -> Self | None: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: bool = False, allow_override: bool = False
) -> Self: ...
@overload
def set_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: bool = False, allow_override: bool = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None = None, inplace: Literal[False] = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: Literal[False] = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: Literal[False] = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None = None, *, inplace: Literal[True]) -> None: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None, inplace: Literal[True]) -> None: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: Literal[True]) -> None: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: Literal[True]) -> None: ...
def estimate_utm_crs(self, datum_name: str = "WGS 84") -> CRS: ...
# def __getitem__(self, key): ...
# def __setitem__(self, key, value) -> None: ...
def copy(self, deep: bool = True) -> Self: ...
def merge(self, *args, **kwargs) -> GeoDataFrame | pd.DataFrame: ...
# def merge(self, *args, **kwargs) -> GeoDataFrame | pd.DataFrame: ...
def apply( # type: ignore[override]
self,
func: Callable[..., Incomplete],
Expand Down Expand Up @@ -245,18 +310,26 @@ class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
chunksize: int | None = None,
dtype: dict[Any, Incomplete] | None = None,
) -> None: ...
@deprecated("'^' operator is deprecated. Use method `symmetric_difference` instead.")
@deprecated("'^' operator is deprecated. Use the `symmetric_difference` method instead.")
def __xor__(self, other: GeoSeries | Geometry) -> GeoSeries: ... # type: ignore[override]
@deprecated("'|' operator is deprecated. Use method `union` instead.")
@deprecated("'|' operator is deprecated. Use the `union` method instead.")
def __or__(self, other: GeoSeries | Geometry) -> GeoSeries: ... # type: ignore[override]
@deprecated("'&' operator is deprecated. Use method `intersection` instead.")
@deprecated("'&' operator is deprecated. Use the `intersection` method instead.")
def __and__(self, other: GeoSeries | Geometry) -> GeoSeries: ... # type: ignore[override]
@deprecated("'-' operator is deprecated. Use method `difference` instead.")
@deprecated("'-' operator is deprecated. Use the `difference` method instead.")
def __sub__(self, other: GeoSeries | Geometry) -> GeoSeries: ... # type: ignore[override]
@property
def plot(self) -> GeoplotAccessor: ...
explore = _explore
def sjoin(self, df: GeoDataFrame, *args, **kwargs) -> GeoDataFrame: ...
def sjoin(
self,
df: GeoDataFrame,
# *args, **kwargs passed to geopandas.sjoin
how: str = "inner",
predicate: str = "intersects",
lsuffix: str = "left",
rsuffix: str = "right",
) -> GeoDataFrame: ...
def sjoin_nearest(
self,
right: GeoDataFrame,
Expand Down
23 changes: 18 additions & 5 deletions stubs/geopandas-stubs/geoseries.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import json
import os
from _typeshed import Incomplete, SupportsRead, SupportsWrite, Unused
from collections.abc import Callable, Hashable, Mapping, Sequence
from typing import Any, Literal, overload
from typing import Any, Literal, final, overload
from typing_extensions import Self, TypeAlias, deprecated

import pandas as pd
Expand All @@ -25,7 +25,6 @@ _GeoListLike: TypeAlias = ArrayLike | Sequence[Geometry] | IndexOpsMixin[Incompl
_ConvertibleToGeoSeries: TypeAlias = Geometry | Mapping[int, Geometry] | Mapping[str, Geometry] | _GeoListLike

class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-var,misc] # pyright: ignore[reportInvalidTypeArguments]
crs: CRS
# Override the weird annotation of Series.__new__ in pandas-stubs
def __new__(
self,
Expand All @@ -49,6 +48,8 @@ class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-va
copy: bool | None = None,
fastpath: bool = False,
) -> None: ...
@final
def copy(self, deep: bool = True) -> Self: ... # to override pandas definition
@property
def values(self) -> GeometryArray: ...
@deprecated("Method `Series.append()` has been removed in pandas version '2.0'.")
Expand All @@ -71,7 +72,7 @@ class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-va
rows: int | slice | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
ignore_geometry: Literal[False] = False,
**kwargs: Any, # depends on engine
**kwargs: Any, # engine dependent
) -> GeoSeries: ...
@classmethod
def from_wkb(
Expand Down Expand Up @@ -149,10 +150,22 @@ class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-va
plot = plot_series # type: ignore[assignment] # pyright: ignore
explore = _explore_geoseries
def explode(self, ignore_index: bool = False, index_parts: bool | None = None) -> GeoSeries: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS, epsg: int | None = None, inplace: bool = False, allow_override: bool = False
) -> Self: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS | None = None, epsg: int | None = None, inplace: bool = False, allow_override: bool = False
self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: bool = False, allow_override: bool = False
) -> Self: ...
def to_crs(self, crs: _ConvertibleToCRS | None = None, epsg: int | None = None) -> GeoSeries: ...
@overload
def set_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: bool = False, allow_override: bool = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None = None) -> GeoSeries: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None = None, *, epsg: int) -> GeoSeries: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None, epsg: int) -> GeoSeries: ...
def estimate_utm_crs(self, datum_name: str = "WGS 84") -> CRS: ...
def to_json( # type: ignore[override]
self,
Expand Down
8 changes: 4 additions & 4 deletions stubs/geopandas-stubs/io/sql.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sqlite3
from collections.abc import Generator, Mapping
from collections.abc import Iterator, Mapping
from contextlib import AbstractContextManager
from typing import Any, Protocol, overload
from typing_extensions import TypeAlias, deprecated
Expand Down Expand Up @@ -85,7 +85,7 @@ def _read_postgis(
params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None,
*,
chunksize: int,
) -> Generator[GeoDataFrame, None, None]: ...
) -> Iterator[GeoDataFrame]: ...
@overload
def _read_postgis(
sql: str,
Expand All @@ -109,7 +109,7 @@ def _read_postgis(
parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None,
params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None,
chunksize: int | None = None,
) -> GeoDataFrame | Generator[GeoDataFrame, None, None]: ...
) -> GeoDataFrame | Iterator[GeoDataFrame]: ...
@deprecated("Function `geopandas.io.sql.read_postgis()` is deprecated. Use `geopandas.read_postgis()` instead.")
def read_postgis(
sql: str,
Expand All @@ -121,4 +121,4 @@ def read_postgis(
parse_dates: list[str] | dict[str, str] | dict[str, dict[str, Any]] | None = None,
params: list[Scalar] | tuple[Scalar, ...] | Mapping[str, Scalar] | None = None,
chunksize: int | None = None,
) -> GeoDataFrame | Generator[GeoDataFrame, None, None]: ...
) -> GeoDataFrame | Iterator[GeoDataFrame]: ...
Empty file added tests/geopandas/__init__.py
Empty file.
Loading

0 comments on commit ad88a76

Please sign in to comment.