Skip to content

Commit

Permalink
ENH: add method-based attribute setting to encoding classes
Browse files Browse the repository at this point in the history
  • Loading branch information
jakevdp committed Jul 26, 2019
1 parent 37cf5a8 commit f1906ca
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 8 deletions.
26 changes: 25 additions & 1 deletion altair/utils/schemapi.py
Expand Up @@ -108,7 +108,6 @@ def __str__(self):
return six.text_type(self).encode("utf-8")



class UndefinedType(object):
"""A singleton object for marking undefined attributes"""
__instance = None
Expand Down Expand Up @@ -528,3 +527,28 @@ def _passthrough(*args, **kwds):
return cls(dct)
else:
return cls(dct)


class _PropertySetter(object):
def __init__(self, prop, schema):
self.prop = prop
self.schema = schema

def __get__(self, obj, cls):
self.obj = obj
self.cls = cls
return self

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


def with_property_setters(cls):
"""Decorator to add property setters to a Schema class."""
schema = cls.resolve_references()
for prop, propschema in schema.get('properties', {}).items():
setattr(cls, prop, _PropertySetter(prop, propschema))
return cls
40 changes: 38 additions & 2 deletions altair/vegalite/v2/schema/channels.py
Expand Up @@ -6,7 +6,7 @@
import six
from . import core
import pandas as pd
from altair.utils.schemapi import Undefined
from altair.utils.schemapi import Undefined, with_property_setters
from altair.utils import parse_shorthand


Expand Down Expand Up @@ -67,7 +67,7 @@ def to_dict(self, validate=True, ignore=(), context=None):
class ValueChannelMixin(object):
def to_dict(self, validate=True, ignore=(), context=None):
context = context or {}
condition = getattr(self, 'condition', Undefined)
condition = self._get('condition')
copy = self # don't copy unless we need to
if condition is not Undefined:
if isinstance(condition, core.SchemaBase):
Expand All @@ -81,6 +81,7 @@ def to_dict(self, validate=True, ignore=(), context=None):
context=context)


