Skip to content

Commit

Permalink
Format style with Black
Browse files Browse the repository at this point in the history
  • Loading branch information
Víctor Ruiz committed Aug 25, 2020
1 parent b1c299a commit 08637f1
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 105 deletions.
2 changes: 1 addition & 1 deletion scrapy_jsonschema/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from scrapy_jsonschema.item import JsonSchemaItem
from scrapy_jsonschema.pipeline import JsonSchemaValidatePipeline

__version__ = '0.4.0'
__version__ = "0.4.0"
31 changes: 13 additions & 18 deletions scrapy_jsonschema/item.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@

import re
import six
from jsonschema import (
Draft3Validator,
Draft4Validator,
Draft6Validator,
Draft7Validator,
FormatChecker
FormatChecker,
)
from scrapy_jsonschema.draft import (
JSON_SCHEMA_DRAFT_3,
Expand All @@ -32,7 +31,6 @@
from abc import ABCMeta as _BaseItemMeta



def _merge_schema(base, new):
if base is None or new is None:
return base or new
Expand Down Expand Up @@ -66,19 +64,19 @@ class JsonSchemaMeta(_BaseItemMeta):
JSON_SCHEMA_DRAFT_7: draft7_format_checker,
}

combination_schemas_keywords = ['allOf', 'anyOf', 'oneOf']
combination_schemas_keywords = ["allOf", "anyOf", "oneOf"]

def __new__(mcs, class_name, bases, attrs):
cls = super(JsonSchemaMeta, mcs).__new__(mcs, class_name, bases, attrs)
fields = {}
schema = attrs.get('jsonschema', {})
schema = attrs.get("jsonschema", {})
if cls.merge_schema:
# priority: left to right
for base in bases:
base_schema = getattr(base, 'jsonschema', None)
base_schema = getattr(base, "jsonschema", None)
if base_schema:
schema = _merge_schema(schema, base_schema)
setattr(cls, 'jsonschema', schema)
setattr(cls, "jsonschema", schema)
if not schema:
raise ValueError(
'{} must contain "jsonschema" attribute'.format(cls.__name__)
Expand All @@ -90,33 +88,31 @@ def __new__(mcs, class_name, bases, attrs):
cls.fields = cls.fields.copy()
cls.fields.update(fields)

pattern_properties = schema.get('patternProperties', {})
pattern_properties = schema.get("patternProperties", {})
cls.pattern_properties = [
re.compile(p)
for p in pattern_properties.keys()
if p is not 'additionalProperties'
if p is not "additionalProperties"
]
return cls

@classmethod
def get_top_level_property_names(cls, schema):
for field in schema.get('properties', {}):
for field in schema.get("properties", {}):
yield field

for keyword in cls.combination_schemas_keywords:
for subschema in schema.get(keyword, []):
for field in subschema.get('properties', {}):
for field in subschema.get("properties", {}):
yield field

@classmethod
def _get_validator(cls, schema):
draft_version = schema.get('$schema')
draft_version = schema.get("$schema")
# Default to Draft4Validator for backward-compatibility
validator_class = cls.draft_to_validator.get(
draft_version, Draft4Validator
)
validator_class = cls.draft_to_validator.get(draft_version, Draft4Validator)
format_checker = cls.draft_to_format_checker.get(
schema.get('$schema'), draft4_format_checker
schema.get("$schema"), draft4_format_checker
)
return validator_class(schema, format_checker=format_checker)

Expand All @@ -135,6 +131,5 @@ def __setitem__(self, key, value):

else:
raise KeyError(
"%s does not support field: %s"
% (self.__class__.__name__, key)
"%s does not support field: %s" % (self.__class__.__name__, key)
)
10 changes: 5 additions & 5 deletions scrapy_jsonschema/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class JsonSchemaValidatePipeline(object):

STAT_FMT = 'jsonschema/errors/{field}'
STAT_FMT = "jsonschema/errors/{field}"
REQUIRED_RE = re.compile("'(.+?)' is a required property")

@classmethod
Expand All @@ -30,13 +30,13 @@ def process_item(self, item, spider):
required_match = self.REQUIRED_RE.search(error.message)
if required_match:
absolute_path.append(required_match.group(1))
path = '.'.join(map(str, absolute_path))
path = ".".join(map(str, absolute_path))
self.stats.inc_value(self.STAT_FMT.format(field=path))
paths_messages.append((path, error.message))
if errors:
error_msg = ''
error_msg = ""
for path, message in paths_messages:
error_msg += u'{}: {}\n'.format(path, message)
raise DropItem(u'schema validation failed: \n {}'.format(error_msg))
error_msg += u"{}: {}\n".format(path, message)
raise DropItem(u"schema validation failed: \n {}".format(error_msg))

return item
38 changes: 19 additions & 19 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
from setuptools import setup

setup(
name='scrapy-jsonschema',
version='0.4.0',
license='BSD',
description='Scrapy schema validation pipeline and Item builder using JSON Schema',
author='Scrapinghub',
author_email='[email protected]',
url='http://github.com/scrapy-plugins/scrapy-jsonschema',
packages=['scrapy_jsonschema'],
platforms=['Any'],
name="scrapy-jsonschema",
version="0.4.0",
license="BSD",
description="Scrapy schema validation pipeline and Item builder using JSON Schema",
author="Scrapinghub",
author_email="[email protected]",
url="http://github.com/scrapy-plugins/scrapy-jsonschema",
packages=["scrapy_jsonschema"],
platforms=["Any"],
classifiers=[
'Development Status :: 4 - Beta',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
"Development Status :: 4 - Beta",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
],
install_requires=['scrapy', 'jsonschema[format]', 'six']
install_requires=["scrapy", "jsonschema[format]", "six"],
)
4 changes: 1 addition & 3 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@
},
{
"id": 123,
"name": [
"name"
], # this value should be a string, not a list of strings
"name": ["name"], # this value should be a string, not a list of strings
},
]

