Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

_PropertySetter silently ignores multiple positional arguments #3661

Open
dangotbanned opened this issue Oct 29, 2024 · 0 comments
Open

_PropertySetter silently ignores multiple positional arguments #3661

dangotbanned opened this issue Oct 29, 2024 · 0 comments
Labels

Comments

@dangotbanned
Copy link
Member

dangotbanned commented Oct 29, 2024

Adapted from #3659 (comment)

What happened?

Minimal Repro

These are all valid:

import altair as alt

valid_scale = alt.Scale(domain=["M", "F"], range=["#1FC3AA", "#8624F5"])

valid_color_1 = alt.Color().scale(valid_scale)
valid_color_2 = alt.Color().scale(domain=["M", "F"], range=["#1FC3AA", "#8624F5"])

Both of these cases naively just ignore everything after the first argument:

alt.Color().scale(["M", "F"], ["#1FC3AA", "#8624F5"])
# Color({
#  scale: ['M', 'F']
#})

alt.Color().scale(valid_scale, valid_scale, valid_scale)
# Color({
#   scale: Scale({
#     domain: ['M', 'F'],
#     range: ['#1FC3AA', '#8624F5']
#   })
# })

Expected

Behavior similar the wrapped class:

invalid_scale = alt.Scale(["M", "F"], ["#1FC3AA", "#8624F5"])
SchemaValidationError: Multiple errors were found.

Error 1: '['M', 'F']' is an invalid value for `align`. Valid values are of type 'number' or 'object'.

Error 2: '['#1FC3AA', '#8624F5']' is an invalid value for `base`. Valid values are of type 'number' or 'object'.

Cause

_PropertySetter.__call__ doesn't align with SchemaBase.__init__:

def __call__(self, *args: Any, **kwargs: Any):
obj = self.obj.copy()
# TODO: use schema to validate
obj[self.prop] = args[0] if args else kwargs
return obj

Above, we silently drop any positional args after the first (see recording)

Below, we raise an AssertionError if there is more than 1 positional argument

def __init__(self, *args: Any, **kwds: Any) -> None:
# Two valid options for initialization, which should be handled by
# derived classes:
# - a single arg with no kwds, for, e.g. {'type': 'string'}
# - zero args with zero or more kwds for {'type': 'object'}
if self._schema is None:
msg = (
f"Cannot instantiate object of type {self.__class__}: "
"_schema class attribute is not defined."
""
)
raise ValueError(msg)
if kwds:
assert len(args) == 0
else:
assert len(args) in {0, 1}
# use object.__setattr__ because we override setattr below.
object.__setattr__(self, "_args", args)
object.__setattr__(self, "_kwds", kwds)

Note

Appears to have been present in all 5.* versions

What would you like to happen instead?

I think we should raise for all cases that look like this:

alt.ChannelsClass().property_setter(arg1, arg...)

Which version of Altair are you using?

5.5.0dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant