Skip to content

Commit

Permalink
Merge pull request #256 from bollwyvl/gh-255-jsonschema-compat
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 committed Mar 31, 2022
2 parents df63593 + ded36a5 commit 4b5bfad
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 33 deletions.
28 changes: 20 additions & 8 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,41 @@ jobs:
name: ${{ matrix.OS }} - Py${{ matrix.PYTHON_VERSION }}
runs-on: ${{ matrix.OS }}
strategy:
fail-fast: false
fail-fast: false
matrix:
OS: ['ubuntu-latest', 'windows-latest']
PYTHON_VERSION: ['3.7', '3.8', '3.9', '3.10']
OS: ['ubuntu-latest', 'windows-latest', 'macos-latest']
PYTHON_VERSION: ['3.7', '3.10', 'pypy-3.8']
include:
- PYTHON_VERSION: '3.7'
EXTRA_DEPS: '"jsonschema<2.7"'
- PYTHON_VERSION: '3.10'
EXTRA_DEPS: ''
- PYTHON_VERSION: 'pypy-3.8'
EXTRA_DEPS: '"jsonschema<4"'
exclude:
- PYTHON_VERSION: 'pypy-3.8'
OS: 'windows-latest'
- PYTHON_VERSION: 'pypy-3.8'
OS: 'macos-latest'
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.PYTHON_VERSION }}
- name: Install test dependencies
run: |
pip install --upgrade pip setuptools
pip install --upgrade pip setuptools wheel
pip install .[test]
pip install codecov pytest-cov
- name: Install nbformat
run: |
pip install .
pip install . ${{ matrix.EXTRA_DEPS }}
pip freeze
- name: List dependencies
run: pip list
- name: Run tests
run: pytest -v --cov=nbformat
run: pytest -v --cov=nbformat --cov-report term-missing:skip-covered --no-cov-on-fail
- name: Check manfest
run: check-manifest -v
- name: Coverage
Expand Down
11 changes: 5 additions & 6 deletions nbformat/corpus/tests/test_words.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
from .. import words


def test_generate_corpus_id():
with pytest.warns(None) as record:
assert len(words.generate_corpus_id()) > 7
# 1 in 4294967296 (2^32) times this will fail
assert words.generate_corpus_id() != words.generate_corpus_id()
assert len(record) == 0
def test_generate_corpus_id(recwarn):
assert len(words.generate_corpus_id()) > 7
# 1 in 4294967296 (2^32) times this will fail
assert words.generate_corpus_id() != words.generate_corpus_id()
assert len(recwarn) == 0
11 changes: 5 additions & 6 deletions nbformat/current.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import re
import warnings

