Skip to content

Commit 6d214f9

Browse files
jtillyjakevdpbinstejoelostblom
authored
Backport bug fixes for a 4.2.1 release (#2827)
* DOC: remove unused section * Disable uri-reference format check in jsonsschema (#2771) * Disable uri-reference format check. Consistently use same validator across codebase * Remove validation in SchemaInfo as not used anywhere and it referenced the wrong jsonschema draft * Add compatibility for older jsonschema versions * Improve comments * Simplify validate_jsonschema * Replace `iteritems` with `items` due to pandas deprecation (#2683) * Add changelog entry. * Bump version. * Run black and flake8. * Pin selenium in CI. Co-authored-by: Jake VanderPlas <[email protected]> Co-authored-by: Stefan Binder <[email protected]> Co-authored-by: Joel Ostblom <[email protected]>
1 parent f654bbe commit 6d214f9

File tree

12 files changed

+73
-192
lines changed

12 files changed

+73
-192
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
run: |
2525
python -m pip install --upgrade pip
2626
pip install .[dev]
27+
pip install "selenium<4.3.0"
2728
pip install altair_saver
2829
- name: Test with pytest
2930
run: |

.github/workflows/docbuild.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ jobs:
1919
run: |
2020
python -m pip install --upgrade pip
2121
pip install .[dev]
22+
pip install "selenium<4.3.0"
2223
pip install altair_saver
2324
pip install -r doc/requirements.txt
2425
- name: Run docbuild
2526
run: |
2627
cd doc && make ${{ matrix.build-type }}
27-
28-

altair/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# flake8: noqa
2-
__version__ = "4.2.0"
2+
__version__ = "4.2.1"
33

44
from .vegalite import *
55
from . import examples

altair/utils/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ def to_list_if_array(val):
314314
else:
315315
return val
316316

317-
for col_name, dtype in df.dtypes.iteritems():
317+
for col_name, dtype in df.dtypes.items():
318318
if str(dtype) == "category":
319319
# XXXX: work around bug in to_json for categorical types
320320
# https://github.com/pydata/pandas/issues/10778

altair/utils/display.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
from typing import Callable, Dict
55
import uuid
66

7-
from jsonschema import validate
8-
97
from .plugin_registry import PluginRegistry
108
from .mimebundle import spec_to_mimebundle
9+
from .schemapi import validate_jsonschema
1110

1211

1312
# ==============================================================================
@@ -126,7 +125,7 @@ def _validate(self):
126125
# type: () -> None
127126
"""Validate the spec against the schema."""
128127
schema_dict = json.loads(pkgutil.get_data(*self.schema_path).decode("utf-8"))
129-
validate(self.spec, schema_dict)
128+
validate_jsonschema(self.spec, schema_dict)
130129

131130
def _repr_mimebundle_(self, include=None, exclude=None):
132131
"""Return a MIME bundle for display in Jupyter frontends."""

altair/utils/schemapi.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import json
77

88
import jsonschema
9+
import jsonschema.exceptions
910
import numpy as np
1011
import pandas as pd
1112

12-
13+
JSONSCHEMA_VALIDATOR = jsonschema.Draft7Validator
1314
# If DEBUG_MODE is True, then schema objects are converted to dict and
1415
# validated at creation time. This slows things down, particularly for
1516
# larger specs, but leads to much more useful tracebacks for the user.
@@ -39,6 +40,24 @@ def debug_mode(arg):
3940
DEBUG_MODE = original
4041

4142

43+
def validate_jsonschema(spec, schema, resolver=None):
44+
# We don't use jsonschema.validate as this would validate the schema itself.
45+
# Instead, we pass the schema directly to the validator class. This is done for
46+
# two reasons: The schema comes from Vega-Lite and is not based on the user
47+
# input, therefore there is no need to validate it in the first place. Furthermore,
48+
# the "uri-reference" format checker fails for some of the references as URIs in
49+
# "$ref" are not encoded,
50+
# e.g. '#/definitions/ValueDefWithCondition<MarkPropFieldOrDatumDef,
51+
# (Gradient|string|null)>' would be a valid $ref in a Vega-Lite schema but
52+
# it is not a valid URI reference due to the characters such as '<'.
53+
validator = JSONSCHEMA_VALIDATOR(
54+
schema, format_checker=JSONSCHEMA_VALIDATOR.FORMAT_CHECKER, resolver=resolver
55+
)
56+
error = jsonschema.exceptions.best_match(validator.iter_errors(spec))
57+
if error is not None:
58+
raise error
59+
60+
4261
def _subclasses(cls):
4362
"""Breadth-first sequence of all classes which inherit from cls."""
4463
seen = set()
@@ -150,7 +169,7 @@ class SchemaBase(object):
150169
_schema = None
151170
_rootschema = None
152171
_class_is_valid_at_instantiation = True
153-
_validator = jsonschema.Draft7Validator
172+
_validator = JSONSCHEMA_VALIDATOR
154173

155174
def __init__(self, *args, **kwds):
156175
# Two valid options for initialization, which should be handled by
@@ -440,9 +459,7 @@ def validate(cls, instance, schema=None):
440459
if schema is None:
441460
schema = cls._schema
442461
resolver = jsonschema.RefResolver.from_schema(cls._rootschema or cls._schema)
443-
return jsonschema.validate(
444-
instance, schema, cls=cls._validator, resolver=resolver
445-
)
462+
return validate_jsonschema(instance, schema, resolver=resolver)
446463

447464
@classmethod
448465
def resolve_references(cls, schema=None):
@@ -461,7 +478,7 @@ def validate_property(cls, name, value, schema=None):
461478
value = _todict(value, validate=False, context={})
462479
props = cls.resolve_references(schema or cls._schema).get("properties", {})
463480
resolver = jsonschema.RefResolver.from_schema(cls._rootschema or cls._schema)
464-
return jsonschema.validate(value, props.get(name, {}), resolver=resolver)
481+
return validate_jsonschema(value, props.get(name, {}), resolver=resolver)
465482

466483
def __dir__(self):
467484
return list(self._kwds.keys())
@@ -555,7 +572,7 @@ def from_dict(
555572
for possible_schema in schemas:
556573
resolver = jsonschema.RefResolver.from_schema(rootschema)
557574
try:
558-
jsonschema.validate(dct, possible_schema, resolver=resolver)
575+
validate_jsonschema(dct, possible_schema, resolver=resolver)
559576
except jsonschema.ValidationError:
560577
continue
561578
else:

altair/utils/tests/test_plugin_registry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_plugin_registry():
2626
assert plugins.get() is None
2727
assert repr(plugins) == "TypedCallableRegistry(active='', registered=[])"
2828

29-
plugins.register("new_plugin", lambda x: x ** 2)
29+
plugins.register("new_plugin", lambda x: x**2)
3030
assert plugins.names() == ["new_plugin"]
3131
assert plugins.active == ""
3232
assert plugins.get() is None
@@ -46,7 +46,7 @@ def test_plugin_registry():
4646
def test_plugin_registry_extra_options():
4747
plugins = GeneralCallableRegistry()
4848

49-
plugins.register("metadata_plugin", lambda x, p=2: x ** p)
49+
plugins.register("metadata_plugin", lambda x, p=2: x**p)
5050
plugins.enable("metadata_plugin")
5151
assert plugins.get()(3) == 9
5252

@@ -86,7 +86,7 @@ def test_plugin_registry_global_settings():
8686
def test_plugin_registry_context():
8787
plugins = GeneralCallableRegistry()
8888

89-
plugins.register("default", lambda x, p=2: x ** p)
89+
plugins.register("default", lambda x, p=2: x**p)
9090

9191
# At first there is no plugin enabled
9292
assert plugins.active == ""

altair/utils/tests/test_utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ def test_sanitize_nullable_integers():
129129
)
130130

131131
df_clean = sanitize_dataframe(df)
132-
assert {col.dtype.name for _, col in df_clean.iteritems()} == {"object"}
132+
assert {col.dtype.name for _, col in df_clean.items()} == {"object"}
133133

134-
result_python = {col_name: list(col) for col_name, col in df_clean.iteritems()}
134+
result_python = {col_name: list(col) for col_name, col in df_clean.items()}
135135
assert result_python == {
136136
"int_np": [1, 2, 3, 4, 5],
137137
"int64": [1, 2, 3, None, 5],
@@ -157,9 +157,9 @@ def test_sanitize_string_dtype():
157157
)
158158

159159
df_clean = sanitize_dataframe(df)
160-
assert {col.dtype.name for _, col in df_clean.iteritems()} == {"object"}
160+
assert {col.dtype.name for _, col in df_clean.items()} == {"object"}
161161

162-
result_python = {col_name: list(col) for col_name, col in df_clean.iteritems()}
162+
result_python = {col_name: list(col) for col_name, col in df_clean.items()}
163163
assert result_python == {
164164
"string_object": ["a", "b", "c", "d"],
165165
"string_string": ["a", "b", "c", "d"],
@@ -182,9 +182,9 @@ def test_sanitize_boolean_dtype():
182182
)
183183

184184
df_clean = sanitize_dataframe(df)
185-
assert {col.dtype.name for _, col in df_clean.iteritems()} == {"object"}
185+
assert {col.dtype.name for _, col in df_clean.items()} == {"object"}
186186

187-
result_python = {col_name: list(col) for col_name, col in df_clean.iteritems()}
187+
result_python = {col_name: list(col) for col_name, col in df_clean.items()}
188188
assert result_python == {
189189
"bool_none": [True, False, None],
190190
"none": [None, None, None],

doc/releases/changes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
Altair Change Log
44
=================
55

6+
Version 4.2.1 (released XXX XX, 2023)
7+
-------------------------------------
8+
9+
Bug Fixes
10+
~~~~~~~~~
11+
- Disable uri-reference format check in jsonsschema (#2771)
12+
- Replace ``iteritems`` with ```items``` due to pandas deprecation (#2683)
13+
14+
615
Version 4.2.0 (released Dec 29, 2021)
716
-------------------------------------
817
- Update Vega-Lite from version 4.8.1 to version 4.17.0;

tools/schemapi/jsonschema-draft04.json

Lines changed: 0 additions & 149 deletions
This file was deleted.

0 commit comments

Comments
 (0)