Repository: python-openapi/openapi-spec-validator (language: python)

Issue:
writeOnly with default doesn't work in 0.6.0
Good day! I use OpenAPI 3.0.0 schema and it stopped working with properties that have `writeOnly` and `default` at the same time.

A simple code snippet:

```
import json
from openapi_spec_validator import validate_spec

data = json.loads('''{
  "openapi": "3.0.0",
  "info": {
    "version": "1.0.0",
    "title": ""
  },
  "servers": [],
  "paths": {
    "/pets": {
      "post": {
        "summary": "Create a pet",
        "tags": [],
        "responses": {
          "201": {
            "description": "Null response"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Pet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "readOnly": true
          },
          "write_only": {
            "type": "string",
            "writeOnly": true,
            "default": "hello"
          }
        }
      }
    }
  }
}''')

validate_spec(data)
```

The error:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.10/site-packages/openapi_spec_validator/shortcuts.py", line 19, in validate_spec
    return validator.validate(spec, base_uri=base_uri, spec_url=spec_url)
  File "/usr/local/lib/python3.10/site-packages/openapi_spec_validator/validation/proxies.py", line 34, in validate
    raise err
openapi_spec_validator.validation.exceptions.OpenAPIValidationError: Tried to read write-only property with hello

Failed validating 'writeOnly' in schema:
    {'default': 'hello', 'type': 'string', 'writeOnly': True}

On instance:
    'hello'
```

As I understood the root cause is here https://github.com/python-openapi/openapi-schema-validator/pull/85

As a workaround, I made a custom validator that uses `OAS30WriteValidator`:

```
from functools import partial
from jsonschema.validators import Draft4Validator
from openapi_spec_validator.schemas import schema_v30
from lazy_object_proxy import Proxy
from openapi_spec_validator.validation.validators import SpecValidator
from openapi_schema_validator import oas30_format_checker
from jsonschema_spec.handlers import default_handlers
from openapi_schema_validator.validators import OAS30WriteValidator

get_openapi_v30_schema_validator = partial(Draft4Validator, schema_v30)
openapi_v30_schema_validator = Proxy(get_openapi_v30_schema_validator)
get_openapi_v30_spec_validator = partial(
    SpecValidator,
    openapi_v30_schema_validator,
    OAS30WriteValidator,
    oas30_format_checker,
    resolver_handlers=default_handlers,
)
openapi_v30_spec_validator = Proxy(get_openapi_v30_spec_validator)

validate_spec(data, validator=openapi_v30_spec_validator)
```

Shouldn't it be replaced in `openapi-spec-validator`?





Discussion / hints:
I think I'm experiencing the same thing with `readOnly`, getting a failure on a simple `{"default": "foo", "readOnly": True}` when trying to validate my generated OpenAPI data.

I'm having trouble following the code -- this library is the most sophisticated user of `jsonschema` I have seen -- but I think the relevant bit must be where a `default` is checked against the schema?
(https://github.com/python-openapi/openapi-spec-validator/blob/b0d96b6b9d94b99978a5db4beb9f586026151124/openapi_spec_validator/validation/validators.py#L336)

Is it reasonable to make it possible to opt-out of this check? I can imagine other cases in which someone wants to specify a default of `"foo"`, but users are only allowed to provide enumerated values of `["bar", "baz"]`, so checking the default will always fail. (Is such a thing forbidden by OpenAPI? It's definitely not forbidden by JSON Schema.)
I believe the issue is in default value validation that we shouldn't consider other keywords, including writeonly/readonly.

Based on OpenAPI 3.0, schema type should be the only keyword to be considered here.

> The default value represents what would be assumed by the consumer of the input as the value of the schema if one is not provided. Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object defined at the same level. For example, if type is string, then default can be "foo" but cannot be 1.


Fix patch:
diff --git a/poetry.lock b/poetry.lock
index 590b2d2..06fa17d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -579,13 +579,13 @@ i18n = ["Babel (>=2.7)"]
 
 [[package]]
 name = "jsonschema"
-version = "4.19.0"
+version = "4.19.1"
 description = "An implementation of JSON Schema validation for Python"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"},
-    {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"},
+    {file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"},
+    {file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"},
 ]
 
 [package.dependencies]
@@ -830,17 +830,17 @@ setuptools = "*"
 
 [[package]]
 name = "openapi-schema-validator"
-version = "0.6.0"
+version = "0.6.2"
 description = "OpenAPI schema validation for Python"
 optional = false
 python-versions = ">=3.8.0,<4.0.0"
 files = [
-    {file = "openapi_schema_validator-0.6.0-py3-none-any.whl", hash = "sha256:9e95b95b621efec5936245025df0d6a7ffacd1551e91d09196b3053040c931d7"},
-    {file = "openapi_schema_validator-0.6.0.tar.gz", hash = "sha256:921b7c1144b856ca3813e41ecff98a4050f7611824dfc5c6ead7072636af0520"},
+    {file = "openapi_schema_validator-0.6.2-py3-none-any.whl", hash = "sha256:c4887c1347c669eb7cded9090f4438b710845cd0f90d1fb9e1b3303fb37339f8"},
+    {file = "openapi_schema_validator-0.6.2.tar.gz", hash = "sha256:11a95c9c9017912964e3e5f2545a5b11c3814880681fcacfb73b1759bb4f2804"},
 ]
 
 [package.dependencies]
-jsonschema = ">=4.18.0,<5.0.0"
+jsonschema = ">=4.19.1,<5.0.0"
 jsonschema-specifications = ">=2023.5.2,<2024.0.0"
 rfc3339-validator = "*"
 


Test patch:
diff --git a/tests/integration/data/v3.0/read-only-write-only.yaml b/tests/integration/data/v3.0/read-only-write-only.yaml
new file mode 100644
index 0000000..9af8465
--- /dev/null
+++ b/tests/integration/data/v3.0/read-only-write-only.yaml
@@ -0,0 +1,42 @@
+openapi: "3.0.0"
+info:
+  title: Specification Containing readOnly
+  version: "0.1"
+paths:
+  /users:
+    post:
+        operationId: createUser
+        requestBody:
+          description: Post data for creating a user
+          required: true
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+        responses:
+          default:
+            description: Create a user
+            content:
+              application/json:
+                schema:
+                  $ref: '#/components/schemas/User'
+components:
+  schemas:
+    User:
+      x-model: User
+      type: object
+      required:
+        - id
+        - name
+      properties:
+        id:
+          type: integer
+          format: int32
+          readOnly: true
+          default: 1
+        name:
+          type: string
+        hidden:
+          type: boolean
+          writeOnly: true
+          default: true
\ No newline at end of file
diff --git a/tests/integration/validation/test_validators.py b/tests/integration/validation/test_validators.py
index 5eacfd2..aef830b 100644
--- a/tests/integration/validation/test_validators.py
+++ b/tests/integration/validation/test_validators.py
@@ -65,6 +65,7 @@ def local_test_suite_file_path(self, test_file):
             "petstore-separate/spec/openapi.yaml",
             "parent-reference/openapi.yaml",
             "property-recursive.yaml",
+            "read-only-write-only.yaml",
         ],
     )
     def test_valid(self, factory, validator_v30, spec_file):