Skip to content
Merged
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
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

```python
# Your code here

```
#### Problem description

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
environment-name: TEST
init-shell: bash
create-args: >-
python=3.12
python=3
--file requirements.txt
--file requirements-dev.txt

Expand Down
9 changes: 7 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repos:
files: requirements-dev.txt

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.12
rev: v0.12.2
hooks:
- id: ruff

Expand All @@ -28,7 +28,7 @@ repos:
language_version: python3

- repo: https://github.com/keewis/blackdoc
rev: v0.3.9
rev: v0.4.1
hooks:
- id: blackdoc

Expand All @@ -44,6 +44,11 @@ repos:
.*\.json |
)$

# - repo: https://github.com/woodruffw/zizmor-pre-commit
# rev: v1.11.0
# hooks:
# - id: zizmor

ci:
autofix_commit_msg: |
[pre-commit.ci] auto fixes from pre-commit.com hooks
Expand Down
7 changes: 3 additions & 4 deletions folium/elements.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from functools import wraps
from typing import List, Tuple

from branca.element import (
CssLink,
Expand All @@ -24,8 +23,8 @@ def inner(self, *args, **kwargs):
class JSCSSMixin(MacroElement):
"""Render links to external Javascript and CSS resources."""

default_js: List[Tuple[str, str]] = []
default_css: List[Tuple[str, str]] = []
default_js: list[tuple[str, str]] = []
default_css: list[tuple[str, str]] = []

# Since this is typically used as a mixin, we cannot
# override the _template member variable here. It would
Expand Down Expand Up @@ -53,7 +52,7 @@ def add_js_link(self, name: str, url: str):
"""Add or update JS resource link."""
self._add_link(name, url, self.default_js)

def _add_link(self, name: str, url: str, default_list: List[Tuple[str, str]]):
def _add_link(self, name: str, url: str, default_list: list[tuple[str, str]]):
"""Modify a css or js link.

If `name` does not exist, the link will be appended
Expand Down
30 changes: 13 additions & 17 deletions folium/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@
import json
import operator
import warnings
from collections.abc import Iterable, Sequence
from typing import (
Any,
Callable,
Dict,
Iterable,
List,
Optional,
Sequence,
Tuple,
Union,
get_args,
)
Expand Down Expand Up @@ -348,7 +344,7 @@ def render(self, **kwargs):
name=self.get_name(),
)

embed_mapping: Dict[Optional[int], Callable] = {
embed_mapping = {
1: self._embed_vegalite_v1,
2: self._embed_vegalite_v2,
3: self._embed_vegalite_v3,
Expand Down Expand Up @@ -851,7 +847,7 @@ def find_identifier(self) -> str:
"field to your geojson data or set `embed=True`. "
)

def _get_self_bounds(self) -> List[List[Optional[float]]]:
def _get_self_bounds(self) -> list[list[Optional[float]]]:
"""
Computes the bounds of the object itself (not including it's children)
in the form [[lat_min, lon_min], [lat_max, lon_max]].
Expand All @@ -871,7 +867,7 @@ def render(self, **kwargs):
super().render()


TypeStyleMapping = Dict[str, Union[str, List[Union[str, int]]]]
TypeStyleMapping = dict[str, Union[str, list[Union[str, int]]]]


class GeoJsonStyleMapper:
Expand Down Expand Up @@ -1756,9 +1752,9 @@ class DivIcon(MacroElement):
def __init__(
self,
html: Optional[str] = None,
icon_size: Optional[Tuple[int, int]] = None,
icon_anchor: Optional[Tuple[int, int]] = None,
popup_anchor: Optional[Tuple[int, int]] = None,
icon_size: Optional[tuple[int, int]] = None,
icon_anchor: Optional[tuple[int, int]] = None,
popup_anchor: Optional[tuple[int, int]] = None,
class_name: str = "empty",
):
super().__init__()
Expand Down Expand Up @@ -1932,12 +1928,12 @@ class CustomIcon(Icon):
def __init__(
self,
icon_image: Any,
icon_size: Optional[Tuple[int, int]] = None,
icon_anchor: Optional[Tuple[int, int]] = None,
icon_size: Optional[tuple[int, int]] = None,
icon_anchor: Optional[tuple[int, int]] = None,
shadow_image: Any = None,
shadow_size: Optional[Tuple[int, int]] = None,
shadow_anchor: Optional[Tuple[int, int]] = None,
popup_anchor: Optional[Tuple[int, int]] = None,
shadow_size: Optional[tuple[int, int]] = None,
shadow_anchor: Optional[tuple[int, int]] = None,
popup_anchor: Optional[tuple[int, int]] = None,
):
super(Icon, self).__init__()
self._name = "icon"
Expand Down Expand Up @@ -2016,7 +2012,7 @@ def __init__(
f"Unexpected type for argument `colormap`: {type(colormap)}"
)

out: Dict[str, List[List[List[float]]]] = {}
out: dict[str, list[list[list[float]]]] = {}
for (lat1, lng1), (lat2, lng2), color in zip(coords[:-1], coords[1:], colors):
out.setdefault(cm(color), []).append([[lat1, lng1], [lat2, lng2]])
for key, val in out.items():
Expand Down
5 changes: 3 additions & 2 deletions folium/folium.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import time
import webbrowser
from typing import Any, List, Optional, Sequence, Union
from collections.abc import Sequence
from typing import Any, Optional, Union

from branca.element import Element, Figure

Expand Down Expand Up @@ -337,7 +338,7 @@ def __init__(
**kwargs,
)

self.objects_to_stay_in_front: List[Layer] = []
self.objects_to_stay_in_front: list[Layer] = []

if isinstance(tiles, TileLayer):
self.add_child(tiles)
Expand Down
5 changes: 3 additions & 2 deletions folium/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import warnings
from collections import OrderedDict, defaultdict
from typing import TYPE_CHECKING, DefaultDict, Optional, Sequence, Union, cast
from collections.abc import Sequence
from typing import TYPE_CHECKING, Optional, Union, cast

from branca.element import Element, Figure, Html, MacroElement

Expand Down Expand Up @@ -38,7 +39,7 @@ def __get__(self, obj, owner):
class Class(MacroElement):
"""The root class of the leaflet class hierarchy"""

_includes: DefaultDict[str, dict] = defaultdict(dict)
_includes: defaultdict[str, dict] = defaultdict(dict)

@classmethod
def include(cls, **kwargs):
Expand Down
4 changes: 2 additions & 2 deletions folium/plugins/timeline.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Optional, TextIO, Union
from typing import Optional, TextIO, Union

from branca.element import MacroElement

Expand Down Expand Up @@ -242,7 +242,7 @@ def __init__(
"""
)

self.timelines: List[Timeline] = []
self.timelines: list[Timeline] = []
self.options = remove_empty(**kwargs)

def add_timelines(self, *args):
Expand Down
32 changes: 13 additions & 19 deletions folium/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,14 @@
import re
import tempfile
import uuid
from collections.abc import Iterable, Iterator, Sequence
from contextlib import contextmanager
from typing import (
TYPE_CHECKING,
Any,
Callable,
Dict,
Iterable,
Iterator,
List,
Literal,
Optional,
Sequence,
Tuple,
Type,
Union,
)
from urllib.parse import urlparse, uses_netloc, uses_params, uses_relative
Expand Down Expand Up @@ -55,7 +49,7 @@
TypePathOptions = Union[bool, str, float, None]

TypeBounds = Sequence[Sequence[float]]
TypeBoundsReturn = List[List[Optional[float]]]
TypeBoundsReturn = list[list[Optional[float]]]

TypeContainer = Union[Figure, Div, "Popup"]
TypePosition = Literal["bottomright", "bottomleft", "topright", "topleft"]
Expand All @@ -66,7 +60,7 @@
_VALID_URLS.add("data")


def validate_location(location: Sequence[float]) -> List[float]:
def validate_location(location: Sequence[float]) -> list[float]:
"""Validate a single lat/lon coordinate pair and convert to a list

Validate that location:
Expand Down Expand Up @@ -126,7 +120,7 @@ def _validate_locations_basics(locations: TypeMultiLine) -> None:
raise ValueError("Locations is empty.")


def validate_locations(locations: TypeLine) -> List[List[float]]:
def validate_locations(locations: TypeLine) -> list[list[float]]:
"""Validate an iterable with lat/lon coordinate pairs."""
locations = if_pandas_df_convert_to_numpy(locations)
_validate_locations_basics(locations)
Expand All @@ -135,7 +129,7 @@ def validate_locations(locations: TypeLine) -> List[List[float]]:

def validate_multi_locations(
locations: TypeMultiLine,
) -> Union[List[List[float]], List[List[List[float]]]]:
) -> Union[list[list[float]], list[list[list[float]]]]:
"""Validate an iterable with possibly nested lists of coordinate pairs."""
locations = if_pandas_df_convert_to_numpy(locations)
_validate_locations_basics(locations)
Expand Down Expand Up @@ -215,7 +209,7 @@ def _is_url(url: str) -> bool:

def mercator_transform(
data: Any,
lat_bounds: Tuple[float, float],
lat_bounds: tuple[float, float],
origin: str = "upper",
height_out: Optional[int] = None,
) -> np.ndarray:
Expand Down Expand Up @@ -279,7 +273,7 @@ def mercator(x):
return out


def iter_coords(obj: Any) -> Iterator[Tuple[float, ...]]:
def iter_coords(obj: Any) -> Iterator[tuple[float, ...]]:
"""
Returns all the coordinate tuples from a geometry or feature.

Expand Down Expand Up @@ -313,13 +307,13 @@ def iter_coords(obj: Any) -> Iterator[Tuple[float, ...]]:
def get_bounds(
locations: Any,
lonlat: bool = False,
) -> List[List[Optional[float]]]:
) -> list[list[Optional[float]]]:
"""
Computes the bounds of the object in the form
[[lat_min, lon_min], [lat_max, lon_max]]

"""
bounds: List[List[Optional[float]]] = [[None, None], [None, None]]
bounds: list[list[Optional[float]]] = [[None, None], [None, None]]
for point in iter_coords(locations):
bounds = [
[
Expand Down Expand Up @@ -397,22 +391,22 @@ def deep_copy(item_original: Element) -> Element:
return item


def get_obj_in_upper_tree(element: Element, cls: Type) -> Element:
def get_obj_in_upper_tree(element: Element, cls: type) -> Element:
"""Return the first object in the parent tree of class `cls`."""
parent = element._parent
if parent is None:
raise ValueError(f"The top of the tree was reached without finding a {cls}")
if not isinstance(parent, cls):
return get_obj_in_upper_tree(parent, cls)
return parent
return parent # type: ignore


def parse_options(**kwargs: TypeJsonValue) -> Dict[str, TypeJsonValueNoNone]:
def parse_options(**kwargs: TypeJsonValue) -> dict[str, TypeJsonValueNoNone]:
"""Return a dict with lower-camelcase keys and non-None values.."""
return {camelize(key): value for key, value in kwargs.items() if value is not None}


def remove_empty(**kwargs: TypeJsonValue) -> Dict[str, TypeJsonValueNoNone]:
def remove_empty(**kwargs: TypeJsonValue) -> dict[str, TypeJsonValueNoNone]:
"""Return a dict without None values."""
return {key: value for key, value in kwargs.items() if value is not None}

Expand Down
7 changes: 4 additions & 3 deletions folium/vector_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

"""

from typing import List, Optional, Sequence, Union
from collections.abc import Sequence
from typing import Optional, Union

from branca.element import MacroElement

Expand Down Expand Up @@ -147,7 +148,7 @@ def __init__(
tooltip if isinstance(tooltip, Tooltip) else Tooltip(str(tooltip))
)

def _get_self_bounds(self) -> List[List[Optional[float]]]:
def _get_self_bounds(self) -> list[list[Optional[float]]]:
"""Compute the bounds of the object itself."""
return get_bounds(self.locations)

Expand Down Expand Up @@ -289,7 +290,7 @@ def __init__(
tooltip if isinstance(tooltip, Tooltip) else Tooltip(str(tooltip))
)

def _get_self_bounds(self) -> List[List[Optional[float]]]:
def _get_self_bounds(self) -> list[list[Optional[float]]]:
"""Compute the bounds of the object itself."""
return get_bounds(self.locations)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ lint.select = [
"I", # import sorting
"U", # upgrade
]
target-version = "py37"
target-version = "py39"
line-length = 120

[lint.per-file-ignores]
Expand Down
Loading