Repository: pydantic/pydantic (Python)

Issue:
Dataclass schema regression in 1.9.0
### Checks

* [x] I added a descriptive title to this issue
* [x] I have searched (google, github) for similar issues and couldn't find anything
* [x] I have read and followed [the docs](https://pydantic-docs.helpmanual.io/) and still think this is a bug

# Bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.9.0
            pydantic compiled: True
                 install path: venv/lib/python3.10/site-packages/pydantic
               python version: 3.10.0 (default, Oct  9 2021, 15:30:15) [Clang 13.0.0 (clang-1300.0.29.3)]
                     platform: macOS-11.6-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']
```
The following errors, (with Pydantic 1.9.0)
```python
from pydantic.dataclasses import dataclass as pydantic_dataclass
from pydantic.schema import model_schema 
from typing import List
from dataclasses import dataclass

@dataclass
class Rule:
    name: str

@dataclass
class RuleData:
    rule: List[Rule]

model_schema(pydantic_dataclass(RuleData))
```
The error is,
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pydantic/schema.py", line 185, in pydantic.schema.model_schema
  File "pydantic/schema.py", line 617, in pydantic.schema.model_process_schema
  File "pydantic/schema.py", line 658, in pydantic.schema.model_type_schema
  File "pydantic/schema.py", line 258, in pydantic.schema.field_schema
  File "pydantic/schema.py", line 498, in pydantic.schema.field_type_schema
  File "pydantic/schema.py", line 848, in pydantic.schema.field_singleton_schema
  File "pydantic/schema.py", line 736, in pydantic.schema.field_singleton_sub_fields_schema
  File "pydantic/schema.py", line 563, in pydantic.schema.field_type_schema
  File "pydantic/schema.py", line 947, in pydantic.schema.field_singleton_schema
ValueError: Value not declarable with JSON Schema, field: name='_rule' type=Rule required=True
```

Whereas with Pydantic 1.8 the output is as expected, i.e.
```
{'title': 'RuleData', 'type': 'object', 'properties': {'rule': {'title': 'Rule', 'type': 'array', 'items': {'$ref': '#/definitions/Rule'}}}, 'required': ['rule'], 'definitions': {'Rule': {'title': 'Rule', 'type': 'object', 'properties': {'name': {'title': 'Name', 'type': 'string'}}, 'required': ['name']}}}
```
list of python dataclass broken after upgrade to 1.9.0
### Checks

* [x] I added a descriptive title to this issue
* [x] I have searched (google, github) for similar issues and couldn't find anything
* [x] I have read and followed [the docs](https://pydantic-docs.helpmanual.io/) and still think this is a bug

<!-- Sorry to sound so draconian, but every second saved replying to issues is time spend improving pydantic :-) -->

# Bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
            pydantic version: 1.9.0
            pydantic compiled: True
                 install path: my_directory/venv/lib/python3.8/site-packages/pydantic
               python version: 3.8.6 (default, Sep  6 2021, 17:04:40)  [GCC 10.3.0]
                     platform: Linux-5.13.0-28-generic-x86_64-with-glibc2.33
     optional deps. installed: ['typing-extensions']
```
<!-- or if you're using pydantic prior to v1.3, manually include: OS, python version and pydantic version -->

<!-- Please read the [docs](https://pydantic-docs.helpmanual.io/) and search through issues to
confirm your bug hasn't already been reported. -->

<!-- Where possible please include a self-contained code snippet describing your bug: -->

The following snippet works as expected with version 1.8.2 but errors with version 1.9.0

```py
from dataclasses import dataclass
from typing import List
import pydantic


@dataclass()
class A:
    a: int = 5


@dataclass()
class B_and_As:
    list_of_as: List[A]
    b: str = 'b'


def get_schema(json_cls: dataclass):
    as_pydantic = pydantic.dataclasses.dataclass(json_cls)
    schema = as_pydantic.__pydantic_model__.schema()
    print(schema)


get_schema(B_and_As)
```

error:
```
    schema = as_pydantic.__pydantic_model__.schema()
  File "pydantic/main.py", line 647, in pydantic.main.BaseModel.schema
  File "pydantic/schema.py", line 185, in pydantic.schema.model_schema
  File "pydantic/schema.py", line 617, in pydantic.schema.model_process_schema
  File "pydantic/schema.py", line 658, in pydantic.schema.model_type_schema
  File "pydantic/schema.py", line 258, in pydantic.schema.field_schema
  File "pydantic/schema.py", line 498, in pydantic.schema.field_type_schema
  File "pydantic/schema.py", line 848, in pydantic.schema.field_singleton_schema
  File "pydantic/schema.py", line 736, in pydantic.schema.field_singleton_sub_fields_schema
  File "pydantic/schema.py", line 563, in pydantic.schema.field_type_schema
  File "pydantic/schema.py", line 947, in pydantic.schema.field_singleton_schema
ValueError: Value not declarable with JSON Schema, field: name='_list_of_as' type=A required=True
```

on 1.8.2 it's prints as expected:
```
{'title': 'B_and_As', 'type': 'object', 'properties': {'list_of_as': {'title': 'List Of As', 'type': 'array', 'items': {'$ref': '#/definitions/A'}}, 'b': {'title': 'B', 'default': 'b', 'type': 'string'}}, 'required': ['list_of_as'], 'definitions': {'A': {'title': 'A', 'type': 'object', 'properties': {'a': {'title': 'A', 'default': 5, 'type': 'integer'}}}}}
```


Btw:
* `get_schema(A)` works in both versions
* [Discussed on stackoverflow](https://stackoverflow.com/questions/71048746/how-can-i-generate-json-schema-for-list-of-dataclass-with-pydantic)


Discussion:
Hi @pgjones 
Bug introduced by https://github.com/samuelcolvin/pydantic/pull/2364. Fix welcome
@PrettyWood, I have contributed a fix here:  #3819
When the Pull Request of this Issue will be merged?

Duplicate of #3658 
thanks, did not see that one, sorry.

This one also fixes the problem for me https://github.com/samuelcolvin/pydantic/pull/2557



Patch:
diff --git a/changes/3819-himbeles.md b/changes/3819-himbeles.md
new file mode 100644
index 00000000000..7845d7b0f93
--- /dev/null
+++ b/changes/3819-himbeles.md
@@ -0,0 +1,1 @@
+Fix nested Python dataclass schema regression in version 1.9
diff --git a/pydantic/schema.py b/pydantic/schema.py
index e979678c229..b608d54b76b 100644
--- a/pydantic/schema.py
+++ b/pydantic/schema.py
@@ -419,10 +419,13 @@ def get_flat_models_from_field(field: ModelField, known_models: TypeModelSet) ->
     # Handle dataclass-based models
     if is_builtin_dataclass(field.type_):
         field.type_ = dataclass(field.type_)
+        was_dataclass = True
+    else:
+        was_dataclass = False
     field_type = field.type_
     if lenient_issubclass(getattr(field_type, '__pydantic_model__', None), BaseModel):
         field_type = field_type.__pydantic_model__
-    if field.sub_fields and not lenient_issubclass(field_type, BaseModel):
+    if field.sub_fields and (not lenient_issubclass(field_type, BaseModel) or was_dataclass):
         flat_models |= get_flat_models_from_fields(field.sub_fields, known_models=known_models)
     elif lenient_issubclass(field_type, BaseModel) and field_type not in known_models:
         flat_models |= get_flat_models_from_model(field_type, known_models=known_models)


Test patch:
diff --git a/tests/test_schema.py b/tests/test_schema.py
index ea0290f09e1..90e6469e66e 100644
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -2884,3 +2884,34 @@ class Model(BaseModel):
             },
         },
     }
+
+
+def test_nested_python_dataclasses():
+    """
+    Test schema generation for nested python dataclasses
+    """
+
+    from dataclasses import dataclass as python_dataclass
+
+    @python_dataclass
+    class ChildModel:
+        name: str
+
+    @python_dataclass
+    class NestedModel:
+        child: List[ChildModel]
+
+    assert model_schema(dataclass(NestedModel)) == {
+        'title': 'NestedModel',
+        'type': 'object',
+        'properties': {'child': {'title': 'Child', 'type': 'array', 'items': {'$ref': '#/definitions/ChildModel'}}},
+        'required': ['child'],
+        'definitions': {
+            'ChildModel': {
+                'title': 'ChildModel',
+                'type': 'object',
+                'properties': {'name': {'title': 'Name', 'type': 'string'}},
+                'required': ['name'],
+            }
+        },
+    }