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

Internal: add inheritance structure to core classes #1803

Merged
merged 3 commits into from
Nov 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions altair/utils/schemapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ def debug_mode(arg):
DEBUG_MODE = original


def _subclasses(cls):
"""Breadth-first sequence of all classes which inherit from cls."""
seen = set()
current_set = {cls}
while current_set:
seen |= current_set
current_set = set.union(*(set(cls.__subclasses__()) for cls in current_set))
for cls in current_set - seen:
yield cls


def _todict(obj, validate, context):
"""Convert an object to a dict representation."""
if isinstance(obj, SchemaBase):
Expand Down Expand Up @@ -337,7 +348,7 @@ def to_json(self, validate=True, ignore=[], context={},
@classmethod
def _default_wrapper_classes(cls):
"""Return the set of classes used within cls.from_dict()"""
return SchemaBase.__subclasses__()
return _subclasses(SchemaBase)

@classmethod
def from_dict(cls, dct, validate=True, _wrapper_classes=None):
Expand Down Expand Up @@ -487,7 +498,9 @@ def _passthrough(*args, **kwds):
return args[0] if args else kwds

if cls is None:
# TODO: do something more than simply selecting the last match?
# If there are multiple matches, we use the last one in the dict.
# Our class dict is constructed breadth-first from top to bottom,
# so the last class that matches is the most specific.
matches = self.class_dict[self.hash_schema(schema)]
cls = matches[-1] if matches else _passthrough
schema = _resolve_references(schema, rootschema)
Expand Down
4 changes: 2 additions & 2 deletions altair/vega/v4/schema/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# The contents of this file are automatically written by
# tools/generate_schema_wrapper.py. Do not modify directly.

from altair.utils.schemapi import SchemaBase, Undefined
from altair.utils.schemapi import SchemaBase, Undefined, _subclasses

import pkgutil
import json
Expand All @@ -16,7 +16,7 @@ def load_schema():
class VegaSchema(SchemaBase):
@classmethod
def _default_wrapper_classes(cls):
return VegaSchema.__subclasses__()
return _subclasses(VegaSchema)


class Root(VegaSchema):
Expand Down
4 changes: 2 additions & 2 deletions altair/vega/v5/schema/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# The contents of this file are automatically written by
# tools/generate_schema_wrapper.py. Do not modify directly.

from altair.utils.schemapi import SchemaBase, Undefined
from altair.utils.schemapi import SchemaBase, Undefined, _subclasses

import pkgutil
import json
Expand All @@ -16,7 +16,7 @@ def load_schema():
class VegaSchema(SchemaBase):
@classmethod
def _default_wrapper_classes(cls):
return VegaSchema.__subclasses__()
return _subclasses(VegaSchema)


class Root(VegaSchema):
Expand Down
20 changes: 5 additions & 15 deletions altair/vegalite/v2/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ def _prepare_data(data, context):
data = _consolidate_data(data, context)

# if data is still not a recognized type, then return
if not isinstance(data, (dict, core.Data, core.UrlData,
core.InlineData, core.NamedData)):
if not isinstance(data, (dict, core.Data)):
warnings.warn("data of type {} not recognized".format(type(data)))

return data
Expand Down Expand Up @@ -329,19 +328,12 @@ def condition(predicate, if_true, if_false, **kwargs):
spec: dict or VegaLiteSchema
the spec that describes the condition
"""
selection_predicates = (core.SelectionNot, core.SelectionOr,
core.SelectionAnd, core.SelectionOperand)
test_predicates = (six.string_types, expr.Expression, core.Predicate,
core.LogicalOperandPredicate, core.LogicalNotPredicate,
core.LogicalOrPredicate, core.LogicalAndPredicate,
core.FieldEqualPredicate, core.FieldOneOfPredicate,
core.FieldRangePredicate, core.FieldLTPredicate,
core.FieldGTPredicate, core.FieldLTEPredicate,
core.FieldGTEPredicate, core.SelectionPredicate)
test_predicates = (six.string_types, expr.Expression,
core.LogicalOperandPredicate)

if isinstance(predicate, NamedSelection):
condition = {'selection': predicate._get_name()}
elif isinstance(predicate, selection_predicates):
elif isinstance(predicate, core.SelectionOperand):
condition = {'selection': predicate}
elif isinstance(predicate, test_predicates):
condition = {'test': predicate}
Expand Down Expand Up @@ -872,11 +864,9 @@ def transform_filter(self, filter, **kwargs):
alt.FilterTransform : underlying transform object

"""
selection_predicates = (core.SelectionNot, core.SelectionOr,
core.SelectionAnd, core.SelectionOperand)
if isinstance(filter, NamedSelection):
filter = {'selection': filter._get_name()}
elif isinstance(filter, selection_predicates):
elif isinstance(filter, core.SelectionOperand):
filter = {'selection': filter}
return self._add_transform(core.FilterTransform(filter=filter, **kwargs))

Expand Down
Loading