Skip to content

Commit

Permalink
Merge branch 'main' into predicate-composition-dunder
Browse files Browse the repository at this point in the history
  • Loading branch information
dangotbanned authored Nov 3, 2024
2 parents dba2b3e + c28dbb9 commit 05de66d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
7 changes: 5 additions & 2 deletions altair/utils/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,14 @@ def infer_vegalite_type_for_narwhals(
and not (categories := column.cat.get_categories()).is_empty()
):
return "ordinal", categories.to_list()
if dtype in {nw.String, nw.Categorical, nw.Boolean}:
if dtype == nw.String or dtype == nw.Categorical or dtype == nw.Boolean: # noqa: PLR1714
return "nominal"
elif dtype.is_numeric():
return "quantitative"
elif dtype in {nw.Datetime, nw.Date}:
elif dtype == nw.Datetime or dtype == nw.Date: # noqa: PLR1714
# We use `== nw.Datetime` to check for any kind of Datetime, regardless of time
# unit and time zone. Prefer this over `dtype in {nw.Datetime, nw.Date}`,
# see https://narwhals-dev.github.io/narwhals/backcompat.
return "temporal"
else:
msg = f"Unexpected DtypeKind: {dtype}"
Expand Down
48 changes: 44 additions & 4 deletions altair/vegalite/v5/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
AnyMark,
BindCheckbox,
Binding,
BindInput,
BindRadioSelect,
BindRange,
BinParams,
Expand Down Expand Up @@ -1743,10 +1744,49 @@ def selection_single(**kwargs: Any) -> Parameter:
return _selection(type="point", **kwargs)


@utils.use_signature(core.Binding)
def binding(input: Any, **kwargs: Any) -> Binding:
"""A generic binding."""
return core.Binding(input=input, **kwargs)
def binding(
input: str,
*,
autocomplete: Optional[str] = Undefined,
debounce: Optional[float] = Undefined,
element: Optional[str] = Undefined,
name: Optional[str] = Undefined,
placeholder: Optional[str] = Undefined,
) -> BindInput:
"""
A generic binding.
Parameters
----------
input : str
The type of input element to use. The valid values are ``"checkbox"``, ``"radio"``,
``"range"``, ``"select"``, and any other legal `HTML form input type
<https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>`__.
autocomplete : str
A hint for form autofill. See the `HTML autocomplete attribute
<https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete>`__ for
additional information.
debounce : float
If defined, delays event handling until the specified milliseconds have elapsed
since the last event was fired.
element : str
An optional CSS selector string indicating the parent element to which the input
element should be added. By default, all input elements are added within the parent
container of the Vega view.
name : str
By default, the signal name is used to label input elements. This ``name`` property
can be used instead to specify a custom label for the bound signal.
placeholder : str
Text that appears in the form control when it has no value set.
"""
return core.BindInput(
autocomplete=autocomplete,
debounce=debounce,
element=element,
input=input,
name=name,
placeholder=placeholder,
)


@utils.use_signature(core.BindCheckbox)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_transformed_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import altair as alt
from altair.utils.execeval import eval_block
from tests import examples_methods_syntax, slow, ignore_DataFrameGroupBy
import narwhals as nw
import narwhals.stable.v1 as nw

try:
import vegafusion as vf
Expand Down
37 changes: 37 additions & 0 deletions tests/vegalite/v5/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@
from packaging.version import Version

import altair as alt
from altair.utils.core import use_signature
from altair.utils.schemapi import Optional, SchemaValidationError, Undefined
from tests import skip_requires_vl_convert, slow

if TYPE_CHECKING:
from typing import Any

from altair.vegalite.v5.api import _Conditional, _Conditions
from altair.vegalite.v5.schema._typing import Map

Expand Down Expand Up @@ -1709,3 +1712,37 @@ def test_ibis_with_vegafusion(monkeypatch: pytest.MonkeyPatch):
{"a": 2, "b": "2020-01-02T00:00:00.000"},
{"a": 3, "b": "2020-01-03T00:00:00.000"},
]


def test_binding() -> None:
@use_signature(alt.Binding)
def old_binding(input: Any, **kwargs: Any) -> alt.Binding:
"""A generic binding."""
return alt.Binding(input=input, **kwargs)

# NOTE: `mypy` doesn't complain, but `pyright` does
old = old_binding(input="search", placeholder="Country", name="Search") # pyright: ignore[reportCallIssue]
old_positional = old_binding("search", placeholder="Country", name="Search")

new = alt.binding(input="search", placeholder="Country", name="Search")
new_positional = alt.binding("search", placeholder="Country", name="Search")

assert (
old.to_dict()
== old_positional.to_dict()
== new.to_dict()
== new_positional.to_dict()
)
assert all(
isinstance(x, alt.Binding) for x in (old, old_positional, new, new_positional)
)

MISSING_INPUT = r"missing 1 required positional argument: 'input"

# NOTE: `mypy` doesn't complain, but `pyright` does (Again)
with pytest.raises(TypeError, match=MISSING_INPUT):
old_binding(placeholder="Country", name="Search") # pyright: ignore[reportCallIssue]

# NOTE: Both type checkers can detect the issue on the new signature
with pytest.raises(TypeError, match=MISSING_INPUT):
alt.binding(placeholder="Country", name="Search") # type: ignore[call-arg]

0 comments on commit 05de66d

Please sign in to comment.