Expand Down
74 changes: 29 additions & 45 deletions tests/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,103 +16,92 @@
merge_schema_new,
)


class SchemaWithCombiningKeywords(TestCase):

schema_allOf = {
"$schema": JSON_SCHEMA_DRAFT_7,
"$schema": JSON_SCHEMA_DRAFT_7,
"allOf": [
{
"properties": {"foo": {"type": "string"}},
"required": ["foo"],
},
{
"properties": {"bar": {"type": "number"}},
"required": ["bar"]
}
]
{"properties": {"bar": {"type": "number"}}, "required": ["bar"]},
],
}

schema_anyOf = {
"$schema": JSON_SCHEMA_DRAFT_7,
"$schema": JSON_SCHEMA_DRAFT_7,
"anyOf": [
{
"properties": {"foo": {"type": "string"}},
"required": ["foo"],
},
{
"properties": {"bar": {"type": "number"}},
"required": ["bar"]
}
]
{"properties": {"bar": {"type": "number"}}, "required": ["bar"]},
],
}

schema_oneOf = {
"$schema": JSON_SCHEMA_DRAFT_7,
"$schema": JSON_SCHEMA_DRAFT_7,
"oneOf": [
{
"properties": {"foo": {"type": "string"}},
"required": ["foo"],
},
{
"properties": {"bar": {"type": "number"}},
"required": ["bar"]
}
]
{"properties": {"bar": {"type": "number"}}, "required": ["bar"]},
],
}

def test_all_of_schema(self):

class allOfItem(JsonSchemaItem):
jsonschema = self.schema_allOf

item = allOfItem()
item['foo'] = 'foo'
item['bar'] = 2
item["foo"] = "foo"
item["bar"] = 2
self.assertFalse(list(item.validator.iter_errors(dict(item))))

with pytest.raises(AssertionError):
item = allOfItem()
item['foo'] = 'foo'
item["foo"] = "foo"
self.assertFalse(list(item.validator.iter_errors(dict(item))))


def test_any_of_schema(self):

class anyOfItem(JsonSchemaItem):
jsonschema = self.schema_anyOf

item = anyOfItem()
item['foo'] = 'foo'
item['bar'] = 2
item["foo"] = "foo"
item["bar"] = 2
self.assertFalse(list(item.validator.iter_errors(dict(item))))

