Hello community,

here is the log from the commit of package python-openapi-core for 
openSUSE:Factory checked in at 2019-07-23 22:40:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-openapi-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-openapi-core.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-openapi-core"

Tue Jul 23 22:40:55 2019 rev:3 rq:717909 version:0.11.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-openapi-core/python-openapi-core.changes  
2019-06-06 18:18:13.196670257 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-openapi-core.new.4126/python-openapi-core.changes
        2019-07-23 22:41:01.306899418 +0200
@@ -1,0 +2,11 @@
+Tue Jul 23 13:45:01 UTC 2019 - Tomáš Chvátal <tchva...@suse.com>
+
+- Update to 0.11.0:
+  * End of Python 3.4 support (#136)
+  * Add support for one-of with any type (#133)
+  * Modify FlaskOpenAPIRequest to accommodate path variables (#141)
+  * Primitive types unmarshallers (#138)
+  * attr errors hashable fix (#143)
+  * Parameters on path item object support (#144)
+
+-------------------------------------------------------------------

Old:
----
  0.10.0.tar.gz

New:
----
  0.11.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-openapi-core.spec ++++++
--- /var/tmp/diff_new_pack.GC3GWq/_old  2019-07-23 22:41:01.814898774 +0200
+++ /var/tmp/diff_new_pack.GC3GWq/_new  2019-07-23 22:41:01.814898774 +0200
@@ -17,9 +17,8 @@
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
-# remove with update to > 0.5.0; atm it is not working on py2 at all
 Name:           python-openapi-core
-Version:        0.10.0
+Version:        0.11.0
 Release:        0
 Summary:        Adds client-side and server-side support for the oas3
 License:        BSD-3-Clause

++++++ 0.10.0.tar.gz -> 0.11.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/.travis.yml 
new/openapi-core-0.11.0/.travis.yml
--- old/openapi-core-0.10.0/.travis.yml 2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/.travis.yml 2019-06-18 23:42:44.000000000 +0200
@@ -3,7 +3,6 @@
 matrix:
   include:
   - python: 2.7
-  - python: 3.4
   - python: 3.5
   - python: 3.6
   - python: 3.7
@@ -14,12 +13,12 @@
   allow_failures:
   - python: nightly
 before_install:
-- if [[ $TRAVIS_PYTHON_VERSION == '3.2' ]]; then pip install 'coverage<4.0.0'; 
fi
 - pip install codecov
 - pip install 'py>=1.5.0'
 install:
-- pip install -e .
+- pip install -r requirements.txt
 - pip install -r requirements_dev.txt
+- pip install -e .
 script:
 - python setup.py test
 after_success:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/openapi_core/__init__.py 
new/openapi-core-0.11.0/openapi_core/__init__.py
--- old/openapi-core-0.10.0/openapi_core/__init__.py    2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/__init__.py    2019-06-18 
23:42:44.000000000 +0200
@@ -6,7 +6,7 @@
 
 __author__ = 'Artur Maciag'
 __email__ = 'maciag.ar...@gmail.com'
-__version__ = '0.10.0'
+__version__ = '0.11.0'
 __url__ = 'https://github.com/p1c2u/openapi-core'
 __license__ = 'BSD 3-Clause License'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/content/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/content/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/content/exceptions.py   
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/content/exceptions.py   
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIContentError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class MimeTypeNotFound(OpenAPIContentError):
     mimetype = attr.ib()
     availableMimetypes = attr.ib()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/content/models.py 
new/openapi-core-0.11.0/openapi_core/schema/content/models.py
--- old/openapi-core-0.10.0/openapi_core/schema/content/models.py       
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/content/models.py       
2019-06-18 23:42:44.000000000 +0200
@@ -18,4 +18,4 @@
             if fnmatch.fnmatch(mimetype, key):
                 return value
 
-        raise MimeTypeNotFound(mimetype, self.keys())
+        raise MimeTypeNotFound(mimetype, list(self.keys()))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/media_types/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/media_types/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/media_types/exceptions.py       
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/media_types/exceptions.py       
2019-06-18 23:42:44.000000000 +0200
@@ -1,19 +1,21 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIMediaTypeError(OpenAPIMappingError):
     pass
 
-@attr.s
+
+@attr.s(hash=True)
 class InvalidMediaTypeValue(OpenAPIMediaTypeError):
     original_exception = attr.ib()
 
     def __str__(self):
         return "Mimetype invalid: {0}".format(self.original_exception)
 
-@attr.s
+
+@attr.s(hash=True)
 class InvalidContentType(OpenAPIMediaTypeError):
     mimetype = attr.ib()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/media_types/models.py 
new/openapi-core-0.11.0/openapi_core/schema/media_types/models.py
--- old/openapi-core-0.10.0/openapi_core/schema/media_types/models.py   
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/media_types/models.py   
2019-06-18 23:42:44.000000000 +0200
@@ -47,6 +47,7 @@
             raise InvalidMediaTypeValue(exc)
 
         try:
-            return self.schema.validate(unmarshalled, 
custom_formatters=custom_formatters)
+            return self.schema.validate(
+                unmarshalled, custom_formatters=custom_formatters)
         except OpenAPISchemaError as exc:
             raise InvalidMediaTypeValue(exc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/operations/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/operations/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/operations/exceptions.py        
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/operations/exceptions.py        
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIOperationError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class InvalidOperation(OpenAPIOperationError):
     path_pattern = attr.ib()
     http_method = attr.ib()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/parameters/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/parameters/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/parameters/exceptions.py        
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/parameters/exceptions.py        
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIParameterError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class MissingParameter(OpenAPIParameterError):
     name = attr.ib()
 
@@ -15,7 +15,7 @@
         return "Missing parameter (without default value): 
{0}".format(self.name)
 
 
-@attr.s
+@attr.s(hash=True)
 class MissingRequiredParameter(OpenAPIParameterError):
     name = attr.ib()
 
@@ -23,7 +23,7 @@
         return "Missing required parameter: {0}".format(self.name)
 
 
-@attr.s
+@attr.s(hash=True)
 class EmptyParameterValue(OpenAPIParameterError):
     name = attr.ib()
 
@@ -31,7 +31,7 @@
         return "Value of parameter cannot be empty: {0}".format(self.name)
 
 
-@attr.s
+@attr.s(hash=True)
 class InvalidParameterValue(OpenAPIParameterError):
     name = attr.ib()
     original_exception = attr.ib()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/parameters/models.py 
new/openapi-core-0.11.0/openapi_core/schema/parameters/models.py
--- old/openapi-core-0.10.0/openapi_core/schema/parameters/models.py    
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/parameters/models.py    
2019-06-18 23:42:44.000000000 +0200
@@ -118,6 +118,7 @@
             raise InvalidParameterValue(self.name, exc)
 
         try:
-            return self.schema.validate(unmarshalled, 
custom_formatters=custom_formatters)
+            return self.schema.validate(
+                unmarshalled, custom_formatters=custom_formatters)
         except OpenAPISchemaError as exc:
             raise InvalidParameterValue(self.name, exc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/paths/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/paths/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/paths/exceptions.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/openapi-core-0.11.0/openapi_core/schema/paths/exceptions.py     
2019-06-18 23:42:44.000000000 +0200
@@ -0,0 +1,15 @@
+import attr
+
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
+
+class OpenAPIPathError(OpenAPIMappingError):
+    pass
+
+
+@attr.s(hash=True)
+class InvalidPath(OpenAPIPathError):
+    path_pattern = attr.ib()
+
+    def __str__(self):
+        return "Unknown path {0}".format(self.path_pattern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/request_bodies/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/request_bodies/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/request_bodies/exceptions.py    
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/request_bodies/exceptions.py    
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIRequestBodyError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class MissingRequestBody(OpenAPIRequestBodyError):
     request = attr.ib()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/responses/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/responses/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/responses/exceptions.py 
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/responses/exceptions.py 
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIResponseError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class InvalidResponse(OpenAPIResponseError):
     http_status = attr.ib()
     responses = attr.ib()
@@ -16,7 +16,7 @@
         return "Unknown response http status: 
{0}".format(str(self.http_status))
 
 
-@attr.s
+@attr.s(hash=True)
 class MissingResponseContent(OpenAPIResponseError):
     response = attr.ib()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/schemas/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/schemas/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/schemas/exceptions.py   
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/schemas/exceptions.py   
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPISchemaError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class NoValidSchema(OpenAPISchemaError):
     value = attr.ib()
 
@@ -15,7 +15,7 @@
         return "No valid schema found for value: {0}".format(self.value)
 
 
-@attr.s
+@attr.s(hash=True)
 class UndefinedItemsSchema(OpenAPISchemaError):
     type = attr.ib()
 
@@ -23,7 +23,7 @@
         return "Null value for schema type {0}".format(self.type)
 
 
-@attr.s
+@attr.s(hash=True)
 class InvalidSchemaValue(OpenAPISchemaError):
     msg = attr.ib()
     value = attr.ib()
@@ -32,7 +32,8 @@
     def __str__(self):
         return self.msg.format(value=self.value, type=self.type)
 
-@attr.s
+
+@attr.s(hash=True)
 class InvalidCustomFormatSchemaValue(InvalidSchemaValue):
     original_exception = attr.ib()
 
@@ -40,14 +41,15 @@
         return self.msg.format(value=self.value, type=self.type, 
exception=self.original_exception)
 
 
-@attr.s
+@attr.s(hash=True)
 class UndefinedSchemaProperty(OpenAPISchemaError):
     extra_props = attr.ib()
 
     def __str__(self):
         return "Extra unexpected properties found in schema: 
{0}".format(self.extra_props)
 
-@attr.s
+
+@attr.s(hash=True)
 class InvalidSchemaProperty(OpenAPISchemaError):
     property_name = attr.ib()
     original_exception = attr.ib()
@@ -55,7 +57,8 @@
     def __str__(self):
         return "Invalid schema property {0}: {1}".format(self.property_name, 
self.original_exception)
 
-@attr.s
+
+@attr.s(hash=True)
 class MissingSchemaProperty(OpenAPISchemaError):
     property_name = attr.ib()
 
@@ -63,7 +66,7 @@
         return "Missing schema property: {0}".format(self.property_name)
 
 
-@attr.s
+@attr.s(hash=True)
 class NoOneOfSchema(OpenAPISchemaError):
     type = attr.ib()
 
@@ -71,9 +74,22 @@
         return "Exactly one valid schema type {0} should be valid, None 
found.".format(self.type)
 
 
-@attr.s
+@attr.s(hash=True)
 class MultipleOneOfSchema(OpenAPISchemaError):
     type = attr.ib()
 
     def __str__(self):
         return "Exactly one schema type {0} should be valid, more than one 
found".format(self.type)
+
+
+class UnmarshallerError(OpenAPIMappingError):
+    pass
+
+
+class UnmarshallerStrictTypeError(UnmarshallerError):
+    value = attr.ib()
+    types = attr.ib()
+    
+    def __str__(self):
+        return "Value {value} is not one of types {types}".format(
+            self.value, self.types)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/schemas/models.py 
new/openapi-core-0.11.0/openapi_core/schema/schemas/models.py
--- old/openapi-core-0.10.0/openapi_core/schema/schemas/models.py       
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/schemas/models.py       
2019-06-18 23:42:44.000000000 +0200
@@ -2,7 +2,6 @@
 import attr
 import functools
 import logging
-from base64 import b64decode, b64encode
 from collections import defaultdict
 from datetime import date, datetime
 from uuid import UUID
@@ -17,6 +16,7 @@
     InvalidSchemaValue, UndefinedSchemaProperty, MissingSchemaProperty,
     OpenAPISchemaError, NoOneOfSchema, MultipleOneOfSchema, NoValidSchema,
     UndefinedItemsSchema, InvalidCustomFormatSchemaValue, 
InvalidSchemaProperty,
+    UnmarshallerStrictTypeError,
 )
 from openapi_core.schema.schemas.util import (
     forcebool, format_date, format_datetime, format_byte, format_uuid,
@@ -156,14 +156,19 @@
         return set(required)
 
     def get_cast_mapping(self, custom_formatters=None, strict=True):
+        primitive_unmarshallers = self.get_primitive_unmarshallers(
+            custom_formatters=custom_formatters)
+
+        primitive_unmarshallers_partial = dict(
+            (t, functools.partial(u, type_format=self.format, strict=strict))
+            for t, u in primitive_unmarshallers.items()
+        )
+
         pass_defaults = lambda f: functools.partial(
           f, custom_formatters=custom_formatters, strict=strict)
         mapping = self.DEFAULT_CAST_CALLABLE_GETTER.copy()
+        mapping.update(primitive_unmarshallers_partial)
         mapping.update({
-            SchemaType.STRING: pass_defaults(self._unmarshal_string),
-            SchemaType.BOOLEAN: pass_defaults(self._unmarshal_boolean),
-            SchemaType.INTEGER: pass_defaults(self._unmarshal_integer),
-            SchemaType.NUMBER: pass_defaults(self._unmarshal_number),
             SchemaType.ANY: pass_defaults(self._unmarshal_any),
             SchemaType.ARRAY: pass_defaults(self._unmarshal_collection),
             SchemaType.OBJECT: pass_defaults(self._unmarshal_object),
@@ -185,6 +190,10 @@
                 raise InvalidSchemaValue("Null value for non-nullable schema", 
value, self.type)
             return self.default
 
+        if self.enum and value not in self.enum:
+            raise InvalidSchemaValue(
+                "Value {value} not in enum choices: {type}", value, self.enum)
+
         cast_mapping = self.get_cast_mapping(
             custom_formatters=custom_formatters, strict=strict)
 
@@ -194,6 +203,9 @@
         cast_callable = cast_mapping[self.type]
         try:
             return cast_callable(value)
+        except UnmarshallerStrictTypeError:
+            raise InvalidSchemaValue(
+                "Value {value} is not of type {type}", value, self.type)
         except ValueError:
             raise InvalidSchemaValue(
                 "Failed to cast value {value} to type {type}", value, 
self.type)
@@ -208,69 +220,27 @@
         if casted is None and not self.required:
             return None
 
-        if self.enum and casted not in self.enum:
-            raise InvalidSchemaValue(
-                "Value {value} not in enum choices: {type}", value, self.enum)
-
         return casted
 
-    def _unmarshal_string(self, value, custom_formatters=None, strict=True):
-        if strict and not isinstance(value, (text_type, binary_type)):
-            raise InvalidSchemaValue("Value {value} is not of type {type}", 
value, self.type)
-
-        try:
-            schema_format = SchemaFormat(self.format)
-        except ValueError:
-            msg = "Unsupported format {type} unmarshalling for value {value}"
-            if custom_formatters is not None:
-                formatstring = custom_formatters.get(self.format)
-                if formatstring is None:
-                    raise InvalidSchemaValue(msg, value, self.format)
-            else:
-                raise InvalidSchemaValue(msg, value, self.format)
-        else:
-            formatstring = self.STRING_FORMAT_CALLABLE_GETTER[schema_format]
-
-        try:
-            return formatstring.unmarshal(value)
-        except ValueError as exc:
-            raise InvalidCustomFormatSchemaValue(
-                "Failed to format value {value} to format {type}: 
{exception}", value, self.format, exc)
-
-    def _unmarshal_integer(self, value, custom_formatters=None, strict=True):
-        if strict and not isinstance(value, integer_types):
-            raise InvalidSchemaValue("Value {value} is not of type {type}", 
value, self.type)
-
-        return int(value)
-
-    def _unmarshal_number(self, value, custom_formatters=None, strict=True):
-        if strict and not isinstance(value, (float, ) + integer_types):
-            raise InvalidSchemaValue("Value {value} is not of type {type}", 
value, self.type)
-
-        try:
-            schema_format = SchemaFormat(self.format)
-        except ValueError:
-            msg = "Unsupported format {type} unmarshalling for value {value}"
-            if custom_formatters is not None:
-                formatnumber = custom_formatters.get(self.format)
-                if formatnumber is None:
-                    raise InvalidSchemaValue(msg, value, self.format)
-            else:
-                raise InvalidSchemaValue(msg, value, self.format)
-        else:
-            formatnumber = self.NUMBER_FORMAT_CALLABLE_GETTER[schema_format]
+    def get_primitive_unmarshallers(self, **options):
+        from openapi_core.schema.schemas.unmarshallers import (
+            StringUnmarshaller, BooleanUnmarshaller, IntegerUnmarshaller,
+            NumberUnmarshaller,
+        )
 
-        try:
-            return formatnumber.unmarshal(value)
-        except ValueError as exc:
-            raise InvalidCustomFormatSchemaValue(
-                "Failed to format value {value} to format {type}: 
{exception}", value, self.format, exc)
-
-    def _unmarshal_boolean(self, value, custom_formatters=None, strict=True):
-        if strict and not isinstance(value, (bool, )):
-            raise InvalidSchemaValue("Value {value} is not of type {type}", 
value, self.type)
+        unmarshallers_classes = {
+            SchemaType.STRING: StringUnmarshaller,
+            SchemaType.BOOLEAN: BooleanUnmarshaller,
+            SchemaType.INTEGER: IntegerUnmarshaller,
+            SchemaType.NUMBER: NumberUnmarshaller,
+        }
+
+        unmarshallers = dict(
+            (t, klass(**options))
+            for t, klass in unmarshallers_classes.items()
+        )
 
-        return forcebool(value)
+        return unmarshallers
 
     def _unmarshal_any(self, value, custom_formatters=None, strict=True):
         types_resolve_order = [
@@ -278,13 +248,32 @@
             SchemaType.INTEGER, SchemaType.NUMBER, SchemaType.STRING,
         ]
         cast_mapping = self.get_cast_mapping()
-        for schema_type in types_resolve_order:
-            cast_callable = cast_mapping[schema_type]
-            try:
-                return cast_callable(value)
-            # @todo: remove ValueError when validation separated
-            except (OpenAPISchemaError, TypeError, ValueError):
-                continue
+        if self.one_of:
+            result = None
+            for subschema in self.one_of:
+                try:
+                    casted = subschema.cast(value, custom_formatters)
+                except (OpenAPISchemaError, TypeError, ValueError):
+                    continue
+                else:
+                    if result is not None:
+                        raise MultipleOneOfSchema(self.type)
+                    result = casted
+
+            if result is None:
+                raise NoOneOfSchema(self.type)
+
+            return result
+        else:
+            for schema_type in types_resolve_order:
+                cast_callable = cast_mapping[schema_type]
+                try:
+                    return cast_callable(value)
+                except UnmarshallerStrictTypeError:
+                    continue
+                # @todo: remove ValueError when validation separated
+                except (OpenAPISchemaError, TypeError, ValueError):
+                    continue
 
         raise NoValidSchema(value)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/schemas/unmarshallers.py 
new/openapi-core-0.11.0/openapi_core/schema/schemas/unmarshallers.py
--- old/openapi-core-0.10.0/openapi_core/schema/schemas/unmarshallers.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/openapi-core-0.11.0/openapi_core/schema/schemas/unmarshallers.py        
2019-06-18 23:42:44.000000000 +0200
@@ -0,0 +1,107 @@
+from six import text_type, binary_type, integer_types
+
+from openapi_core.schema.schemas.enums import SchemaFormat, SchemaType
+from openapi_core.schema.schemas.exceptions import (
+    InvalidSchemaValue, InvalidCustomFormatSchemaValue,
+    OpenAPISchemaError, MultipleOneOfSchema, NoOneOfSchema,
+    InvalidSchemaProperty,
+    UnmarshallerStrictTypeError,
+)
+from openapi_core.schema.schemas.util import (
+    forcebool, format_date, format_datetime, format_byte, format_uuid,
+    format_number,
+)
+
+
+class StrictUnmarshaller(object):
+
+    STRICT_TYPES = ()
+
+    def __call__(self, value, type_format=SchemaFormat.NONE, strict=True):
+        if self.STRICT_TYPES and strict and not isinstance(
+                value, self.STRICT_TYPES):
+            raise UnmarshallerStrictTypeError(value, self.STRICT_TYPES)
+
+        return value
+
+
+class PrimitiveTypeUnmarshaller(StrictUnmarshaller):
+
+    FORMATTERS = {
+        SchemaFormat.NONE: lambda x: x,
+    }
+
+    def __init__(self, custom_formatters=None):
+        if custom_formatters is None:
+            custom_formatters = {}
+        self.custom_formatters = custom_formatters
+
+    def __call__(self, value, type_format=SchemaFormat.NONE, strict=True):
+        value = super(PrimitiveTypeUnmarshaller, self).__call__(
+            value, type_format=type_format, strict=strict)
+
+        try:
+            schema_format = SchemaFormat(type_format)
+        except ValueError:
+            formatter = self.custom_formatters.get(type_format)
+        else:
+            formatters = self.get_formatters()
+            formatter = formatters.get(schema_format)
+
+        if formatter is None:
+            raise InvalidSchemaValue(
+                "Unsupported format {type} unmarshalling "
+                "for value {value}",
+                value, type_format)
+
+        try:
+            return formatter(value)
+        except ValueError as exc:
+            raise InvalidCustomFormatSchemaValue(
+                "Failed to format value {value} to format {type}: {exception}",
+                value, type_format, exc)
+
+    def get_formatters(self):
+        return self.FORMATTERS
+
+
+class StringUnmarshaller(PrimitiveTypeUnmarshaller):
+
+    STRICT_TYPES = (text_type, binary_type)
+    FORMATTERS = {
+        SchemaFormat.NONE: text_type,
+        SchemaFormat.PASSWORD: text_type,
+        SchemaFormat.DATE: format_date,
+        SchemaFormat.DATETIME: format_datetime,
+        SchemaFormat.BINARY: binary_type,
+        SchemaFormat.UUID: format_uuid,
+        SchemaFormat.BYTE: format_byte,
+    }
+
+
+class IntegerUnmarshaller(PrimitiveTypeUnmarshaller):
+
+    STRICT_TYPES = integer_types
+    FORMATTERS = {
+        SchemaFormat.NONE: int,
+        SchemaFormat.INT32: int,
+        SchemaFormat.INT64: int,
+    }
+
+
+class NumberUnmarshaller(PrimitiveTypeUnmarshaller):
+
+    STRICT_TYPES = (float, ) + integer_types
+    FORMATTERS = {
+        SchemaFormat.NONE: format_number,
+        SchemaFormat.FLOAT: float,
+        SchemaFormat.DOUBLE: float,
+    }
+
+
+class BooleanUnmarshaller(PrimitiveTypeUnmarshaller):
+
+    STRICT_TYPES = (bool, )
+    FORMATTERS = {
+        SchemaFormat.NONE: forcebool,
+    }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/servers/exceptions.py 
new/openapi-core-0.11.0/openapi_core/schema/servers/exceptions.py
--- old/openapi-core-0.10.0/openapi_core/schema/servers/exceptions.py   
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/servers/exceptions.py   
2019-06-18 23:42:44.000000000 +0200
@@ -1,13 +1,13 @@
-from openapi_core.schema.exceptions import OpenAPIMappingError
-
 import attr
 
+from openapi_core.schema.exceptions import OpenAPIMappingError
+
 
 class OpenAPIServerError(OpenAPIMappingError):
     pass
 
 
-@attr.s
+@attr.s(hash=True)
 class InvalidServer(OpenAPIServerError):
     full_url_pattern = attr.ib()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/schema/specs/models.py 
new/openapi-core-0.11.0/openapi_core/schema/specs/models.py
--- old/openapi-core-0.10.0/openapi_core/schema/specs/models.py 2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/schema/specs/models.py 2019-06-18 
23:42:44.000000000 +0200
@@ -4,6 +4,7 @@
 
 from openapi_core.compat import partialmethod
 from openapi_core.schema.operations.exceptions import InvalidOperation
+from openapi_core.schema.paths.exceptions import InvalidPath
 from openapi_core.schema.servers.exceptions import InvalidServer
 
 
@@ -19,8 +20,8 @@
         self.servers = servers or []
         self.components = components
 
-    def __getitem__(self, path_name):
-        return self.paths[path_name]
+    def __getitem__(self, path_pattern):
+        return self.get_path(path_pattern)
 
     @property
     def default_url(self):
@@ -36,6 +37,12 @@
     def get_server_url(self, index=0):
         return self.servers[index].default_url
 
+    def get_path(self, path_pattern):
+        try:
+            return self.paths[path_pattern]
+        except KeyError:
+            raise InvalidPath(path_pattern)
+
     def get_operation(self, path_pattern, http_method):
         try:
             return self.paths[path_pattern].operations[http_method]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/validation/request/models.py 
new/openapi-core-0.11.0/openapi_core/validation/request/models.py
--- old/openapi-core-0.10.0/openapi_core/validation/request/models.py   
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/validation/request/models.py   
2019-06-18 23:42:44.000000000 +0200
@@ -16,6 +16,16 @@
     def __setitem__(self, location, value):
         raise NotImplementedError
 
+    def __add__(self, other):
+        if not isinstance(other, self.__class__):
+            raise ValueError("Invalid type")
+
+        for location in self.valid_locations:
+            if location in other:
+                self[location].update(other[location])
+
+        return self    
+
     @classmethod
     def validate_location(cls, location):
         if location not in cls.valid_locations:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/openapi_core/validation/request/validators.py 
new/openapi-core-0.11.0/openapi_core/validation/request/validators.py
--- old/openapi-core-0.10.0/openapi_core/validation/request/validators.py       
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/validation/request/validators.py       
2019-06-18 23:42:44.000000000 +0200
@@ -27,17 +27,25 @@
         )
 
         try:
+            path = self.spec[operation_pattern]
+        # don't process if operation errors
+        except OpenAPIMappingError as exc:
+            return RequestValidationResult([exc, ], None, None)
+
+        path_params, path_params_errors = self._get_parameters(request, path)
+
+        try:
             operation = self.spec.get_operation(
                 operation_pattern, request.method)
         # don't process if operation errors
         except OpenAPIMappingError as exc:
             return RequestValidationResult([exc, ], None, None)
 
-        params, params_errors = self._get_parameters(request, operation)
+        op_params, op_params_errors = self._get_parameters(request, operation)
         body, body_errors = self._get_body(request, operation)
 
-        errors = params_errors + body_errors
-        return RequestValidationResult(errors, body, params)
+        errors = path_params_errors + op_params_errors + body_errors
+        return RequestValidationResult(errors, body, path_params + op_params)
 
     def _get_parameters(self, request, operation):
         errors = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/openapi_core/wrappers/flask.py 
new/openapi-core-0.11.0/openapi_core/wrappers/flask.py
--- old/openapi-core-0.10.0/openapi_core/wrappers/flask.py      2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/openapi_core/wrappers/flask.py      2019-06-18 
23:42:44.000000000 +0200
@@ -1,9 +1,16 @@
 """OpenAPI core wrappers module"""
+import re
+
 from openapi_core.wrappers.base import BaseOpenAPIRequest, BaseOpenAPIResponse
 
+# http://flask.pocoo.org/docs/1.0/quickstart/#variable-rules
+PATH_PARAMETER_PATTERN = r'<(?:(?:string|int|float|path|uuid):)?(\w+)>'
+
 
 class FlaskOpenAPIRequest(BaseOpenAPIRequest):
 
+    path_regex = re.compile(PATH_PARAMETER_PATTERN)
+
     def __init__(self, request):
         self.request = request
 
@@ -24,7 +31,7 @@
         if self.request.url_rule is None:
             return self.path
 
-        return self.request.url_rule.rule
+        return self.path_regex.sub(r'{\1}', self.request.url_rule.rule)
 
     @property
     def parameters(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/setup.py 
new/openapi-core-0.11.0/setup.py
--- old/openapi-core-0.10.0/setup.py    2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/setup.py    2019-06-18 23:42:44.000000000 +0200
@@ -74,7 +74,6 @@
         "Topic :: Software Development :: Libraries :: Python Modules",
         "Operating System :: OS Independent",
         'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/integration/data/v3.0/flask_wrapper.yaml 
new/openapi-core-0.11.0/tests/integration/data/v3.0/flask_wrapper.yaml
--- old/openapi-core-0.10.0/tests/integration/data/v3.0/flask_wrapper.yaml      
1970-01-01 01:00:00.000000000 +0100
+++ new/openapi-core-0.11.0/tests/integration/data/v3.0/flask_wrapper.yaml      
2019-06-18 23:42:44.000000000 +0200
@@ -0,0 +1,19 @@
+openapi: "3.0.0"
+info:
+  title: Basic OpenAPI specification used with 
test_wrappers.TestFlaskOpenAPIIValidation
+  version: "0.1"
+servers:
+  - url: 'http://localhost'
+paths:
+  '/browse/{id}/':
+    parameters:
+      - name: id
+        in: path
+        required: true
+        description: the ID of the resource to retrieve
+        schema:
+          type: integer
+    get:
+      responses:
+        default:
+          description: Return the resource.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/integration/test_minimal.py 
new/openapi-core-0.11.0/tests/integration/test_minimal.py
--- old/openapi-core-0.10.0/tests/integration/test_minimal.py   2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/integration/test_minimal.py   2019-06-18 
23:42:44.000000000 +0200
@@ -1,6 +1,7 @@
 import pytest
 
 from openapi_core.schema.operations.exceptions import InvalidOperation
+from openapi_core.schema.paths.exceptions import InvalidPath
 from openapi_core.shortcuts import create_spec
 from openapi_core.validation.request.validators import RequestValidator
 from openapi_core.wrappers.mock import MockRequest
@@ -39,7 +40,7 @@
         spec_dict = factory.spec_from_file(spec_path)
         spec = create_spec(spec_dict)
         validator = RequestValidator(spec)
-        request = MockRequest(server, "get", "/nonexistent")
+        request = MockRequest(server, "post", "/status")
 
         result = validator.validate(request)
 
@@ -47,3 +48,18 @@
         assert isinstance(result.errors[0], InvalidOperation)
         assert result.body is None
         assert result.parameters == {}
+
+    @pytest.mark.parametrize("server", servers)
+    @pytest.mark.parametrize("spec_path", spec_paths)
+    def test_invalid_path(self, factory, server, spec_path):
+        spec_dict = factory.spec_from_file(spec_path)
+        spec = create_spec(spec_dict)
+        validator = RequestValidator(spec)
+        request = MockRequest(server, "get", "/nonexistent")
+
+        result = validator.validate(request)
+
+        assert len(result.errors) == 1
+        assert isinstance(result.errors[0], InvalidPath)
+        assert result.body is None
+        assert result.parameters == {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/integration/test_petstore.py 
new/openapi-core-0.11.0/tests/integration/test_petstore.py
--- old/openapi-core-0.10.0/tests/integration/test_petstore.py  2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/integration/test_petstore.py  2019-06-18 
23:42:44.000000000 +0200
@@ -1,5 +1,6 @@
 import json
 import pytest
+from datetime import datetime
 from base64 import b64encode
 from uuid import UUID
 from six import iteritems, text_type
@@ -19,7 +20,7 @@
 from openapi_core.schema.responses.models import Response
 from openapi_core.schema.schemas.enums import SchemaType
 from openapi_core.schema.schemas.exceptions import (
-    NoValidSchema, InvalidSchemaProperty, InvalidSchemaValue,
+    InvalidSchemaProperty, InvalidSchemaValue,
 )
 from openapi_core.schema.schemas.models import Schema
 from openapi_core.schema.servers.exceptions import InvalidServer
@@ -1213,7 +1214,7 @@
 
         assert parameters == {}
         assert isinstance(body, BaseModel)
-        assert body.created == created
+        assert body.created == datetime(2016, 4, 16, 16, 6, 5)
         assert body.name == pet_name
 
         code = 400
@@ -1257,7 +1258,7 @@
         )
 
         parameters = request.get_parameters(spec)
-        with pytest.raises(NoValidSchema):
+        with pytest.raises(InvalidMediaTypeValue):
             request.get_body(spec)
 
         assert parameters == {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/integration/test_validators.py 
new/openapi-core-0.11.0/tests/integration/test_validators.py
--- old/openapi-core-0.10.0/tests/integration/test_validators.py        
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/integration/test_validators.py        
2019-06-18 23:42:44.000000000 +0200
@@ -9,6 +9,8 @@
 from openapi_core.extensions.models.models import BaseModel
 from openapi_core.schema.operations.exceptions import InvalidOperation
 from openapi_core.schema.parameters.exceptions import MissingRequiredParameter
+from openapi_core.schema.parameters.exceptions import InvalidParameterValue
+from openapi_core.schema.paths.exceptions import InvalidPath
 from openapi_core.schema.request_bodies.exceptions import MissingRequestBody
 from openapi_core.schema.responses.exceptions import (
     MissingResponseContent, InvalidResponse,
@@ -54,12 +56,22 @@
         assert result.body is None
         assert result.parameters == {}
 
-    def test_invalid_operation(self, validator):
+    def test_invalid_path(self, validator):
         request = MockRequest(self.host_url, 'get', '/v1')
 
         result = validator.validate(request)
 
         assert len(result.errors) == 1
+        assert type(result.errors[0]) == InvalidPath
+        assert result.body is None
+        assert result.parameters == {}
+
+    def test_invalid_operation(self, validator):
+        request = MockRequest(self.host_url, 'patch', '/v1/pets')
+
+        result = validator.validate(request)
+
+        assert len(result.errors) == 1
         assert type(result.errors[0]) == InvalidOperation
         assert result.body is None
         assert result.parameters == {}
@@ -220,6 +232,80 @@
         }
 
 
+class TestPathItemParamsValidator(object):
+
+    @pytest.fixture
+    def spec_dict(self, factory):
+        return {
+            "openapi": "3.0.0",
+            "info": {
+                "title": "Test path item parameter validation",
+                "version": "0.1",
+            },
+            "paths": {
+                "/resource": {
+                    "parameters": [
+                        {
+                            "name": "resId",
+                            "in": "query",
+                            "required": True,
+                            "schema": {
+                                "type": "integer",
+                            },
+                        },
+                    ],
+                    "get": {
+                        "responses": {
+                            "default": {
+                                "description": "Return the resource."
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+    @pytest.fixture
+    def spec(self, spec_dict):
+        return create_spec(spec_dict)
+
+    @pytest.fixture
+    def validator(self, spec):
+        return RequestValidator(spec)
+
+    def test_request_missing_param(self, validator):
+        request = MockRequest('http://example.com', 'get', '/resource')
+        result = validator.validate(request)
+
+        assert len(result.errors) == 1
+        assert type(result.errors[0]) == MissingRequiredParameter
+        assert result.body is None
+        assert result.parameters == {}
+
+    def test_request_invalid_param(self, validator):
+        request = MockRequest(
+            'http://example.com', 'get', '/resource',
+            args={'resId': 'invalid'},
+        )
+        result = validator.validate(request)
+
+        assert len(result.errors) == 1
+        assert type(result.errors[0]) == InvalidParameterValue
+        assert result.body is None
+        assert result.parameters == {}
+
+    def test_request_valid_param(self, validator):
+        request = MockRequest(
+            'http://example.com', 'get', '/resource',
+            args={'resId': '10'},
+        )
+        result = validator.validate(request)
+
+        assert len(result.errors) == 0
+        assert result.body is None
+        assert result.parameters == {'query': {'resId': 10}}
+
+
 class TestResponseValidator(object):
 
     host_url = 'http://petstore.swagger.io'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/integration/test_wrappers.py 
new/openapi-core-0.11.0/tests/integration/test_wrappers.py
--- old/openapi-core-0.10.0/tests/integration/test_wrappers.py  2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/integration/test_wrappers.py  2019-06-18 
23:42:44.000000000 +0200
@@ -1,54 +1,61 @@
-import pytest
-
 from flask.wrappers import Request, Response
 from werkzeug.datastructures import EnvironHeaders, ImmutableMultiDict
 from werkzeug.routing import Map, Rule, Subdomain
 from werkzeug.test import create_environ
 
-from openapi_core.wrappers.flask import (
-    FlaskOpenAPIRequest, FlaskOpenAPIResponse,
-)
-
+import pytest
+from openapi_core.shortcuts import create_spec
+from openapi_core.validation.response.validators import ResponseValidator
+from openapi_core.validation.request.validators import RequestValidator
+from openapi_core.wrappers.flask import (FlaskOpenAPIRequest,
+                                         FlaskOpenAPIResponse)
+
+
+@pytest.fixture
+def environ_factory():
+    return create_environ
+
+
+@pytest.fixture
+def map():
+    return Map([
+        # Static URLs
+        Rule('/', endpoint='static/index'),
+        Rule('/about', endpoint='static/about'),
+        Rule('/help', endpoint='static/help'),
+        # Knowledge Base
+        Subdomain('kb', [
+            Rule('/', endpoint='kb/index'),
+            Rule('/browse/', endpoint='kb/browse'),
+            Rule('/browse/<int:id>/', endpoint='kb/browse'),
+            Rule('/browse/<int:id>/<int:page>', endpoint='kb/browse')
+        ])
+    ], default_subdomain='www')
 
-class TestFlaskOpenAPIRequest(object):
 
+@pytest.fixture
+def request_factory(map, environ_factory):
     server_name = 'localhost'
 
-    @pytest.fixture
-    def environ_factory(self):
-        return create_environ
-
-    @pytest.fixture
-    def map(self):
-        return Map([
-            # Static URLs
-            Rule('/', endpoint='static/index'),
-            Rule('/about', endpoint='static/about'),
-            Rule('/help', endpoint='static/help'),
-            # Knowledge Base
-            Subdomain('kb', [
-                Rule('/', endpoint='kb/index'),
-                Rule('/browse/', endpoint='kb/browse'),
-                Rule('/browse/<int:id>/', endpoint='kb/browse'),
-                Rule('/browse/<int:id>/<int:page>', endpoint='kb/browse')
-            ])
-        ], default_subdomain='www')
+    def create_request(method, path, subdomain=None, query_string=None):
+        environ = environ_factory(query_string=query_string)
+        req = Request(environ)
+        urls = map.bind_to_environ(
+            environ, server_name=server_name, subdomain=subdomain)
+        req.url_rule, req.view_args = urls.match(
+            path, method, return_rule=True)
+        return req
+    return create_request
+
+
+@pytest.fixture
+def response_factory():
+    def create_response(data, status_code=200):
+        return Response(data, status=status_code)
+    return create_response
 
-    @pytest.fixture
-    def request_factory(self, map, environ_factory):
-        def create_request(method, path, subdomain=None, query_string=None):
-            environ = environ_factory(query_string=query_string)
-            req = Request(environ)
-            urls = map.bind_to_environ(
-                environ, server_name=self.server_name, subdomain=subdomain)
-            req.url_rule, req.view_args = urls.match(
-                path, method, return_rule=True)
-            return req
-        return create_request
 
-    @pytest.fixture
-    def openapi_request(self, request):
-        return FlaskOpenAPIRequest(request)
+class TestFlaskOpenAPIRequest(object):
 
     def test_simple(self, request_factory, request):
         request = request_factory('GET', '/', subdomain='www')
@@ -115,19 +122,13 @@
         assert openapi_request.host_url == request.host_url
         assert openapi_request.path == request.path
         assert openapi_request.method == request.method.lower()
-        assert openapi_request.path_pattern == request.url_rule.rule
+        assert openapi_request.path_pattern == '/browse/{id}/'
         assert openapi_request.body == request.data
         assert openapi_request.mimetype == request.mimetype
 
 
 class TestFlaskOpenAPIResponse(object):
 
-    @pytest.fixture
-    def response_factory(self):
-        def create_response(data, status_code=200):
-            return Response(data, status=status_code)
-        return create_response
-
     def test_invalid_server(self, response_factory):
         response = response_factory('Not Found', status_code=404)
 
@@ -137,3 +138,30 @@
         assert openapi_response.data == response.data
         assert openapi_response.status_code == response._status_code
         assert openapi_response.mimetype == response.mimetype
+
+
+class TestFlaskOpenAPIValidation(object):
+
+    @pytest.fixture
+    def flask_spec(self, factory):
+        specfile = 'data/v3.0/flask_wrapper.yaml'
+        return create_spec(factory.spec_from_file(specfile))
+
+    def test_response_validator_path_pattern(self,
+                                             flask_spec,
+                                             request_factory,
+                                             response_factory):
+        validator = ResponseValidator(flask_spec)
+        request = request_factory('GET', '/browse/12/', subdomain='kb')
+        openapi_request = FlaskOpenAPIRequest(request)
+        response = response_factory('Some item', status_code=200)
+        openapi_response = FlaskOpenAPIResponse(response)
+        result = validator.validate(openapi_request, openapi_response)
+        assert not result.errors
+
+    def test_request_validator_path_pattern(self, flask_spec, request_factory):
+        validator = RequestValidator(flask_spec)
+        request = request_factory('GET', '/browse/12/', subdomain='kb')
+        openapi_request = FlaskOpenAPIRequest(request)
+        result = validator.validate(openapi_request)
+        assert not result.errors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/tests/unit/schema/test_links.py 
new/openapi-core-0.11.0/tests/unit/schema/test_links.py
--- old/openapi-core-0.10.0/tests/unit/schema/test_links.py     2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/unit/schema/test_links.py     2019-06-18 
23:42:44.000000000 +0200
@@ -40,5 +40,5 @@
     @pytest.mark.parametrize("request_body", request_body_list)
     def test_iteritems(self, link_factory, request_body, server):
         link = link_factory(request_body, server)
-        for par_name in link.parameters.keys():
+        for par_name in link.parameters:
             assert link[par_name] == link.parameters[par_name]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/unit/schema/test_operations.py 
new/openapi-core-0.11.0/tests/unit/schema/test_operations.py
--- old/openapi-core-0.10.0/tests/unit/schema/test_operations.py        
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/unit/schema/test_operations.py        
2019-06-18 23:42:44.000000000 +0200
@@ -15,7 +15,7 @@
         return Operation('get', '/path', {}, parameters=parameters)
 
     def test_iteritems(self, operation):
-        for name in operation.parameters.keys():
+        for name in operation.parameters:
             assert operation[name] == operation.parameters[name]
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/tests/unit/schema/test_paths.py 
new/openapi-core-0.11.0/tests/unit/schema/test_paths.py
--- old/openapi-core-0.10.0/tests/unit/schema/test_paths.py     2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/unit/schema/test_paths.py     2019-06-18 
23:42:44.000000000 +0200
@@ -16,6 +16,6 @@
 
     @property
     def test_iteritems(self, path):
-        for http_method in path.operations.keys():
+        for http_method in path.operations:
             assert path[http_method] ==\
                 path.operations[http_method]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/unit/schema/test_request_bodies.py 
new/openapi-core-0.11.0/tests/unit/schema/test_request_bodies.py
--- old/openapi-core-0.10.0/tests/unit/schema/test_request_bodies.py    
2019-05-21 14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/unit/schema/test_request_bodies.py    
2019-06-18 23:42:44.000000000 +0200
@@ -16,6 +16,6 @@
 
     @property
     def test_iteritems(self, request_body):
-        for mimetype in request_body.content.keys():
+        for mimetype in request_body.content:
             assert request_body[mimetype] ==\
                 request_body.content[mimetype]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openapi-core-0.10.0/tests/unit/schema/test_schemas.py 
new/openapi-core-0.11.0/tests/unit/schema/test_schemas.py
--- old/openapi-core-0.10.0/tests/unit/schema/test_schemas.py   2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/unit/schema/test_schemas.py   2019-06-18 
23:42:44.000000000 +0200
@@ -27,7 +27,7 @@
 
     @property
     def test_valid(self, schema):
-        for name in schema.properties.keys():
+        for name in schema.properties:
             assert schema[name] == schema.properties[name]
 
 
@@ -300,6 +300,33 @@
 
         assert result == 1.2
 
+    def test_schema_any_one_of(self):
+        schema = Schema(one_of=[
+            Schema('string'),
+            Schema('array', items=Schema('string')),
+        ])
+        assert schema.unmarshal(['hello']) == ['hello']
+
+    def test_schema_any_one_of_mutiple(self):
+        schema = Schema(one_of=[
+            Schema('array', items=Schema('string')),
+            Schema('array', items=Schema('number')),
+        ])
+        with pytest.raises(MultipleOneOfSchema):
+            schema.unmarshal([])
+
+    def test_schema_any_one_of_no_valid(self):
+        schema = Schema(one_of=[
+            Schema('array', items=Schema('string')),
+            Schema('array', items=Schema('number')),
+        ])
+        with pytest.raises(NoOneOfSchema):
+            schema.unmarshal({})
+
+    def test_schema_any(self):
+        schema = Schema()
+        assert schema.unmarshal('string') == 'string'
+
 
 class TestSchemaValidate(object):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openapi-core-0.10.0/tests/unit/schema/test_specs.py 
new/openapi-core-0.11.0/tests/unit/schema/test_specs.py
--- old/openapi-core-0.10.0/tests/unit/schema/test_specs.py     2019-05-21 
14:21:42.000000000 +0200
+++ new/openapi-core-0.11.0/tests/unit/schema/test_specs.py     2019-06-18 
23:42:44.000000000 +0200
@@ -32,7 +32,7 @@
         return Spec(servers, paths)
 
     def test_iteritems(self, spec):
-        for path_name in spec.paths.keys():
+        for path_name in spec.paths:
             assert spec[path_name] ==\
                 spec.paths[path_name]
 


Reply via email to