Repository: marshmallow-code/apispec

Issue:
Marshmallow OpenApiConverter does not support str openapi_version 
The [mashmallow ext documentation](https://apispec.readthedocs.io/en/latest/api_ext.html#apispec.ext.marshmallow.openapi.OpenAPIConverter) says 
```
openapi_version (Version) – The OpenAPI version to use. Should be in the form ‘2.x’ or ‘3.x.x’ to comply with the OpenAPI standard.
```
but in [APISpec](https://apispec.readthedocs.io/en/latest/api_core.html#module-apispec.core) str is supported which leads to confusion:
```
openapi_version (str) – OpenAPI Specification version. Should be in the form ‘2.x’ or ‘3.x.x’ to comply with the OpenAPI standard.
```

This commit has removed the conversion from str to version instance in marshmallow ext:
https://github.com/marshmallow-code/apispec/commit/d9e7ef9e1225a4d9f1169caba6c7c1235afe8ecd#diff-d2965e63925ff25611aef4a29719e18095c4a035c9a855e65d4d8ea7908298b8L54-L60

which when using str version leads to errors like `AttributeError: 'str' object has no attribute 'major'` here https://github.com/marshmallow-code/apispec/blob/dev/src/apispec/ext/marshmallow/openapi.py#L191 in version 6.0.1

Is it the desired behavior?
Thanks



Discussion:

Patch:
diff --git a/src/apispec/ext/marshmallow/openapi.py b/src/apispec/ext/marshmallow/openapi.py
index 011af55..6d6fcb5 100644
--- a/src/apispec/ext/marshmallow/openapi.py
+++ b/src/apispec/ext/marshmallow/openapi.py
@@ -40,7 +40,7 @@ __location_map__ = {
 class OpenAPIConverter(FieldConverterMixin):
     """Adds methods for generating OpenAPI specification from marshmallow schemas and fields.
 
-    :param Version openapi_version: The OpenAPI version to use.
+    :param Version|str openapi_version: The OpenAPI version to use.
         Should be in the form '2.x' or '3.x.x' to comply with the OpenAPI standard.
     :param callable schema_name_resolver: Callable to generate the schema definition name.
         Receives the `Schema` class and returns the name to be used in refs within
@@ -52,11 +52,15 @@ class OpenAPIConverter(FieldConverterMixin):
 
     def __init__(
         self,
-        openapi_version: Version,
+        openapi_version: Version | str,
         schema_name_resolver,
         spec: APISpec,
     ) -> None:
-        self.openapi_version = openapi_version
+        self.openapi_version = (
+            Version(openapi_version)
+            if isinstance(openapi_version, str)
+            else openapi_version
+        )
         self.schema_name_resolver = schema_name_resolver
         self.spec = spec
         self.init_attribute_functions()


Test patch:
diff --git a/tests/test_ext_marshmallow_openapi.py b/tests/test_ext_marshmallow_openapi.py
index 46824f3..fc27626 100644
--- a/tests/test_ext_marshmallow_openapi.py
+++ b/tests/test_ext_marshmallow_openapi.py
@@ -4,8 +4,9 @@ import pytest
 
 from marshmallow import EXCLUDE, fields, INCLUDE, RAISE, Schema, validate
 
-from apispec.ext.marshmallow import MarshmallowPlugin
+from apispec.ext.marshmallow import MarshmallowPlugin, OpenAPIConverter
 from apispec import exceptions, APISpec
+from packaging.version import Version
 
 from .schemas import CustomList, CustomStringField
 from .utils import get_schemas, build_ref, validate_spec
@@ -608,6 +609,15 @@ def test_openapi_tools_validate_v3():
         pytest.fail(str(error))
 
 
+def test_openapi_converter_openapi_version_types():
+    converter_with_version = OpenAPIConverter(Version("3.1"), None, None)
+    converter_with_str_version = OpenAPIConverter("3.1", None, None)
+    assert (
+        converter_with_version.openapi_version
+        == converter_with_str_version.openapi_version
+    )
+
+
 class TestFieldValidation:
     class ValidationSchema(Schema):
         id = fields.Int(dump_only=True)