warnings.warn("""nbformat.current is deprecated.
warnings.warning("""nbformat.current is deprecated.
- use nbformat for read/write/validate public API
- use nbformat.vX directly to composing notebooks of a particular version
Expand Down Expand Up @@ -50,15 +50,15 @@ class NBFormatError(ValueError):


def _warn_format():
warnings.warn("""Non-JSON file support in nbformat is deprecated.
warnings.warning("""Non-JSON file support in nbformat is deprecated.
Use nbconvert to create files of other formats.""")


def parse_py(s, **kwargs):
"""Parse a string into a (nbformat, string) tuple."""
nbf = current_nbformat
nbm = current_nbformat_minor

pattern = r'# <nbformat>(?P<nbformat>\d+[\.\d+]*)</nbformat>'
m = re.search(pattern,s)
if m is not None:
Expand All @@ -72,12 +72,12 @@ def parse_py(s, **kwargs):

def reads_json(nbjson, **kwargs):
"""DEPRECATED, use reads"""
warnings.warn("reads_json is deprecated, use reads")
warnings.warning("reads_json is deprecated, use reads")
return reads(nbjson)

def writes_json(nb, **kwargs):
"""DEPRECATED, use writes"""
warnings.warn("writes_json is deprecated, use writes")
warnings.warning("writes_json is deprecated, use writes")
return writes(nb, **kwargs)

def reads_py(s, **kwargs):
Expand Down Expand Up @@ -189,4 +189,3 @@ def write(nb, fp, format='DEPRECATED', **kwargs):
if isinstance(s, bytes):
s = s.decode('utf8')
return fp.write(s)

9 changes: 7 additions & 2 deletions nbformat/json_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
_JsonSchemaException = ValidationError



class JsonSchemaValidator:
name = "jsonschema"

Expand All @@ -32,10 +33,14 @@ def validate(self, data):
self._default_validator.validate(data)

def iter_errors(self, data, schema=None):
if schema is None:
return self._default_validator.iter_errors(data)
if hasattr(self._default_validator, "evolve"):
return self._default_validator.evolve(schema=schema).iter_errors(data)
return self._default_validator.iter_errors(data, schema)

def error_tree(self, errors):
return ErrorTree(errors)
return ErrorTree(errors=errors)


class FastJsonSchemaValidator(JsonSchemaValidator):
Expand All @@ -53,7 +58,7 @@ def validate(self, data):

def iter_errors(self, data, schema=None):
if schema is not None:
return self._default_validator.iter_errors(data, schema)
return super().iter_errors(data, schema)

errors = []
validate_func = self._validator
Expand Down
1 change: 0 additions & 1 deletion nbformat/v3/nbbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,3 @@ def new_author(name=None, email=None, affiliation=None, url=None):
if url is not None:
author.url = str_passthrough(url)
return author

7 changes: 6 additions & 1 deletion nbformat/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,12 @@ def validate(nbdict=None, ref=None, version=None, version_minor=None,
if repair_duplicate_cell_ids:
# Best effort to repair if we find a duplicate id
cell['id'] = generate_corpus_id()
get_logger().warn("Non-unique cell id '{}' detected. Corrected to '{}'.".format(cell_id, cell['id']))
get_logger().warning(
"Non-unique cell id '{}' detected. Corrected to '{}'.".format(
cell_id,
cell['id']
)
)
else:
raise ValidationError("Non-unique cell id '{}' detected.".format(cell_id))
seen_ids.add(cell_id)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
setuptools_args = {}
install_requires = setuptools_args['install_requires'] = [
'traitlets>=4.1',
'jsonschema>=2.4,!=2.5.0',
'jsonschema>=2.6',
'jupyter_core',
]

Expand Down
4 changes: 3 additions & 1 deletion tests/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def test_invalid_validator_raises_value_error_after_read():
validate(nb)


def test_fallback_validator_with_iter_errors_using_ref():
def test_fallback_validator_with_iter_errors_using_ref(recwarn):
"""
Test that when creating a standalone object (code_cell etc)
the default validator is used as fallback.
Expand All @@ -211,6 +211,8 @@ def test_fallback_validator_with_iter_errors_using_ref():
nbformat.v4.new_code_cell()
nbformat.v4.new_markdown_cell()
nbformat.v4.new_raw_cell()
assert len(recwarn) == 0



def test_non_unique_cell_ids():
Expand Down
18 changes: 11 additions & 7 deletions tests/v3/test_nbbase.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from unittest import TestCase

import pytest

from nbformat.v3.nbbase import (
NotebookNode,
new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
Expand Down Expand Up @@ -134,17 +136,19 @@ def test_metadata(self):

class TestOutputs(TestCase):
def test_binary_png(self):
out = new_output(output_png=b'\x89PNG\r\n\x1a\n', output_type='display_data')
with pytest.warns(UserWarning, match='bytes instead of likely base64'):
out = new_output(output_png=b'\x89PNG\r\n\x1a\n', output_type='display_data')

def test_b64b6tes_png(self):
# really those tests are wrong, this is not b64, if prefixed by b
out = new_output(output_png=b'iVBORw0KG', output_type='display_data')

with pytest.warns(UserWarning, match='bytes instead of likely base64'):
out = new_output(output_png=b'iVBORw0KG', output_type='display_data')

def test_binary_jpeg(self):
out = new_output(output_jpeg=b'\xff\xd8', output_type='display_data')
with pytest.warns(UserWarning, match='bytes instead of likely base64'):
out = new_output(output_jpeg=b'\xff\xd8', output_type='display_data')

def test_b64b6tes_jpeg(self):
# really those tests are wrong, this is not b64, if prefixed by b
out = new_output(output_jpeg=b'/9', output_type='display_data')


with pytest.warns(UserWarning, match='bytes instead of likely base64'):
out = new_output(output_jpeg=b'/9', output_type='display_data')

0 comments on commit 4b5bfad

Please sign in to comment.