Repository: pydantic/pydantic

Issue:
sub-model cannot always re-write field infos from the same BaseModel.
### Checks

* [-] I added a descriptive title to this issue
* [-] I have searched (google, github) for similar issues and couldn't find anything
* [-] 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: /home/zuobinhua/anaconda3/lib/python3.7/site-packages/pydantic
               python version: 3.7.6 (default, Jan  8 2020, 19:59:22)  [GCC 7.3.0]
                     platform: Linux-4.15.0-159-generic-x86_64-with-debian-buster-sid
     optional deps. installed: ['email-validator', 'typing-extensions']
```
When creating two sub models(A, B) from Pydantic BaseModel, with fields infos defined in Config. Then creating another two sub models(Model1, Model2) from A and B, trying to rewrite the extra keys (we used `level` in the following code) in field info. Only one of the sub models can re-write the extra value correctly. 
As shown in the following code, `extra` in m2.__fields__["root"].field_info got level=3, but for m1 it still got level=1.

```py
from typing import Optional
from pydantic import BaseModel
from pydantic import Field


class A(BaseModel):
    root: Optional[str]
    class Config:
        fields = {
            "root": {"description": "root path of data", "level": 1},
        }

class B(BaseModel):
    root: Optional[str]
    class Config:
        field = {
            "root": {"description": "root path of data", "level": 1},
        }

class Model1(A):
    root: str = Field("asa", description="image height", level=3)

class Model2(B):
    root: str = Field("asa", description="image height", level=3)

m1 = Model1()
print(m1.__fields__["root"].field_info)
# default='asa' description='image height' extra={'level': 1}

m2 = Model2()
print(m2.__fields__["root"].field_info)
# default='asa' description='image height' extra={'level': 3}

```



Discussion:
You wrote `Config.field` for model B instead of `Config.fields` hence the difference.
Now you're right the output is not the expected one. I'll open a fix shortly

Resolving patch:
diff --git a/pydantic/fields.py b/pydantic/fields.py
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -199,7 +199,8 @@ def update_from_config(self, from_config: Dict[str, Any]) -> None:
                 current_value = getattr(self, attr_name)
             except AttributeError:
                 # attr_name is not an attribute of FieldInfo, it should therefore be added to extra
-                self.extra[attr_name] = value
+                # (except if extra already has this value!)
+                self.extra.setdefault(attr_name, value)
             else:
                 if current_value is self.__field_constraints__.get(attr_name, None):
                     setattr(self, attr_name, value)


Test patch:
diff --git a/tests/test_schema.py b/tests/test_schema.py
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -3001,3 +3001,27 @@ class Model(BaseModel):
             },
         },
     }
+
+
+def test_extra_inheritance():
+    class A(BaseModel):
+        root: Optional[str]
+
+        class Config:
+            fields = {
+                'root': {'description': 'root path of data', 'level': 1},
+            }
+
+    class Model(A):
+        root: str = Field('asa', description='image height', level=3)
+
+    m = Model()
+    assert m.schema()['properties'] == {
+        'root': {
+            'title': 'Root',
+            'type': 'string',
+            'description': 'image height',
+            'default': 'asa',
+            'level': 3,
+        }
+    }