Repository: samuelcolvin/pydantic (python)

Issue:
Frozen dataclass behavior change 1.6.1 -> 1.7
### 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())"`:
```
$ python -c "import pydantic.utils; print(pydantic.utils.version_info())"
             pydantic version: 1.7
            pydantic compiled: True
                 install path: /home/user/miniconda3/envs/debug_pydantic/lib/python3.8/site-packages/pydantic
               python version: 3.8.2 (default, May  7 2020, 20:00:49)  [GCC 7.3.0]
                     platform: Linux-5.4.0-52-generic-x86_64-with-glibc2.10
     optional deps. installed: []
```
<!-- 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: -->

This code works in v1.6.1:
```py
from dataclasses import dataclass

from pydantic import BaseModel


@dataclass(frozen=True)
class Item:
    name: str


class Example(BaseModel):
    item: Item

    class Config:
        arbitrary_types_allowed = True
```

However, in v1.7, it produces the following error:
```py
Traceback (most recent call last):
  File "/home/user/debug_pydantic.py", line 11, in <module>
    class Example(BaseModel):
  File "pydantic/main.py", line 262, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 315, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 284, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 362, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 538, in pydantic.fields.ModelField.populate_validators
  File "pydantic/validators.py", line 596, in find_validators
  File "pydantic/dataclasses.py", line 222, in make_dataclass_validator
    # and only from the field() function, although Field instances are
  File "pydantic/dataclasses.py", line 214, in pydantic.dataclasses.dataclass
    type_name = self.type.__name__
  File "pydantic/dataclasses.py", line 209, in pydantic.dataclasses.dataclass.wrap
    def __init__(self, type):
  File "pydantic/dataclasses.py", line 126, in pydantic.dataclasses._process_class
    # +=======+=======+=======+========+========+
  File "/home/user/miniconda3/envs/debug_pydantic/lib/python3.8/dataclasses.py", line 1019, in dataclass
    return wrap(cls)
  File "/home/user/miniconda3/envs/debug_pydantic/lib/python3.8/dataclasses.py", line 1011, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
  File "/home/user/miniconda3/envs/debug_pydantic/lib/python3.8/dataclasses.py", line 891, in _process_class
    raise TypeError('cannot inherit non-frozen dataclass from a '
TypeError: cannot inherit non-frozen dataclass from a frozen one
```

Looking through the changelog, this does not appear to be an intentional change. I can remove the `frozen=True` attribute of the dataclass decorator as a workaround, but this seems less than ideal.

