From 30057a0c2418910aa245b6055ec3a28392f047f3 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:53:26 +0100 Subject: [PATCH 01/16] feat: Support `datetime.(date|datetime)` as a `SchemaBase` parameter #3651 --- altair/utils/schemapi.py | 23 +++++++++++++++++++++++ tools/schemapi/schemapi.py | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/altair/utils/schemapi.py b/altair/utils/schemapi.py index 3a730f2e5..8fa8c7025 100644 --- a/altair/utils/schemapi.py +++ b/altair/utils/schemapi.py @@ -4,6 +4,7 @@ import contextlib import copy +import datetime as dt import inspect import json import sys @@ -502,6 +503,26 @@ def _from_array_like(obj: Iterable[Any], /) -> list[Any]: return list(obj) +def _from_date_datetime(obj: dt.date | dt.datetime, /) -> dict[str, Any]: + """ + Parse native `datetime.(date|datetime)` into a `DateTime`_ schema. + + .. _DateTime: + https://vega.github.io/vega-lite/docs/datetime.html + """ + result: dict[str, Any] = {"year": obj.year, "month": obj.month, "date": obj.day} + if isinstance(obj, dt.datetime): + if obj.time() != dt.time.min: + us = obj.microsecond + ms = us if us == 0 else us // 1_000 + result.update( + hours=obj.hour, minutes=obj.minute, seconds=obj.second, milliseconds=ms + ) + if (name := obj.tzname()) and name == "UTC": + result["utc"] = True + return result + + def _todict(obj: Any, context: dict[str, Any] | None, np_opt: Any, pd_opt: Any) -> Any: # noqa: C901 """Convert an object to a dict representation.""" if np_opt is not None: @@ -532,6 +553,8 @@ def _todict(obj: Any, context: dict[str, Any] | None, np_opt: Any, pd_opt: Any) return pd_opt.Timestamp(obj).isoformat() elif _is_iterable(obj, exclude=(str, bytes)): return _todict(_from_array_like(obj), context, np_opt, pd_opt) + elif isinstance(obj, dt.date): + return _from_date_datetime(obj) else: return obj diff --git a/tools/schemapi/schemapi.py b/tools/schemapi/schemapi.py index bf08994bd..efc2c7522 100644 --- a/tools/schemapi/schemapi.py +++ b/tools/schemapi/schemapi.py @@ -2,6 +2,7 @@ import contextlib import copy +import datetime as dt import inspect import json import sys @@ -500,6 +501,26 @@ def _from_array_like(obj: Iterable[Any], /) -> list[Any]: return list(obj) +def _from_date_datetime(obj: dt.date | dt.datetime, /) -> dict[str, Any]: + """ + Parse native `datetime.(date|datetime)` into a `DateTime`_ schema. + + .. _DateTime: + https://vega.github.io/vega-lite/docs/datetime.html + """ + result: dict[str, Any] = {"year": obj.year, "month": obj.month, "date": obj.day} + if isinstance(obj, dt.datetime): + if obj.time() != dt.time.min: + us = obj.microsecond + ms = us if us == 0 else us // 1_000 + result.update( + hours=obj.hour, minutes=obj.minute, seconds=obj.second, milliseconds=ms + ) + if (name := obj.tzname()) and name == "UTC": + result["utc"] = True + return result + + def _todict(obj: Any, context: dict[str, Any] | None, np_opt: Any, pd_opt: Any) -> Any: # noqa: C901 """Convert an object to a dict representation.""" if np_opt is not None: @@ -530,6 +551,8 @@ def _todict(obj: Any, context: dict[str, Any] | None, np_opt: Any, pd_opt: Any) return pd_opt.Timestamp(obj).isoformat() elif _is_iterable(obj, exclude=(str, bytes)): return _todict(_from_array_like(obj), context, np_opt, pd_opt) + elif isinstance(obj, dt.date): + return _from_date_datetime(obj) else: return obj From 8ce69ce829c6470d8d49cc8c8d915c603573c975 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:53:58 +0100 Subject: [PATCH 02/16] test: Adds `test_to_dict_datetime` --- tests/utils/test_schemapi.py | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index d369ab29b..55f6868e0 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -2,6 +2,7 @@ from __future__ import annotations import copy +import datetime as dt import inspect import io import json @@ -1024,3 +1025,91 @@ def test_to_dict_range(tp) -> None: x_dict = alt.X("x:O", sort=tp(0, 5)).to_dict() actual = x_dict["sort"] # type: ignore assert actual == expected + + +@pytest.fixture +def stocks() -> alt.Chart: + source = "https://cdn.jsdelivr.net/npm/vega-datasets@v1.29.0/data/sp500.csv" + return alt.Chart(source).mark_area().encode(x="date:T", y="price:Q") + + +def DateTime( + year: int, + month: int, + day: int, + hour: int = 0, + minute: int = 0, + second: int = 0, + milliseconds: int = 0, + *, + utc: bool | None = None, +) -> alt.DateTime: + """Factory for positionally aligning `datetime.datetime`/ `alt.DateTime`.""" + kwds: dict[str, Any] = {} + if utc is True: + kwds.update(utc=utc) + if (hour, minute, second, milliseconds) != (0, 0, 0, 0): + kwds.update( + hours=hour, minutes=minute, seconds=second, milliseconds=milliseconds + ) + return alt.DateTime(year=year, month=month, date=day, **kwds) + + +@pytest.mark.parametrize( + ("window", "expected"), + [ + ( + (dt.date(2005, 1, 1), dt.date(2009, 1, 1)), + (DateTime(2005, 1, 1), DateTime(2009, 1, 1)), + ), + ( + (dt.datetime(2005, 1, 1), dt.datetime(2009, 1, 1)), + ( + # NOTE: Keep this to test truncating independently! + alt.DateTime(year=2005, month=1, date=1), + alt.DateTime(year=2009, month=1, date=1), + ), + ), + ( + ( + dt.datetime(2001, 1, 1, 9, 30, 0, 2999), + dt.datetime(2002, 1, 1, 17, 0, 0, 5000), + ), + ( + DateTime(2001, 1, 1, 9, 30, 0, 2), + DateTime(2002, 1, 1, 17, 0, 0, 5), + ), + ), + ( + ( + dt.datetime(2003, 5, 1, 1, 30, tzinfo=dt.timezone.utc), + dt.datetime(2003, 6, 3, 4, 3, tzinfo=dt.timezone.utc), + ), + ( + DateTime(2003, 5, 1, 1, 30, 0, 0, utc=True), + DateTime(2003, 6, 3, 4, 3, 0, 0, utc=True), + ), + ), + ], + ids=["date", "datetime (no time)", "datetime (microseconds)", "datetime (UTC)"], +) +def test_to_dict_datetime( + stocks, window: tuple[Any, Any], expected: tuple[alt.DateTime, alt.DateTime] +) -> None: + """ + Includes `datetime.datetime` with an empty time component. + + This confirms that conversion matches how `alt.DateTime` omits `Undefined`. + """ + expected_dicts = [e.to_dict() for e in expected] + brush = alt.selection_interval(encodings=["x"], value={"x": window}) + base = stocks + + upper = base.encode(alt.X("date:T").scale(domain=brush)) + lower = base.add_params(brush) + chart = upper & lower + mapping = chart.to_dict() + params_value = mapping["params"][0]["value"]["x"] + + assert isinstance(params_value, list) + assert params_value == expected_dicts From 59bc8d8dd7955045c897ebadddab6ce222f5a2f9 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:49:35 +0100 Subject: [PATCH 03/16] feat: Reject non-UTC timezones The [vega-lite docs](https://vega.github.io/vega-lite/docs/datetime.html) don't mention the `utc` property - but this restricts us to `utc` or `None` --- altair/utils/schemapi.py | 12 ++++++++++-- tests/utils/test_schemapi.py | 19 +++++++++++++++++++ tools/schemapi/schemapi.py | 12 ++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/altair/utils/schemapi.py b/altair/utils/schemapi.py index 8fa8c7025..e5439dc55 100644 --- a/altair/utils/schemapi.py +++ b/altair/utils/schemapi.py @@ -518,8 +518,16 @@ def _from_date_datetime(obj: dt.date | dt.datetime, /) -> dict[str, Any]: result.update( hours=obj.hour, minutes=obj.minute, seconds=obj.second, milliseconds=ms ) - if (name := obj.tzname()) and name == "UTC": - result["utc"] = True + if name := obj.tzname(): + if name == "UTC": + result["utc"] = True + else: + msg = ( + f"Unsupported timezone {name!r}.\n" + "Only `'UTC'` or naive (local) datetimes are permitted.\n" + "See https://altair-viz.github.io/user_guide/generated/core/altair.DateTime.html" + ) + raise TypeError(msg) return result diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index 55f6868e0..89943c95d 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -1113,3 +1113,22 @@ def test_to_dict_datetime( assert isinstance(params_value, list) assert params_value == expected_dicts + + +@pytest.mark.parametrize( + "tzinfo", + [ + dt.timezone(dt.timedelta(hours=2), "UTC+2"), + dt.timezone(dt.timedelta(hours=1), "BST"), + dt.timezone(dt.timedelta(hours=-7), "pdt"), + dt.timezone(dt.timedelta(hours=-3), "BRT"), + ], +) +def test_to_dict_datetime_unsupported_timezone(tzinfo: dt.timezone) -> None: + datetime = dt.datetime(2003, 5, 1, 1, 30) + + result = alt.FieldEqualPredicate(datetime, "column 1") # type: ignore[arg-type] + assert result.to_dict() + + with pytest.raises(TypeError, match=r"Unsupported timezone.+\n.+UTC.+local"): + alt.FieldEqualPredicate(datetime.replace(tzinfo=tzinfo), "column 1") # type: ignore[arg-type] diff --git a/tools/schemapi/schemapi.py b/tools/schemapi/schemapi.py index efc2c7522..f874c5042 100644 --- a/tools/schemapi/schemapi.py +++ b/tools/schemapi/schemapi.py @@ -516,8 +516,16 @@ def _from_date_datetime(obj: dt.date | dt.datetime, /) -> dict[str, Any]: result.update( hours=obj.hour, minutes=obj.minute, seconds=obj.second, milliseconds=ms ) - if (name := obj.tzname()) and name == "UTC": - result["utc"] = True + if name := obj.tzname(): + if name == "UTC": + result["utc"] = True + else: + msg = ( + f"Unsupported timezone {name!r}.\n" + "Only `'UTC'` or naive (local) datetimes are permitted.\n" + "See https://altair-viz.github.io/user_guide/generated/core/altair.DateTime.html" + ) + raise TypeError(msg) return result From 62ba4ef01c7c57adf75b975eddadea012d338f5b Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:38:24 +0100 Subject: [PATCH 04/16] test(typing): Adds `test_to_dict_datetime_typing` Annotation support will be complete once `mypy` starts complaining that these comments are unused --- tests/utils/test_schemapi.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index 89943c95d..e9a4fdf0c 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -1132,3 +1132,32 @@ def test_to_dict_datetime_unsupported_timezone(tzinfo: dt.timezone) -> None: with pytest.raises(TypeError, match=r"Unsupported timezone.+\n.+UTC.+local"): alt.FieldEqualPredicate(datetime.replace(tzinfo=tzinfo), "column 1") # type: ignore[arg-type] + + +def test_to_dict_datetime_typing() -> None: + """ + Enumerating various places that need updated annotations. + + All work at runtime, just need to give the type checkers the new info. + + Sub-issue of https://github.com/vega/altair/issues/3650 + """ + datetime = dt.datetime(2003, 5, 1, 1, 30) + datetime_seq = [datetime, datetime.replace(2005), datetime.replace(2008)] + assert alt.FieldEqualPredicate(datetime, field="column 1") # type: ignore[arg-type] + assert alt.FieldOneOfPredicate( + oneOf=datetime_seq, # type: ignore[arg-type] + field="column 1", + ) # type: ignore[arg-type] + + assert alt.Legend(values=datetime_seq) # type: ignore[arg-type] + + assert alt.Scale(domain=datetime_seq) # type: ignore[arg-type] + assert alt.Scale(domainMin=datetime_seq[0], domainMax=datetime_seq[2]) # type: ignore[arg-type] + + # NOTE: `datum` is not annotated? + assert alt.XDatum(datum=datetime).to_dict() + + # NOTE: `*args` is not annotated? + # - All of these uses *args incorrectly + assert alt.Vector2DateTime(datetime_seq[:2]) From 5fb8f730c98890d901831c16a036fa39487c88cd Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:41:58 +0100 Subject: [PATCH 05/16] fix(typing): Remove unused ignore https://github.com/vega/altair/actions/runs/11460348337/job/31886851940?pr=3653 --- tests/utils/test_schemapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index e9a4fdf0c..8d51f641e 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -1148,7 +1148,7 @@ def test_to_dict_datetime_typing() -> None: assert alt.FieldOneOfPredicate( oneOf=datetime_seq, # type: ignore[arg-type] field="column 1", - ) # type: ignore[arg-type] + ) assert alt.Legend(values=datetime_seq) # type: ignore[arg-type] From 8e27a38645004f7fecb72e20a165b22adbe8b664 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:29:31 +0100 Subject: [PATCH 06/16] feat(typing): Adds `Temporal` alias --- altair/vegalite/v5/schema/_typing.py | 4 ++++ tools/generate_schema_wrapper.py | 6 ++++++ tools/schemapi/utils.py | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/altair/vegalite/v5/schema/_typing.py b/altair/vegalite/v5/schema/_typing.py index f1fbbb4db..dd7bdfb2c 100644 --- a/altair/vegalite/v5/schema/_typing.py +++ b/altair/vegalite/v5/schema/_typing.py @@ -6,6 +6,7 @@ import re import sys from collections.abc import Mapping, Sequence +from datetime import date, datetime from typing import Annotated, Any, Generic, Literal, TypeVar, Union, get_args if sys.version_info >= (3, 14): # https://peps.python.org/pep-0728/ @@ -86,6 +87,7 @@ "StepFor_T", "StrokeCap_T", "StrokeJoin_T", + "Temporal", "TextBaseline_T", "TextDirection_T", "TimeInterval_T", @@ -197,6 +199,8 @@ class PaddingKwds(TypedDict, total=False): top: float +Temporal: TypeAlias = Union[date, datetime] + VegaThemes: TypeAlias = Literal[ "carbong10", "carbong100", diff --git a/tools/generate_schema_wrapper.py b/tools/generate_schema_wrapper.py index bf42cdf96..8787508ca 100644 --- a/tools/generate_schema_wrapper.py +++ b/tools/generate_schema_wrapper.py @@ -255,6 +255,7 @@ class {name}(TypedDict{metaclass_kwds}):{comment} THEME_CONFIG: Literal["ThemeConfig"] = "ThemeConfig" PADDING_KWDS: Literal["PaddingKwds"] = "PaddingKwds" ROW_COL_KWDS: Literal["RowColKwds"] = "RowColKwds" +TEMPORAL: Literal["Temporal"] = "Temporal" ENCODE_KWDS_SUMMARY: Final = ( "Encoding channels map properties of the data to visual properties of the chart." ) @@ -392,6 +393,8 @@ class PaddingKwds(TypedDict, total=False): left: float right: float top: float + +Temporal: TypeAlias = Union[date, datetime] ''' _ChannelType = Literal["field", "datum", "value"] @@ -667,6 +670,7 @@ def generate_vegalite_schema_wrapper(fp: Path, /) -> str: "from narwhals.dependencies import is_pandas_dataframe as _is_pandas_dataframe", "from altair.utils.schemapi import SchemaBase, Undefined, UndefinedType, _subclasses # noqa: F401\n", import_type_checking( + "from datetime import date, datetime", "from altair import Parameter", "from altair.typing import Optional", "from ._typing import * # noqa: F403", @@ -792,6 +796,7 @@ def generate_vegalite_channel_wrappers(fp: Path, /) -> str: CHANNEL_MYPY_IGNORE_STATEMENTS, *imports, import_type_checking( + "from datetime import date, datetime", "from altair import Parameter, SchemaBase", "from altair.typing import Optional", f"from altair.vegalite.v5.api import {INTO_CONDITION}", @@ -1102,6 +1107,7 @@ def vegalite_main(skip_download: bool = False) -> None: "is_color_hex", ROW_COL_KWDS, PADDING_KWDS, + TEMPORAL, header=HEADER, extra=TYPING_EXTRA, ) diff --git a/tools/schemapi/utils.py b/tools/schemapi/utils.py index 31a64a4f2..4acc8545c 100644 --- a/tools/schemapi/utils.py +++ b/tools/schemapi/utils.py @@ -100,6 +100,7 @@ def __init__(self, fmt: str = "{}_T") -> None: self._imports: Sequence[str] = ( "from __future__ import annotations\n", "import sys", + "from datetime import date, datetime", "from typing import Annotated, Any, Generic, Literal, Mapping, TypeVar, Sequence, Union, get_args", "import re", import_typing_extensions( @@ -524,6 +525,8 @@ def title_to_type_reprs(self, *, use_concrete: bool) -> set[str]: # NOTE: To keep type hints simple, we annotate with `SchemaBase` for all subclasses. if title in tp_param: tps.add("Parameter") + if self.is_datetime(): + tps.add("Temporal") elif self.is_value(): value = self.properties["value"] t = value.to_type_repr(target="annotation", use_concrete=use_concrete) @@ -783,6 +786,9 @@ def is_theme_config_target(self) -> bool: and not (iskeyword(next(iter(self.required), ""))) ) + def is_datetime(self) -> bool: + return self.refname == "DateTime" + def flatten(container: Iterable) -> Iterable: """ From b6711c7ab5c11e9efd2fc9b04105496d4407a487 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:31:01 +0100 Subject: [PATCH 07/16] build: run `generate-schema-wrapper` **Expecting to fail `mypy`** https://github.com/vega/altair/pull/3653#discussion_r1810655676 --- altair/vegalite/v5/schema/channels.py | 466 +++++++++++++++++--------- altair/vegalite/v5/schema/core.py | 96 ++++-- 2 files changed, 363 insertions(+), 199 deletions(-) diff --git a/altair/vegalite/v5/schema/channels.py b/altair/vegalite/v5/schema/channels.py index f0a7e0978..c068ad87e 100644 --- a/altair/vegalite/v5/schema/channels.py +++ b/altair/vegalite/v5/schema/channels.py @@ -651,7 +651,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -673,12 +673,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -845,7 +851,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -1075,7 +1081,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -1093,7 +1099,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -1120,7 +1126,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -1137,7 +1143,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -1577,7 +1583,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -1599,12 +1605,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -1771,7 +1783,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -2004,7 +2016,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -2022,7 +2034,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -2049,7 +2061,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -2066,7 +2078,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -2549,7 +2561,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | SortOrder_T ] = Undefined, @@ -3002,7 +3014,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -3020,7 +3032,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -3047,7 +3059,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -3064,7 +3076,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -3931,7 +3943,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | SortOrder_T ] = Undefined, @@ -4361,7 +4373,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -4383,12 +4395,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -4555,7 +4573,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -4788,7 +4806,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -4806,7 +4824,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -4833,7 +4851,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -4850,7 +4868,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -5289,7 +5307,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -5311,12 +5329,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -5483,7 +5507,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -5715,7 +5739,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -5733,7 +5757,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -5760,7 +5784,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -5777,7 +5801,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -6242,7 +6266,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -6260,7 +6284,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -6287,7 +6311,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -6304,7 +6328,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -8665,7 +8689,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -8687,12 +8711,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -8859,7 +8889,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -9089,7 +9119,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -9107,7 +9137,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -9134,7 +9164,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -9151,7 +9181,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -9869,12 +9899,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -10048,7 +10084,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -10238,12 +10274,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -11159,7 +11201,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | SortOrder_T ] = Undefined, @@ -11587,7 +11629,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -11609,12 +11651,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -11781,7 +11829,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -12014,7 +12062,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -12032,7 +12080,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -12059,7 +12107,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -12076,7 +12124,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -12513,7 +12561,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -12535,12 +12583,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -12707,7 +12761,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -12937,7 +12991,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -12955,7 +13009,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -12982,7 +13036,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -12999,7 +13053,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -13439,7 +13493,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -13461,12 +13515,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -13633,7 +13693,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -13866,7 +13926,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -13884,7 +13944,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -13911,7 +13971,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -13928,7 +13988,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -14367,7 +14427,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -14389,12 +14449,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -14561,7 +14627,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -14793,7 +14859,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -14811,7 +14877,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -14838,7 +14904,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -14855,7 +14921,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -15294,7 +15360,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -15316,12 +15382,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -15488,7 +15560,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -15720,7 +15792,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -15738,7 +15810,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -15765,7 +15837,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -15782,7 +15854,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -16221,7 +16293,7 @@ def legend( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -16243,12 +16315,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -16415,7 +16493,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -16647,7 +16725,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -16665,7 +16743,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -16692,7 +16770,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -16709,7 +16787,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -17740,12 +17818,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -17919,7 +18003,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -18109,12 +18193,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -19012,7 +19102,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -19030,7 +19120,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -19057,7 +19147,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -19074,7 +19164,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -19539,7 +19629,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -19557,7 +19647,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -19584,7 +19674,7 @@ def condition( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -19601,7 +19691,7 @@ def condition( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, empty: Optional[bool] = Undefined, legend: Optional[None | SchemaBase | Map] = Undefined, @@ -20022,7 +20112,7 @@ def axis( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -20095,12 +20185,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -20276,7 +20372,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -20581,7 +20677,7 @@ def axis( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -20619,12 +20715,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -21865,12 +21967,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -22035,7 +22143,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -22193,12 +22301,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -22662,7 +22776,7 @@ def axis( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -22735,12 +22849,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -22916,7 +23036,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -23221,7 +23341,7 @@ def axis( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -23259,12 +23379,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -24505,12 +24631,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -24675,7 +24807,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -24833,12 +24965,18 @@ def scale( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ diff --git a/altair/vegalite/v5/schema/core.py b/altair/vegalite/v5/schema/core.py index 26dd8a8f2..b633d389d 100644 --- a/altair/vegalite/v5/schema/core.py +++ b/altair/vegalite/v5/schema/core.py @@ -1725,7 +1725,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -2302,7 +2302,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -5647,7 +5647,7 @@ class DomainUnionWith(VegaLiteSchema): def __init__( self, unionWith: Optional[ - Sequence[str | bool | float | SchemaBase | Map] + Sequence[str | bool | float | Temporal | SchemaBase | Map] ] = Undefined, **kwds, ): @@ -6600,7 +6600,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | SortOrder_T ] = Undefined, @@ -6826,7 +6826,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | SortOrder_T ] = Undefined, @@ -9728,7 +9728,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map ] = Undefined, zindex: Optional[float] = Undefined, @@ -12470,7 +12470,7 @@ def __init__( bandPosition: Optional[float] = Undefined, condition: Optional[SchemaBase | Sequence[SchemaBase | Map] | Map] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, title: Optional[str | None | SchemaBase | Sequence[str]] = Undefined, type: Optional[SchemaBase | Type_T] = Undefined, @@ -12728,7 +12728,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -13120,7 +13120,7 @@ def __init__( bandPosition: Optional[float] = Undefined, condition: Optional[SchemaBase | Sequence[SchemaBase | Map] | Map] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, title: Optional[str | None | SchemaBase | Sequence[str]] = Undefined, type: Optional[SchemaBase | Type_T] = Undefined, @@ -13378,7 +13378,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -13529,7 +13529,7 @@ def __init__( bandPosition: Optional[float] = Undefined, condition: Optional[SchemaBase | Sequence[SchemaBase | Map] | Map] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, title: Optional[str | None | SchemaBase | Sequence[str]] = Undefined, type: Optional[SchemaBase | Type_T] = Undefined, @@ -13787,7 +13787,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -15164,7 +15164,7 @@ def __init__( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, title: Optional[str | None | SchemaBase | Sequence[str]] = Undefined, type: Optional[SchemaBase | Type_T] = Undefined, @@ -15324,7 +15324,7 @@ def __init__( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, stack: Optional[bool | None | SchemaBase | StackOffset_T] = Undefined, @@ -15519,7 +15519,7 @@ def __init__( axis: Optional[None | SchemaBase | Map] = Undefined, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, impute: Optional[None | SchemaBase | Map] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, @@ -15810,7 +15810,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -16090,7 +16090,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -16229,7 +16229,9 @@ class FieldEqualPredicate(Predicate): def __init__( self, - equal: Optional[str | bool | float | Parameter | SchemaBase | Map] = Undefined, + equal: Optional[ + str | bool | float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, field: Optional[str | SchemaBase] = Undefined, timeUnit: Optional[ SchemaBase | Map | MultiTimeUnit_T | BinnedTimeUnit_T | SingleTimeUnit_T @@ -16258,7 +16260,9 @@ class FieldGTEPredicate(Predicate): def __init__( self, field: Optional[str | SchemaBase] = Undefined, - gte: Optional[str | float | Parameter | SchemaBase | Map] = Undefined, + gte: Optional[ + str | float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, timeUnit: Optional[ SchemaBase | Map | MultiTimeUnit_T | BinnedTimeUnit_T | SingleTimeUnit_T ] = Undefined, @@ -16286,7 +16290,7 @@ class FieldGTPredicate(Predicate): def __init__( self, field: Optional[str | SchemaBase] = Undefined, - gt: Optional[str | float | Parameter | SchemaBase | Map] = Undefined, + gt: Optional[str | float | Temporal | Parameter | SchemaBase | Map] = Undefined, timeUnit: Optional[ SchemaBase | Map | MultiTimeUnit_T | BinnedTimeUnit_T | SingleTimeUnit_T ] = Undefined, @@ -16314,7 +16318,9 @@ class FieldLTEPredicate(Predicate): def __init__( self, field: Optional[str | SchemaBase] = Undefined, - lte: Optional[str | float | Parameter | SchemaBase | Map] = Undefined, + lte: Optional[ + str | float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, timeUnit: Optional[ SchemaBase | Map | MultiTimeUnit_T | BinnedTimeUnit_T | SingleTimeUnit_T ] = Undefined, @@ -16342,7 +16348,7 @@ class FieldLTPredicate(Predicate): def __init__( self, field: Optional[str | SchemaBase] = Undefined, - lt: Optional[str | float | Parameter | SchemaBase | Map] = Undefined, + lt: Optional[str | float | Temporal | Parameter | SchemaBase | Map] = Undefined, timeUnit: Optional[ SchemaBase | Map | MultiTimeUnit_T | BinnedTimeUnit_T | SingleTimeUnit_T ] = Undefined, @@ -16375,7 +16381,7 @@ def __init__( Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] ] = Undefined, timeUnit: Optional[ SchemaBase | Map | MultiTimeUnit_T | BinnedTimeUnit_T | SingleTimeUnit_T @@ -16408,7 +16414,7 @@ def __init__( range: Optional[ Parameter | SchemaBase - | Sequence[None | float | Parameter | SchemaBase | Map] + | Sequence[None | float | Temporal | Parameter | SchemaBase | Map] | Map ] = Undefined, timeUnit: Optional[ @@ -17987,7 +17993,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | SortOrder_T ] = Undefined, @@ -18290,12 +18296,18 @@ def __init__( Parameter | SchemaBase | Literal["unaggregated"] - | Sequence[str | bool | None | float | Parameter | SchemaBase | Map] + | Sequence[ + str | bool | None | float | Temporal | Parameter | SchemaBase | Map + ] | Map ] = Undefined, - domainMax: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMax: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainMid: Optional[float | Parameter | SchemaBase | Map] = Undefined, - domainMin: Optional[float | Parameter | SchemaBase | Map] = Undefined, + domainMin: Optional[ + float | Temporal | Parameter | SchemaBase | Map + ] = Undefined, domainRaw: Optional[Parameter | SchemaBase | Map] = Undefined, exponent: Optional[float | Parameter | SchemaBase | Map] = Undefined, interpolate: Optional[ @@ -18742,7 +18754,7 @@ def __init__( self, bandPosition: Optional[float] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, scale: Optional[None | SchemaBase | Map] = Undefined, title: Optional[str | None | SchemaBase | Sequence[str]] = Undefined, @@ -18979,7 +18991,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -20072,7 +20084,14 @@ def __init__( select: Optional[SchemaBase | Map | SelectionType_T] = Undefined, bind: Optional[SchemaBase | Literal["legend", "scales"] | Map] = Undefined, value: Optional[ - str | bool | None | float | SchemaBase | Sequence[SchemaBase | Map] | Map + str + | bool + | None + | float + | Temporal + | SchemaBase + | Sequence[SchemaBase | Map] + | Map ] = Undefined, **kwds, ): @@ -20297,7 +20316,7 @@ def __init__( bandPosition: Optional[float] = Undefined, condition: Optional[SchemaBase | Sequence[SchemaBase | Map] | Map] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, title: Optional[str | None | SchemaBase | Sequence[str]] = Undefined, type: Optional[SchemaBase | Type_T] = Undefined, @@ -20555,7 +20574,7 @@ def __init__( | Sequence[str] | Sequence[bool] | Sequence[float] - | Sequence[SchemaBase | Map] + | Sequence[Temporal | SchemaBase | Map] | Map | AllSortString_T ] = Undefined, @@ -22766,7 +22785,7 @@ def __init__( bandPosition: Optional[float] = Undefined, condition: Optional[SchemaBase | Sequence[SchemaBase | Map] | Map] = Undefined, datum: Optional[ - str | bool | None | float | Parameter | SchemaBase | Map + str | bool | None | float | Temporal | Parameter | SchemaBase | Map ] = Undefined, format: Optional[str | SchemaBase | Map] = Undefined, formatType: Optional[str] = Undefined, @@ -24223,7 +24242,14 @@ def __init__( select: Optional[SchemaBase | Map | SelectionType_T] = Undefined, bind: Optional[SchemaBase | Literal["legend", "scales"] | Map] = Undefined, value: Optional[ - str | bool | None | float | SchemaBase | Sequence[SchemaBase | Map] | Map + str + | bool + | None + | float + | Temporal + | SchemaBase + | Sequence[SchemaBase | Map] + | Map ] = Undefined, views: Optional[Sequence[str]] = Undefined, **kwds, From 29c500c925974b2ed672554e644a10af212a9d42 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:16:21 +0100 Subject: [PATCH 08/16] fix(typing): Remove unused ignores https://github.com/vega/altair/pull/3653#discussion_r1810655676, https://github.com/vega/altair/actions/runs/11461315861/job/31890019636?pr=3653 --- tests/utils/test_schemapi.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index 8d51f641e..fd945e4c8 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -1127,11 +1127,11 @@ def test_to_dict_datetime( def test_to_dict_datetime_unsupported_timezone(tzinfo: dt.timezone) -> None: datetime = dt.datetime(2003, 5, 1, 1, 30) - result = alt.FieldEqualPredicate(datetime, "column 1") # type: ignore[arg-type] + result = alt.FieldEqualPredicate(datetime, "column 1") assert result.to_dict() with pytest.raises(TypeError, match=r"Unsupported timezone.+\n.+UTC.+local"): - alt.FieldEqualPredicate(datetime.replace(tzinfo=tzinfo), "column 1") # type: ignore[arg-type] + alt.FieldEqualPredicate(datetime.replace(tzinfo=tzinfo), "column 1") def test_to_dict_datetime_typing() -> None: @@ -1144,16 +1144,13 @@ def test_to_dict_datetime_typing() -> None: """ datetime = dt.datetime(2003, 5, 1, 1, 30) datetime_seq = [datetime, datetime.replace(2005), datetime.replace(2008)] - assert alt.FieldEqualPredicate(datetime, field="column 1") # type: ignore[arg-type] - assert alt.FieldOneOfPredicate( - oneOf=datetime_seq, # type: ignore[arg-type] - field="column 1", - ) + assert alt.FieldEqualPredicate(datetime, field="column 1") + assert alt.FieldOneOfPredicate(oneOf=datetime_seq, field="column 1") - assert alt.Legend(values=datetime_seq) # type: ignore[arg-type] + assert alt.Legend(values=datetime_seq) - assert alt.Scale(domain=datetime_seq) # type: ignore[arg-type] - assert alt.Scale(domainMin=datetime_seq[0], domainMax=datetime_seq[2]) # type: ignore[arg-type] + assert alt.Scale(domain=datetime_seq) + assert alt.Scale(domainMin=datetime_seq[0], domainMax=datetime_seq[2]) # NOTE: `datum` is not annotated? assert alt.XDatum(datum=datetime).to_dict() From 33b6868b827bbaaba22c7d0c94cf26b6cc5d1ac3 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:13:42 +0100 Subject: [PATCH 09/16] fix: Use object identity for `utc` test instead of name Adds two tests with "fake" utc timezones --- altair/utils/schemapi.py | 6 +++--- tests/utils/test_schemapi.py | 2 ++ tools/schemapi/schemapi.py | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/altair/utils/schemapi.py b/altair/utils/schemapi.py index e5439dc55..7eaab77c1 100644 --- a/altair/utils/schemapi.py +++ b/altair/utils/schemapi.py @@ -518,12 +518,12 @@ def _from_date_datetime(obj: dt.date | dt.datetime, /) -> dict[str, Any]: result.update( hours=obj.hour, minutes=obj.minute, seconds=obj.second, milliseconds=ms ) - if name := obj.tzname(): - if name == "UTC": + if tzinfo := obj.tzinfo: + if tzinfo is dt.timezone.utc: result["utc"] = True else: msg = ( - f"Unsupported timezone {name!r}.\n" + f"Unsupported timezone {tzinfo!r}.\n" "Only `'UTC'` or naive (local) datetimes are permitted.\n" "See https://altair-viz.github.io/user_guide/generated/core/altair.DateTime.html" ) diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index fd945e4c8..5b0e94677 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -1122,6 +1122,8 @@ def test_to_dict_datetime( dt.timezone(dt.timedelta(hours=1), "BST"), dt.timezone(dt.timedelta(hours=-7), "pdt"), dt.timezone(dt.timedelta(hours=-3), "BRT"), + dt.timezone(dt.timedelta(hours=9), "UTC"), + dt.timezone(dt.timedelta(minutes=60), "utc"), ], ) def test_to_dict_datetime_unsupported_timezone(tzinfo: dt.timezone) -> None: diff --git a/tools/schemapi/schemapi.py b/tools/schemapi/schemapi.py index f874c5042..b41c61a85 100644 --- a/tools/schemapi/schemapi.py +++ b/tools/schemapi/schemapi.py @@ -516,12 +516,12 @@ def _from_date_datetime(obj: dt.date | dt.datetime, /) -> dict[str, Any]: result.update( hours=obj.hour, minutes=obj.minute, seconds=obj.second, milliseconds=ms ) - if name := obj.tzname(): - if name == "UTC": + if tzinfo := obj.tzinfo: + if tzinfo is dt.timezone.utc: result["utc"] = True else: msg = ( - f"Unsupported timezone {name!r}.\n" + f"Unsupported timezone {tzinfo!r}.\n" "Only `'UTC'` or naive (local) datetimes are permitted.\n" "See https://altair-viz.github.io/user_guide/generated/core/altair.DateTime.html" ) From 30b5a3c1a06573366bdd14278b76f42a025a5bab Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Wed, 23 Oct 2024 11:46:51 +0100 Subject: [PATCH 10/16] refactor(typing): Narrow `selection_(interval|point)(value=...)` types - Tentative - Copied from `core.SelectionParameter` --- altair/vegalite/v5/api.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index b10fb88a4..4384ea653 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -88,6 +88,7 @@ SingleDefUnitChannel_T, SingleTimeUnit_T, StackOffset_T, + Temporal, ) from .schema.channels import Column, Facet, Row from .schema.core import ( @@ -1438,7 +1439,16 @@ def selection(type: Optional[SelectionType_T] = Undefined, **kwds: Any) -> Param def selection_interval( name: str | None = None, - value: Optional[Any] = Undefined, + value: Optional[ + str + | bool + | None + | float + | Temporal + | SchemaBase + | Sequence[SchemaBase | Map] + | Map + ] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, expr: Optional[str | Expr | Expression] = Undefined, @@ -1551,7 +1561,16 @@ def selection_interval( def selection_point( name: str | None = None, - value: Optional[Any] = Undefined, + value: Optional[ + str + | bool + | None + | float + | Temporal + | SchemaBase + | Sequence[SchemaBase | Map] + | Map + ] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, expr: Optional[Expr] = Undefined, From 063fee9d5989b1bb7026edf8e302ce7336ca9a0b Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:12:28 +0100 Subject: [PATCH 11/16] refactor(typing): Utilize `PrimitiveValue_T` https://github.com/vega/altair/pull/3656 --- altair/vegalite/v5/api.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index 4384ea653..02134b273 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -30,7 +30,7 @@ from .data import data_transformers from .display import VEGA_VERSION, VEGAEMBED_VERSION, VEGALITE_VERSION, renderers from .schema import SCHEMA_URL, channels, core, mixins -from .schema._typing import Map +from .schema._typing import Map, PrimitiveValue_T from .theme import themes if sys.version_info >= (3, 14): @@ -1440,14 +1440,7 @@ def selection(type: Optional[SelectionType_T] = Undefined, **kwds: Any) -> Param def selection_interval( name: str | None = None, value: Optional[ - str - | bool - | None - | float - | Temporal - | SchemaBase - | Sequence[SchemaBase | Map] - | Map + PrimitiveValue_T | Temporal | SchemaBase | Sequence[SchemaBase | Map] | Map ] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, @@ -1562,14 +1555,7 @@ def selection_interval( def selection_point( name: str | None = None, value: Optional[ - str - | bool - | None - | float - | Temporal - | SchemaBase - | Sequence[SchemaBase | Map] - | Map + PrimitiveValue_T | Temporal | SchemaBase | Sequence[SchemaBase | Map] | Map ] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, From 23f7a70adc1efa3085b178b4d8bb6fbac50100fc Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Wed, 23 Oct 2024 21:14:13 +0100 Subject: [PATCH 12/16] refactor(typing): Factor out `_LiteralValue` alias This was incomplete as it didn't include `None`, but was serving the same purpose as the generated alias --- altair/vegalite/v5/api.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index 02134b273..65fd46fa3 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -540,10 +540,8 @@ def check_fields_and_encodings(parameter: Parameter, field_name: str) -> bool: ``` """ -_LiteralValue: TypeAlias = Union[str, bool, float, int] -"""Primitive python value types.""" -_FieldEqualType: TypeAlias = Union[_LiteralValue, Map, Parameter, SchemaBase] +_FieldEqualType: TypeAlias = Union[PrimitiveValue_T, Map, Parameter, SchemaBase] """Permitted types for equality checks on field values: - `datum.field == ...` @@ -634,7 +632,7 @@ class _ConditionExtra(TypedDict, closed=True, total=False): # type: ignore[call param: Parameter | str test: _TestPredicateType value: Any - __extra_items__: _StatementType | OneOrSeq[_LiteralValue] + __extra_items__: _StatementType | OneOrSeq[PrimitiveValue_T] _Condition: TypeAlias = _ConditionExtra From 30aa4baa537308ffa7e27effb2bcd386ee9a701e Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:38:23 +0100 Subject: [PATCH 13/16] feat(typing): Accurately type `selection_(interval|point)(value=...)` Added some docs to the new types, since what they describe is somewhat complex References: - https://vega.github.io/vega-lite/docs/selection.html#current-limitations - https://vega.github.io/vega-lite/docs/param-value.html - https://vega.github.io/vega-lite/docs/selection.html#project - https://github.com/vega/altair/blob/5a6f70dc193f7ed9c89e6cc22e95c9d885167939/altair/vegalite/v5/schema/vega-lite-schema.json#L23087-L23118 Resolves: - https://github.com/vega/altair/pull/3653#discussion_r1813473173 - https://github.com/vega/altair/pull/3653#discussion_r1813473660 --- altair/vegalite/v5/api.py | 77 ++++++++++++++++++++++++++++++------ tests/utils/test_schemapi.py | 2 +- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index 65fd46fa3..c8fed1677 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -9,6 +9,7 @@ import sys import typing as t import warnings +from collections.abc import Mapping, Sequence from copy import deepcopy as _deepcopy from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, overload @@ -30,7 +31,7 @@ from .data import data_transformers from .display import VEGA_VERSION, VEGAEMBED_VERSION, VEGALITE_VERSION, renderers from .schema import SCHEMA_URL, channels, core, mixins -from .schema._typing import Map, PrimitiveValue_T +from .schema._typing import Map, PrimitiveValue_T, SingleDefUnitChannel_T, Temporal from .theme import themes if sys.version_info >= (3, 14): @@ -38,16 +39,24 @@ else: from typing_extensions import TypedDict if sys.version_info >= (3, 12): - from typing import Protocol, runtime_checkable + from typing import Protocol, TypeAliasType, runtime_checkable else: - from typing_extensions import Protocol, runtime_checkable # noqa: F401 + from typing_extensions import ( # noqa: F401 + Protocol, + TypeAliasType, + runtime_checkable, + ) +if sys.version_info >= (3, 11): + from typing import LiteralString +else: + from typing_extensions import LiteralString if sys.version_info >= (3, 10): from typing import TypeAlias else: from typing_extensions import TypeAlias if TYPE_CHECKING: - from collections.abc import Iterable, Iterator, Sequence + from collections.abc import Iterable, Iterator from pathlib import Path from typing import IO @@ -85,10 +94,8 @@ ResolveMode_T, SelectionResolution_T, SelectionType_T, - SingleDefUnitChannel_T, SingleTimeUnit_T, StackOffset_T, - Temporal, ) from .schema.channels import Column, Facet, Row from .schema.core import ( @@ -100,6 +107,7 @@ BindRadioSelect, BindRange, BinParams, + DateTime, Expr, ExprRef, FacetedEncoding, @@ -1435,11 +1443,58 @@ def selection(type: Optional[SelectionType_T] = Undefined, **kwds: Any) -> Param return _selection(type=type, **kwds) +_V2 = TypeVar("_V2", bool, float, str, Temporal, "DateTime") +"""Vector2 value type. + +Constrained to non-`None` primitive values or date/datetime: + + bool, float, str, datetime.date, datetime.datetime, alt.DateTime +""" + +_SelectionPointValue: TypeAlias = "PrimitiveValue_T | Temporal | DateTime | Sequence[Mapping[SingleDefUnitChannel_T | LiteralString, PrimitiveValue_T | Temporal | DateTime]]" +""" +Point selections can be initialized with a single primitive value: + + import altair as alt + + alt.selection_point(fields=["year"], value=1980) + + +You can also provide a sequence of mappings between ``encodings`` or ``fields`` to **values**: + + alt.selection_point( + fields=["cylinders", "year"], + value=[{"cylinders": 4, "year": 1981}, {"cylinders": 8, "year": 1972}], + ) +""" + +_SelectionIntervalValueMap = TypeAliasType( + "_SelectionIntervalValueMap", + Mapping[SingleDefUnitChannel_T, "tuple[_V2, _V2] | Sequence[_V2]"], + type_params=(_V2,), +) +""" +Interval selections are initialized with a mapping between ``encodings`` to **values**: + + import altair as alt + + alt.selection_interval( + encodings=["longitude"], + empty=False, + value={"longitude": [-50, -110]}, + ) + +The values specify the **start** and **end** of the interval selection. + +You can use a ``tuple`` for type-checking each sequence has **two** elements: + + alt.selection_interval(value={"x": (55, 160), "y": (13, 37)}) +""" + + def selection_interval( name: str | None = None, - value: Optional[ - PrimitiveValue_T | Temporal | SchemaBase | Sequence[SchemaBase | Map] | Map - ] = Undefined, + value: Optional[_SelectionIntervalValueMap[_V2]] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, expr: Optional[str | Expr | Expression] = Undefined, @@ -1552,9 +1607,7 @@ def selection_interval( def selection_point( name: str | None = None, - value: Optional[ - PrimitiveValue_T | Temporal | SchemaBase | Sequence[SchemaBase | Map] | Map - ] = Undefined, + value: Optional[_SelectionPointValue] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, expr: Optional[Expr] = Undefined, diff --git a/tests/utils/test_schemapi.py b/tests/utils/test_schemapi.py index 5b0e94677..fa5e83aff 100644 --- a/tests/utils/test_schemapi.py +++ b/tests/utils/test_schemapi.py @@ -1094,7 +1094,7 @@ def DateTime( ids=["date", "datetime (no time)", "datetime (microseconds)", "datetime (UTC)"], ) def test_to_dict_datetime( - stocks, window: tuple[Any, Any], expected: tuple[alt.DateTime, alt.DateTime] + stocks, window: tuple[dt.date, dt.date], expected: tuple[alt.DateTime, alt.DateTime] ) -> None: """ Includes `datetime.datetime` with an empty time component. From 8c664208c7817da90621097119ffb80b5471f007 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:24:35 +0100 Subject: [PATCH 14/16] test(typing): Add (failing) `test_selection_interval_value_typing` Need to fix this, but adding this first to demonstrate the issue. Currently the way I've typed it prevents using different types for each encoding. The goal is for each encoding to restrict types independently. E.g. here `x` is **only** `date`, `y` is **only** `float` --- tests/vegalite/v5/test_params.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/vegalite/v5/test_params.py b/tests/vegalite/v5/test_params.py index a5ea3c001..ac94f1074 100644 --- a/tests/vegalite/v5/test_params.py +++ b/tests/vegalite/v5/test_params.py @@ -167,6 +167,24 @@ def test_selection_condition(): assert dct["encoding"]["size"]["value"] == 10 +def test_selection_interval_value_typing() -> None: + import datetime as dt + + window_date = dt.date(2005, 1, 1), dt.date(2009, 1, 1) + window_other = (0, 999) + + a = alt.selection_interval(encodings=["x"], value={"x": window_date}).to_dict() + b = alt.selection_interval(encodings=["y"], value={"y": window_other}).to_dict() + a_b = alt.selection_interval( # type: ignore[type-var] + encodings=["x", "y"], + value={"x": window_date, "y": window_other}, # pyright: ignore[reportArgumentType] + ).to_dict() + + assert a + assert b + assert a_b + + def test_creation_views_params_layered_repeat_chart(): import altair as alt from vega_datasets import data From 901e9b38d7506925a3b8bb7cd16972471db77918 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:55:01 +0100 Subject: [PATCH 15/16] fix(typing): Correct failing `selection_interval` typing https://github.com/vega/altair/pull/3653#discussion_r1814994658 --- altair/vegalite/v5/api.py | 33 ++++++++++++++++++-------------- tests/vegalite/v5/test_params.py | 4 ++-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index c8fed1677..d836615f9 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -1443,14 +1443,6 @@ def selection(type: Optional[SelectionType_T] = Undefined, **kwds: Any) -> Param return _selection(type=type, **kwds) -_V2 = TypeVar("_V2", bool, float, str, Temporal, "DateTime") -"""Vector2 value type. - -Constrained to non-`None` primitive values or date/datetime: - - bool, float, str, datetime.date, datetime.datetime, alt.DateTime -""" - _SelectionPointValue: TypeAlias = "PrimitiveValue_T | Temporal | DateTime | Sequence[Mapping[SingleDefUnitChannel_T | LiteralString, PrimitiveValue_T | Temporal | DateTime]]" """ Point selections can be initialized with a single primitive value: @@ -1468,11 +1460,19 @@ def selection(type: Optional[SelectionType_T] = Undefined, **kwds: Any) -> Param ) """ -_SelectionIntervalValueMap = TypeAliasType( - "_SelectionIntervalValueMap", - Mapping[SingleDefUnitChannel_T, "tuple[_V2, _V2] | Sequence[_V2]"], - type_params=(_V2,), -) +_SelectionIntervalValueMap: TypeAlias = Mapping[ + SingleDefUnitChannel_T, + Union[ + tuple[bool, bool], + tuple[float, float], + tuple[str, str], + tuple["Temporal | DateTime", "Temporal | DateTime"], + Sequence[bool], + Sequence[float], + Sequence[str], + Sequence["Temporal | DateTime"], + ], +] """ Interval selections are initialized with a mapping between ``encodings`` to **values**: @@ -1489,12 +1489,17 @@ def selection(type: Optional[SelectionType_T] = Undefined, **kwds: Any) -> Param You can use a ``tuple`` for type-checking each sequence has **two** elements: alt.selection_interval(value={"x": (55, 160), "y": (13, 37)}) + + +.. note:: + + Unlike :func:`.selection_point()`, the use of ``None`` is not permitted. """ def selection_interval( name: str | None = None, - value: Optional[_SelectionIntervalValueMap[_V2]] = Undefined, + value: Optional[_SelectionIntervalValueMap] = Undefined, bind: Optional[Binding | str] = Undefined, empty: Optional[bool] = Undefined, expr: Optional[str | Expr | Expression] = Undefined, diff --git a/tests/vegalite/v5/test_params.py b/tests/vegalite/v5/test_params.py index ac94f1074..39a5ee8dd 100644 --- a/tests/vegalite/v5/test_params.py +++ b/tests/vegalite/v5/test_params.py @@ -175,9 +175,9 @@ def test_selection_interval_value_typing() -> None: a = alt.selection_interval(encodings=["x"], value={"x": window_date}).to_dict() b = alt.selection_interval(encodings=["y"], value={"y": window_other}).to_dict() - a_b = alt.selection_interval( # type: ignore[type-var] + a_b = alt.selection_interval( encodings=["x", "y"], - value={"x": window_date, "y": window_other}, # pyright: ignore[reportArgumentType] + value={"x": window_date, "y": window_other}, ).to_dict() assert a From 2882d5e9d6b7dc05cf84d49577963909ad70db95 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:14:31 +0100 Subject: [PATCH 16/16] test(typing): Improve coverage for `test_selection_interval_value_typing` --- tests/vegalite/v5/test_params.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/vegalite/v5/test_params.py b/tests/vegalite/v5/test_params.py index 39a5ee8dd..d380586a8 100644 --- a/tests/vegalite/v5/test_params.py +++ b/tests/vegalite/v5/test_params.py @@ -168,21 +168,37 @@ def test_selection_condition(): def test_selection_interval_value_typing() -> None: + """Ensure each encoding restricts types independently.""" import datetime as dt - window_date = dt.date(2005, 1, 1), dt.date(2009, 1, 1) - window_other = (0, 999) + w_date = dt.date(2005, 1, 1), dt.date(2009, 1, 1) + w_float = (0, 999) + w_date_datetime = dt.date(2005, 1, 1), alt.DateTime(year=2009) + w_str = ["0", "500"] + + a = alt.selection_interval(encodings=["x"], value={"x": w_date}).to_dict() + b = alt.selection_interval(encodings=["y"], value={"y": w_float}).to_dict() + c = alt.selection_interval(encodings=["x"], value={"x": w_date_datetime}).to_dict() + d = alt.selection_interval(encodings=["text"], value={"text": w_str}).to_dict() - a = alt.selection_interval(encodings=["x"], value={"x": window_date}).to_dict() - b = alt.selection_interval(encodings=["y"], value={"y": window_other}).to_dict() a_b = alt.selection_interval( - encodings=["x", "y"], - value={"x": window_date, "y": window_other}, + encodings=["x", "y"], value={"x": w_date, "y": w_float} + ).to_dict() + a_c = alt.selection_interval( + encodings=["x", "y"], value={"x": w_date, "y": w_date_datetime} + ).to_dict() + b_c_d = alt.selection_interval( + encodings=["x", "y", "text"], + value={"x": w_date_datetime, "y": w_float, "text": w_str}, ).to_dict() assert a assert b + assert c + assert d assert a_b + assert a_c + assert b_c_d def test_creation_views_params_layered_repeat_chart():