item = anyOfItem()
item['foo'] = 'foo'
item["foo"] = "foo"
self.assertFalse(list(item.validator.iter_errors(dict(item))))

item = anyOfItem()
item['bar'] = 2
item["bar"] = 2
self.assertFalse(list(item.validator.iter_errors(dict(item))))

def test_one_of_schema(self):

class oneOfItem(JsonSchemaItem):
jsonschema = self.schema_oneOf

item = oneOfItem()
item['foo'] = 'foo'
item["foo"] = "foo"
self.assertFalse(list(item.validator.iter_errors(dict(item))))

item = oneOfItem()
item['bar'] = 2
item["bar"] = 2
self.assertFalse(list(item.validator.iter_errors(dict(item))))

with pytest.raises(AssertionError):
item = oneOfItem()
item['foo'] = 'foo'
item['bar'] = 2
item["foo"] = "foo"
item["bar"] = 2
self.assertFalse(list(item.validator.iter_errors(dict(item))))


class ValidSchemaTestCase(TestCase):

schema1 = {
Expand Down Expand Up @@ -187,19 +176,14 @@ def test_format_validation(self):
schema = {
"$schema": JSON_SCHEMA_DRAFT_7,
"title": "Item with Schema Draft",
"properties": {
"url": {
"type": "string",
"format": "uri"
}
}
"properties": {"url": {"type": "string", "format": "uri"}},
}

with pytest.raises(ValidationError):
draft7_validator = JsonSchemaItem._get_validator(schema)
draft7_validator.validate({'url': 'this is not an uri'})
draft7_validator.validate({"url": "this is not an uri"})

draft7_validator.validate({'url': 'http://localhost'})
draft7_validator.validate({"url": "http://localhost"})

def test_pattern_properties(self):
schema = {
Expand All @@ -218,15 +202,15 @@ def test_pattern_properties(self):
}

draft7_validator = JsonSchemaItem._get_validator(schema)
draft7_validator.validate({'image_1': 'http://foo.com/bar/1'})
draft7_validator.validate({"image_1": "http://foo.com/bar/1"})
with pytest.raises(ValidationError):
draft7_validator.validate({'image_a': 'http://foo.com/bar/a'})
draft7_validator.validate({"image_a": "http://foo.com/bar/a"})

class PatternPropertiesItem(JsonSchemaItem):
jsonschema = schema

item = PatternPropertiesItem()
item['image_1'] = 'http://foo.com/bar/1'
item["image_1"] = "http://foo.com/bar/1"

with pytest.raises(KeyError):
item['image_a'] = 'http://foo.com/bar/a'
item["image_a"] = "http://foo.com/bar/a"
28 changes: 14 additions & 14 deletions tests/test_item_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,31 @@ class TestItem1(JsonSchemaItem):
except SchemaError:
pass
else:
self.fail('SchemaError was not raised')
self.fail("SchemaError was not raised")

def test_valid_schema(self):
class TestItem2(JsonSchemaItem):
jsonschema = valid_schema

def test_merge_schema_func(self):
schema1 = {
'both': 1,
'only_base': 2,
'nested': {'list_to_merge': [1, 2], 'both': 'foo'},
"both": 1,
"only_base": 2,
"nested": {"list_to_merge": [1, 2], "both": "foo"},
}
schema2 = {
'both': 3,
'only_new': 4,
'nested': {'list_to_merge': [3], 'both': 'bar', 'only_new': 'baz'},
"both": 3,
"only_new": 4,
"nested": {"list_to_merge": [3], "both": "bar", "only_new": "baz"},
}
expected = {
'both': 1,
'only_base': 2,
'only_new': 4,
'nested': {
'list_to_merge': [1, 2, 3],
'both': 'foo',
'only_new': 'baz',
"both": 1,
"only_base": 2,
"only_new": 4,
"nested": {
"list_to_merge": [1, 2, 3],
"both": "foo",
"only_new": "baz",
},
}
self.assertEqual(_merge_schema(schema1, schema2), expected)
Expand Down

0 comments on commit 08637f1

Please sign in to comment.