Repository: pydantic/pydantic

Issue:
Mypy regression - Missing named argument
### Initial Checks

- [X] I have searched GitHub for a duplicate issue and I'm sure this is something new
- [X] I have searched Google & StackOverflow for a solution and couldn't find anything
- [X] I have read and followed [the docs](https://docs.pydantic.dev) and still think this is a bug
- [X] I am confident that the issue is with pydantic (not my code, or another library in the ecosystem like [FastAPI](https://fastapi.tiangolo.com) or [mypy](https://mypy.readthedocs.io/en/stable))


### Description

pydantic version 1.10.6 + mypy 1.1.1 + mypy plugin causes error with previously ok code.
Note: mypy plugin is irrelevant, and does not affect the output in this usecase

Using Field with a description on an optional Field, without an explicit default=None, used to work

```
$ mypy sample.py 
sample.py:10: error: Missing named argument "bar" for "Sample"  [call-arg]
Found 1 error in 1 file (checked 1 source file)
```
Error started happening with pydantic 1.10.4, version 1.10.2 does not have this issue
versions >1.10.2 now require the explicit default=None on Optional fields.

This seems like a bug, if not please advise.


### Example Code

```Python
from typing import Optional
from pydantic import BaseModel, Field


class Sample(BaseModel):
    foo: str
    bar: Optional[str] = Field(description="optional")


Sample(foo="hello world")
```


### Python, Pydantic & OS Version

```Text
pydantic version: 1.10.6
            pydantic compiled: True
                 install path: /home/hatem/projects/inventory_service/venv/lib/python3.8/site-packages/pydantic
               python version: 3.8.10 (default, Sep 28 2021, 16:10:42)  [GCC 9.3.0]
                     platform: Linux-5.11.0-37-generic-x86_64-with-glibc2.29
     optional deps. installed: ['dotenv', 'typing-extensions']
```


### Affected Components

- [X] [Compatibility between releases](https://docs.pydantic.dev/changelog/)
- [ ] [Data validation/parsing](https://docs.pydantic.dev/usage/models/#basic-model-usage)
- [ ] [Data serialization](https://docs.pydantic.dev/usage/exporting_models/) - `.dict()` and `.json()`
- [ ] [JSON Schema](https://docs.pydantic.dev/usage/schema/)
- [ ] [Dataclasses](https://docs.pydantic.dev/usage/dataclasses/)
- [ ] [Model Config](https://docs.pydantic.dev/usage/model_config/)
- [ ] [Field Types](https://docs.pydantic.dev/usage/types/) - adding or changing a particular data type
- [ ] [Function validation decorator](https://docs.pydantic.dev/usage/validation_decorator/)
- [ ] [Generic Models](https://docs.pydantic.dev/usage/models/#generic-models)
- [ ] [Other Model behaviour](https://docs.pydantic.dev/usage/models/) - `construct()`, pickling, private attributes, ORM mode
- [X] [Plugins](https://docs.pydantic.dev/) and integration with other tools - mypy, FastAPI, python-devtools, Hypothesis, VS Code, PyCharm, etc.


Discussion:
see #5192
This appears to have been introduced by using `@dataclass_transform` on the metaclass, and the reason that it works in 1.10.2 is because that version used the keyword argument `field_descriptors` instead of the correct `field_specifiers`.

I'm not sure how involved it will be to fix this properly while retaining the `@dataclass_transform` behavior; the good news is that in v2 this shouldn't be an issue because we no longer set an implicit default for Optional/Any fields.

Does anyone know why the keyword argument was `field_descriptors` before? Was that just a typo?
Seems there was some logic issues in the plugin that meant it wouldn't work correctly if you set a `Field` as the default but didn't specify `default` or `default_factory`. The `dataclass_transform` thing was just hiding the issue. I've got a fix coming shortly.

Resolving patch:
diff --git a/pydantic/mypy.py b/pydantic/mypy.py
--- a/pydantic/mypy.py
+++ b/pydantic/mypy.py
@@ -53,6 +53,7 @@
     Instance,
     NoneType,
     Overloaded,
+    ProperType,
     Type,
     TypeOfAny,
     TypeType,
@@ -573,10 +574,7 @@ def get_is_required(cls: ClassDef, stmt: AssignmentStmt, lhs: NameExpr) -> bool:
         if isinstance(expr, TempNode):
             # TempNode means annotation-only, so only non-required if Optional
             value_type = get_proper_type(cls.info[lhs.name].type)
-            if isinstance(value_type, UnionType) and any(isinstance(item, NoneType) for item in value_type.items):
-                # Annotated as Optional, or otherwise having NoneType in the union
-                return False
-            return True
+            return not PydanticModelTransformer.type_has_implicit_default(value_type)
         if isinstance(expr, CallExpr) and isinstance(expr.callee, RefExpr) and expr.callee.fullname == FIELD_FULLNAME:
             # The "default value" is a call to `Field`; at this point, the field is
             # only required if default is Ellipsis (i.e., `field_name: Annotation = Field(...)`) or if default_factory
@@ -587,10 +585,29 @@ def get_is_required(cls: ClassDef, stmt: AssignmentStmt, lhs: NameExpr) -> bool:
                     return arg.__class__ is EllipsisExpr
                 if name == 'default_factory':
                     return False
-            return True
+            # In this case, default and default_factory are not specified, so we need to look at the annotation
+            value_type = get_proper_type(cls.info[lhs.name].type)
+            return not PydanticModelTransformer.type_has_implicit_default(value_type)
         # Only required if the "default value" is Ellipsis (i.e., `field_name: Annotation = ...`)
         return isinstance(expr, EllipsisExpr)
 
+    @staticmethod
+    def type_has_implicit_default(type_: Optional[ProperType]) -> bool:
+        """
+        Returns True if the passed type will be given an implicit default value.
+
+        In pydantic v1, this is the case for Optional types and Any (with default value None).
+        """
+        if isinstance(type_, AnyType):
+            # Annotated as Any
+            return True
+        if isinstance(type_, UnionType) and any(
+            isinstance(item, NoneType) or isinstance(item, AnyType) for item in type_.items
+        ):
+            # Annotated as Optional, or otherwise having NoneType or AnyType in the union
+            return True
+        return False
+
     @staticmethod
     def get_alias_info(stmt: AssignmentStmt) -> Tuple[Optional[str], bool]:
         """


Test patch:
diff --git a/tests/mypy/modules/plugin_success.py b/tests/mypy/modules/plugin_success.py
--- a/tests/mypy/modules/plugin_success.py
+++ b/tests/mypy/modules/plugin_success.py
@@ -1,4 +1,4 @@
-from typing import ClassVar, Generic, List, Optional, TypeVar, Union
+from typing import Any, ClassVar, Generic, List, Optional, TypeVar, Union
 
 from pydantic import BaseModel, BaseSettings, Field, create_model, validator
 from pydantic.dataclasses import dataclass
@@ -253,3 +253,12 @@ def from_orm_optional(cls, model: Optional[_TModel]) -> Optional[_TType]:
         if model is None:
             return None
         return cls.from_orm(model)
+
+
+class Sample(BaseModel):
+    foo: str
+    bar: Optional[str] = Field(description='optional')
+    zoo: Any
+
+
+Sample(foo='hello world')