Repository: marshmallow-code/apispec

Issue:
`Dict()` should resolve to `{"type": "object", "additionalProperties": {}}`
`Dict` will output the schema of the `values` field as `additionalProperties`, you can see that in the example below with `Dict(values=Integer)` -> `additionalProperties: {type: integer}` and `Dict(values=Raw)` -> `additionalProperties: {}` (OpenAPI's "any" type).

To my understanding, leaving `values` to its default of `None` will allow any value input, and is effectively the same as `Dict(values=Raw())`.  So it would make more sense to output the same schema (`additionalProperties: {}`), but instead it omits `additionalProperties` entirely.  This means only an empty object complies with the spec, which is obviously not the desired behavior of `Dict()`.

```python
from apispec import APISpec

from apispec.ext.marshmallow import MarshmallowPlugin
from marshmallow import Schema, fields

spec = APISpec(
    title="Test",
    version="1.0.0",
    openapi_version="3.0.2",
    plugins=[MarshmallowPlugin()],
)


class TestSchema(Schema):
    id = fields.Int()
    plain = fields.Dict()
    raw = fields.Dict(values=fields.Raw)
    integer = fields.Dict(values=fields.Integer)


spec.components.schema("Test", schema=TestSchema)
print(spec.to_yaml())
```

Gives

```
paths: {}
info:
  title: Test
  version: 1.0.0
openapi: 3.0.2
components:
  schemas:
    Test:
      type: object
      properties:
        id:
          type: integer
        plain:
          type: object
        raw:
          type: object
          additionalProperties: {}
        integer:
          type: object
          additionalProperties:
            type: integer
```

Discussion:

Patch:
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 16fb499..2d5ed60 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -83,3 +83,4 @@ Contributors (chronological)
 - Tobias Kolditz `@kolditz-senec <https://github.com/kolditz-senec>`_
 - Christian Proud `@cjproud <https://github.com/cjproud>`_
 - `<https://github.com/kolditz-senec >`_
+- Theron Luhn `@luhn <https://github.com/luhn>`_
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 291c3d4..178eca3 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,6 +4,11 @@ Changelog
 6.7.0 (unreleased)
 ******************
 
+Bug fixes:
+
+- Fix handling of ``fields.Dict()`` with ``values`` unset (:issue:`949`).
+  Thanks :user:`luhn` for the catch and patch.
+
 Other changes:
 
 - Officially support Python 3.13 (:pr:`948`).
diff --git a/src/apispec/ext/marshmallow/field_converter.py b/src/apispec/ext/marshmallow/field_converter.py
index 4e17aa2..a284f9b 100644
--- a/src/apispec/ext/marshmallow/field_converter.py
+++ b/src/apispec/ext/marshmallow/field_converter.py
@@ -504,6 +504,8 @@ class FieldConverterMixin:
             value_field = field.value_field
             if value_field:
                 ret["additionalProperties"] = self.field2property(value_field)
+            else:
+                ret["additionalProperties"] = {}
         return ret
 
     def timedelta2properties(self, field, **kwargs: typing.Any) -> dict:


Test patch:
diff --git a/tests/test_ext_marshmallow.py b/tests/test_ext_marshmallow.py
index fa1cfe7..0b863f4 100644
--- a/tests/test_ext_marshmallow.py
+++ b/tests/test_ext_marshmallow.py
@@ -1294,7 +1294,7 @@ class TestDictValues:
 
         spec.components.schema("SchemaWithDict", schema=SchemaWithDict)
         result = get_schemas(spec)["SchemaWithDict"]["properties"]["dict_field"]
-        assert result == {"type": "object"}
+        assert result == {"type": "object", "additionalProperties": {}}
 
     def test_dict_with_nested(self, spec):
         class SchemaWithDict(Schema):