Pull request:
fix: forward all the params of the stdlib `dataclass` when converted into _pydantic_ `dataclass`
## Change Summary
When converting (automatically or not) a stdlib `dataclass` into a _pydantic_ `dataclass`, we
forward only the `Config` instance but not all the params used to created the initial `dataclass.
Now we do!

## Related issue number
closes #2065

## Checklist

* [x] Unit tests for the changes exist
* [x] Tests pass on CI and coverage remains at 100%
* [x] Documentation reflects the changes where applicable
* [x] `changes/<pull request or issue id>-<github username>.md` file added describing change
  (see [changes/README.md](https://github.com/samuelcolvin/pydantic/blob/master/changes/README.md) for details)


Patch:
diff --git a/changes/2065-PrettyWood.md b/changes/2065-PrettyWood.md
new file mode 100644
index 000000000..8a5643f83
--- /dev/null
+++ b/changes/2065-PrettyWood.md
@@ -0,0 +1,1 @@
+fix: forward all the params of the stdlib `dataclass` when converted into _pydantic_ `dataclass`
\ No newline at end of file
diff --git a/docs/examples/dataclasses_stdlib_with_basemodel.py b/docs/examples/dataclasses_stdlib_with_basemodel.py
index 35ff1e883..92b494891 100644
--- a/docs/examples/dataclasses_stdlib_with_basemodel.py
+++ b/docs/examples/dataclasses_stdlib_with_basemodel.py
@@ -5,14 +5,20 @@ from typing import Optional
 from pydantic import BaseModel, ValidationError
 
 
+@dataclasses.dataclass(frozen=True)
+class User:
+    name: str
+
+
 @dataclasses.dataclass
 class File:
     filename: str
-    last_modification_time: Optional[datetime]
+    last_modification_time: Optional[datetime] = None
 
 
 class Foo(BaseModel):
     file: File
+    user: Optional[User] = None
 
 
 file = File(
@@ -25,3 +31,9 @@ try:
     Foo(file=file)
 except ValidationError as e:
     print(e)
+
+foo = Foo(file=File(filename='myfile'), user=User(name='pika'))
+try:
+    foo.user.name = 'bulbi'
+except dataclasses.FrozenInstanceError as e:
+    print(e)
diff --git a/docs/usage/dataclasses.md b/docs/usage/dataclasses.md
index 54dbcbbf3..536d91205 100644
--- a/docs/usage/dataclasses.md
+++ b/docs/usage/dataclasses.md
@@ -71,8 +71,9 @@ _(This script is complete, it should run "as is")_
 
 ### Use of stdlib dataclasses with `BaseModel`
 
-Bear in mind that stdlib dataclasses (nested or not) are **automatically converted** into _pydantic_ dataclasses
-when mixed with `BaseModel`!
+Bear in mind that stdlib dataclasses (nested or not) are **automatically converted** into _pydantic_
+dataclasses when mixed with `BaseModel`! Furthermore the generated _pydantic_ dataclass will have
+the **exact same configuration** (`order`, `frozen`, ...) as the original one.
 
 ```py
 {!.tmp_examples/dataclasses_stdlib_with_basemodel.py!}
diff --git a/docs/usage/settings.md b/docs/usage/settings.md
index a06ea52d4..9f9c50580 100644
--- a/docs/usage/settings.md
+++ b/docs/usage/settings.md
@@ -135,7 +135,7 @@ Placing secret values in files is a common pattern to provide sensitive configur
 A secret file follows the same principal as a dotenv file except it only contains a single value and the file name 
 is used as the key. A secret file will look like the following:
 
-`/var/run/db_password`:
+`/var/run/database_password`:
 ```
 super_secret_database_password
 ```
diff --git a/pydantic/dataclasses.py b/pydantic/dataclasses.py
index 28e2f9509..0d28e1b20 100644
--- a/pydantic/dataclasses.py
+++ b/pydantic/dataclasses.py
@@ -220,6 +220,9 @@ def make_dataclass_validator(_cls: Type[Any], config: Type['BaseConfig']) -> 'Ca
     """
     Create a pydantic.dataclass from a builtin dataclass to add type validation
     and yield the validators
+    It retrieves the parameters of the dataclass and forwards them to the newly created dataclass
     """
-    cls = dataclass(_cls, config=config)
+    dataclass_params = _cls.__dataclass_params__
+    stdlib_dataclass_parameters = {param: getattr(dataclass_params, param) for param in dataclass_params.__slots__}
+    cls = dataclass(_cls, config=config, **stdlib_dataclass_parameters)
     yield from _get_validators(cls)


Test patch:
diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py
index 061b73d09..e213ff567 100644
--- a/tests/test_dataclasses.py
+++ b/tests/test_dataclasses.py
@@ -777,3 +777,21 @@ def test_dataclass_arbitrary():
             arbitrary_types_allowed = True
 
     TestModel(a=ArbitraryType(), b=(ArbitraryType(), [ArbitraryType()]))
+
+
+def test_forward_stdlib_dataclass_params():
+    @dataclasses.dataclass(frozen=True)
+    class Item:
+        name: str
+
+    class Example(BaseModel):
+        item: Item
+        other: str
+
+        class Config:
+            arbitrary_types_allowed = True
+
+    e = Example(item=Item(name='pika'), other='bulbi')
+    e.other = 'bulbi2'
+    with pytest.raises(dataclasses.FrozenInstanceError):
+        e.item.name = 'pika2'