Skip to content
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,6 @@ ENV/

# mypy
.mypy_cache/

# pytest
.pytest_cache/
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ language: python
sudo: false
matrix:
include:
- python: 2.7
- python: 3.2
- python: 3.3
- python: 3.4
Expand All @@ -10,10 +11,12 @@ matrix:
- python: nightly
- python: pypy3
allow_failures:
- python: 3.2
- python: 3.2 # EOL
- python: 3.3 # EOL
- python: nightly
before_install:
- if [[ $TRAVIS_PYTHON_VERSION == '3.2' ]]; then pip install 'coverage<4.0.0'; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install 'pyflakes<2.0.0'; fi
- pip install codecov
install:
- pip install -r requirements.txt
Expand Down
6 changes: 4 additions & 2 deletions openapi_spec_validator/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def __init__(self, instance_resolver):
def __call__(self, func):
def wrapped(validator, schema_element, instance, schema):
if not isinstance(instance, dict) or '$ref' not in instance:
yield from func(validator, schema_element, instance, schema)
for res in func(validator, schema_element, instance, schema):
yield res
return

ref = instance['$ref']
Expand All @@ -30,7 +31,8 @@ def wrapped(validator, schema_element, instance, schema):
self._attach_scope(instance)
with self.visiting.visit(ref):
with self.instance_resolver.resolving(ref) as target:
yield from func(validator, schema_element, target, schema)
for res in func(validator, schema_element, target, schema):
yield res

return wrapped

Expand Down
1 change: 0 additions & 1 deletion openapi_spec_validator/resources/schemas/v2.0/schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"title": "A JSON Schema for Swagger 2.0 API.",
"id": "http://swagger.io/v2/schema.json#",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [
Expand Down
42 changes: 26 additions & 16 deletions openapi_spec_validator/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,24 @@ def __init__(self, validator_factory, resolver_handlers):
self.resolver_handlers = resolver_handlers

def validate(self, spec, spec_url=''):
for error in self.iter_errors(spec, spec_url=spec_url):
raise error
for err in self.iter_errors(spec, spec_url=spec_url):
raise err

def iter_errors(self, spec, spec_url=''):
spec_resolver = self._get_resolver(spec_url, spec)
dereferencer = self._get_dereferencer(spec_resolver)

validator = self._get_validator(spec_resolver)
yield from validator.iter_errors(spec)
for err in validator.iter_errors(spec):
yield err

paths = spec.get('paths', {})
yield from self._iter_paths_errors(paths, dereferencer)
for err in self._iter_paths_errors(paths, dereferencer):
yield err

components = spec.get('components', {})
yield from self._iter_components_errors(components, dereferencer)
for err in self._iter_components_errors(components, dereferencer):
yield err

def _get_resolver(self, base_uri, referrer):
return RefResolver(
Expand Down Expand Up @@ -81,7 +84,8 @@ def iter_errors(self, components):
components_deref = self.dereferencer.dereference(components)

schemas = components_deref.get('schemas', {})
yield from self._iter_schemas_errors(schemas)
for err in self._iter_schemas_errors(schemas):
yield err

def _iter_schemas_errors(self, schemas):
return SchemasValidator(self.dereferencer).iter_errors(schemas)
Expand All @@ -95,7 +99,8 @@ def __init__(self, dereferencer):
def iter_errors(self, schemas):
schemas_deref = self.dereferencer.dereference(schemas)
for name, schema in iteritems(schemas_deref):
yield from self._iter_schem_errors(schema)
for err in self._iter_schem_errors(schema):
yield err

def _iter_schem_errors(self, schema):
return SchemaValidator(self.dereferencer).iter_errors(schema)
Expand All @@ -111,7 +116,8 @@ def iter_errors(self, schema):

if 'allOf' in schema_deref:
for inner_schema in schema_deref['allOf']:
yield from self.iter_errors(inner_schema)
for err in self.iter_errors(inner_schema):
yield err

required = schema_deref.get('required', [])
properties = schema_deref.get('properties', {}).keys()
Expand All @@ -132,7 +138,8 @@ def __init__(self, dereferencer):
def iter_errors(self, paths):
paths_deref = self.dereferencer.dereference(paths)
for url, path_item in iteritems(paths_deref):
yield from self._iter_path_errors(url, path_item)
for err in self._iter_path_errors(url, path_item):
yield err

def _iter_path_errors(self, url, path_item):
return PathValidator(self.dereferencer).iter_errors(url, path_item)
Expand All @@ -146,7 +153,8 @@ def __init__(self, dereferencer):
def iter_errors(self, url, path_item):
path_item_deref = self.dereferencer.dereference(path_item)

yield from self._iter_path_item_errors(url, path_item_deref)
for err in self._iter_path_item_errors(url, path_item_deref):
yield err

def _iter_path_item_errors(self, url, path_item):
return PathItemValidator(self.dereferencer).iter_errors(url, path_item)
Expand All @@ -165,14 +173,16 @@ def iter_errors(self, url, path_item):
path_item_deref = self.dereferencer.dereference(path_item)

parameters = path_item_deref.get('parameters', [])
yield from self._iter_parameters_errors(parameters)
for err in self._iter_parameters_errors(parameters):
yield err

for field_name, operation in iteritems(path_item):
if field_name not in self.OPERATIONS:
continue

yield from self._iter_operation_errors(
url, field_name, operation, parameters)
for err in self._iter_operation_errors(
url, field_name, operation, parameters):
yield err

def _iter_operation_errors(self, url, name, operation, path_parameters):
return OperationValidator(self.dereferencer).iter_errors(
Expand All @@ -192,7 +202,8 @@ def iter_errors(self, url, name, operation, path_parameters=None):
operation_deref = self.dereferencer.dereference(operation)

parameters = operation_deref.get('parameters', [])
yield from self._iter_parameters_errors(parameters)
for err in self._iter_parameters_errors(parameters):
yield err

all_params = list(set(
list(self._get_path_param_names(path_parameters)) +
Expand All @@ -205,8 +216,7 @@ def iter_errors(self, url, name, operation, path_parameters=None):
"Path parameter '{0}' for '{1}' operation in '{2}' "
"was not resolved".format(path, name, url)
)

return []
return

def _get_path_param_names(self, params):
for param in params:
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def run_tests(self):
package_data={
'openapi_spec_validator': [
'openapi_spec_validator/resources/schemas/v3.0.0/*',
'openapi_spec_validator/resources/schemas/v2.0/*',
],
},
include_package_data=True,
Expand Down Expand Up @@ -85,7 +86,7 @@ def run_tests(self):
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = {py33,py34,py35,py36}-{default,simplejson}
envlist = {py27,py34,py35,py36}-{default,simplejson}

[testenv]
deps =
Expand Down