@with_property_setters
class Color(FieldChannelMixin, core.MarkPropFieldDefWithCondition):
"""Color schema wrapper
Expand Down Expand Up @@ -209,6 +210,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class ColorValue(ValueChannelMixin, core.MarkPropValueDefWithCondition):
"""ColorValue schema wrapper
Expand All @@ -231,6 +233,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(ColorValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Column(FieldChannelMixin, core.FacetFieldDef):
"""Column schema wrapper
Expand Down Expand Up @@ -338,6 +341,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
type=type, **kwds)


@with_property_setters
class Detail(FieldChannelMixin, core.FieldDef):
"""Detail schema wrapper
Expand Down Expand Up @@ -416,6 +420,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Fill(FieldChannelMixin, core.MarkPropFieldDefWithCondition):
"""Fill schema wrapper
Expand Down Expand Up @@ -544,6 +549,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class FillValue(ValueChannelMixin, core.MarkPropValueDefWithCondition):
"""FillValue schema wrapper
Expand All @@ -566,6 +572,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(FillValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Href(FieldChannelMixin, core.FieldDefWithCondition):
"""Href schema wrapper
Expand Down Expand Up @@ -651,6 +658,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
type=type, **kwds)


@with_property_setters
class HrefValue(ValueChannelMixin, core.ValueDefWithCondition):
"""HrefValue schema wrapper
Expand All @@ -673,6 +681,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(HrefValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Key(FieldChannelMixin, core.FieldDef):
"""Key schema wrapper
Expand Down Expand Up @@ -751,6 +760,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Latitude(FieldChannelMixin, core.FieldDef):
"""Latitude schema wrapper
Expand Down Expand Up @@ -829,6 +839,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Latitude2(FieldChannelMixin, core.FieldDef):
"""Latitude2 schema wrapper
Expand Down Expand Up @@ -907,6 +918,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Longitude(FieldChannelMixin, core.FieldDef):
"""Longitude schema wrapper
Expand Down Expand Up @@ -985,6 +997,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Longitude2(FieldChannelMixin, core.FieldDef):
"""Longitude2 schema wrapper
Expand Down Expand Up @@ -1063,6 +1076,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Opacity(FieldChannelMixin, core.MarkPropFieldDefWithCondition):
"""Opacity schema wrapper
Expand Down Expand Up @@ -1191,6 +1205,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class OpacityValue(ValueChannelMixin, core.MarkPropValueDefWithCondition):
"""OpacityValue schema wrapper
Expand All @@ -1213,6 +1228,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(OpacityValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Order(FieldChannelMixin, core.OrderFieldDef):
"""Order schema wrapper
Expand Down Expand Up @@ -1292,6 +1308,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class OrderValue(ValueChannelMixin, core.ValueDef):
"""OrderValue schema wrapper
Expand All @@ -1312,6 +1329,7 @@ def __init__(self, value, **kwds):
super(OrderValue, self).__init__(value=value, **kwds)


@with_property_setters
class Row(FieldChannelMixin, core.FacetFieldDef):
"""Row schema wrapper
Expand Down Expand Up @@ -1419,6 +1437,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
**kwds)


@with_property_setters
class Shape(FieldChannelMixin, core.MarkPropFieldDefWithCondition):
"""Shape schema wrapper
Expand Down Expand Up @@ -1547,6 +1566,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class ShapeValue(ValueChannelMixin, core.MarkPropValueDefWithCondition):
"""ShapeValue schema wrapper
Expand All @@ -1569,6 +1589,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(ShapeValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Size(FieldChannelMixin, core.MarkPropFieldDefWithCondition):
"""Size schema wrapper
Expand Down Expand Up @@ -1697,6 +1718,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class SizeValue(ValueChannelMixin, core.MarkPropValueDefWithCondition):
"""SizeValue schema wrapper
Expand All @@ -1719,6 +1741,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(SizeValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Stroke(FieldChannelMixin, core.MarkPropFieldDefWithCondition):
"""Stroke schema wrapper
Expand Down Expand Up @@ -1847,6 +1870,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
sort=sort, timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class StrokeValue(ValueChannelMixin, core.MarkPropValueDefWithCondition):
"""StrokeValue schema wrapper
Expand All @@ -1869,6 +1893,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(StrokeValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Text(FieldChannelMixin, core.TextFieldDefWithCondition):
"""Text schema wrapper
Expand Down Expand Up @@ -1958,6 +1983,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
title=title, type=type, **kwds)


@with_property_setters
class TextValue(ValueChannelMixin, core.TextValueDefWithCondition):
"""TextValue schema wrapper
Expand All @@ -1980,6 +2006,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(TextValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class Tooltip(FieldChannelMixin, core.TextFieldDefWithCondition):
"""Tooltip schema wrapper
Expand Down Expand Up @@ -2069,6 +2096,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, cond
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class TooltipValue(ValueChannelMixin, core.TextValueDefWithCondition):
"""TooltipValue schema wrapper
Expand All @@ -2091,6 +2119,7 @@ def __init__(self, value, condition=Undefined, **kwds):
super(TooltipValue, self).__init__(value=value, condition=condition, **kwds)


@with_property_setters
class X(FieldChannelMixin, core.PositionFieldDef):
"""X schema wrapper
Expand Down Expand Up @@ -2239,6 +2268,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, axis=Undefined, bin
title=title, type=type, **kwds)


@with_property_setters
class XValue(ValueChannelMixin, core.ValueDef):
"""XValue schema wrapper
Expand All @@ -2259,6 +2289,7 @@ def __init__(self, value, **kwds):
super(XValue, self).__init__(value=value, **kwds)


@with_property_setters
class X2(FieldChannelMixin, core.FieldDef):
"""X2 schema wrapper
Expand Down Expand Up @@ -2337,6 +2368,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class X2Value(ValueChannelMixin, core.ValueDef):
"""X2Value schema wrapper
Expand All @@ -2357,6 +2389,7 @@ def __init__(self, value, **kwds):
super(X2Value, self).__init__(value=value, **kwds)


@with_property_setters
class Y(FieldChannelMixin, core.PositionFieldDef):
"""Y schema wrapper
Expand Down Expand Up @@ -2505,6 +2538,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, axis=Undefined, bin
title=title, type=type, **kwds)


@with_property_setters
class YValue(ValueChannelMixin, core.ValueDef):
"""YValue schema wrapper
Expand All @@ -2525,6 +2559,7 @@ def __init__(self, value, **kwds):
super(YValue, self).__init__(value=value, **kwds)


@with_property_setters
class Y2(FieldChannelMixin, core.FieldDef):
"""Y2 schema wrapper
Expand Down Expand Up @@ -2603,6 +2638,7 @@ def __init__(self, shorthand=Undefined, aggregate=Undefined, bin=Undefined, fiel
timeUnit=timeUnit, title=title, type=type, **kwds)


@with_property_setters
class Y2Value(ValueChannelMixin, core.ValueDef):
"""Y2Value schema wrapper
Expand Down

0 comments on commit f1906ca

Please sign in to comment.