Repository: pydantic/pydantic

Issue:
Overriding default value makes __fields__ inconsistent with __annotations__ 
# Bug

Please complete:
* OS: **OSX**
* Python version `import sys; print(sys.version)`: **3.7.3 | packaged by conda-forge | (default, Jul  1 2019, 14:38:56)**
* Pydantic version `import pydantic; print(pydantic.VERSION)`: **0.32.1**

**Please read the [docs](https://pydantic-docs.helpmanual.io/) and search through issues to
confirm your bug hasn't already been reported before.**

Where possible please include a self contained code snippet describing your bug:

```py
from pydantic import BaseModel


class A(BaseModel):
    value: int = 1
        
        
class B(A):
    value = 'G'


print(A.__annotations__, A.__fields__)
# ({'value': int}, {'value': <Field(value type=int default=1)>})

print(A.__annotations__, A.__fields__)
# ({'value': int}, {'value': <Field(value type=str default='G')>})
```

The film type should be int in both cases. [`__annotations__`](https://github.com/samuelcolvin/pydantic/blob/master/pydantic/main.py#L181) is empty in the metaclass so a type will be [inferred](https://github.com/samuelcolvin/pydantic/blob/master/pydantic/fields.py#L169) for the field even [without a type hint](https://github.com/samuelcolvin/pydantic/blob/master/pydantic/main.py#L202).

A solution would be to take the parents' annotations into consideration as well, or to introduce another config option to prevent inferring the type of the default value as the type hint for the field. I'm not sure how would the former one affect the rest of the features.


Comments:
I think I’ve noticed this before with slightly different resulting issues but thought it might just be a limitation of python. Thanks for breaking this down.

I think there doesn’t need to be a config value, parent annotations should probably just be used if they exist; if you want to override you should probably just have to do it explicitly. I’m not sure if this would be hard to implement though.

Patch:
diff --git a/pydantic/main.py b/pydantic/main.py
--- a/pydantic/main.py
+++ b/pydantic/main.py
@@ -151,7 +151,7 @@ def validate_custom_root_type(fields: Dict[str, Field]) -> None:
 
 
 class MetaModel(ABCMeta):
-    @no_type_check
+    @no_type_check  # noqa C901
     def __new__(mcs, name, bases, namespace):
         fields: Dict[str, Field] = {}
         config = BaseConfig
@@ -205,13 +205,19 @@ def __new__(mcs, name, bases, namespace):
                     and var_name not in class_vars
                 ):
                     validate_field_name(bases, var_name)
-                    fields[var_name] = Field.infer(
+                    inferred = Field.infer(
                         name=var_name,
                         value=value,
                         annotation=annotations.get(var_name),
                         class_validators=vg.get_validators(var_name),
                         config=config,
                     )
+                    if var_name in fields and inferred.type_ != fields[var_name].type_:
+                        raise TypeError(
+                            f'The type of {name}.{var_name} differs from the new default value; '
+                            f'if you wish to change the type of this field, please use a type annotation'
+                        )
+                    fields[var_name] = inferred
 
         _custom_root_type = '__root__' in fields
         if _custom_root_type:


Test patch:
diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py
--- a/tests/test_edge_cases.py
+++ b/tests/test_edge_cases.py
@@ -527,9 +527,9 @@ class Foo(BaseModel):
 
     class Bar(Foo):
         x: float = 12.3
-        a = 123
+        a = 123.0
 
-    assert Bar().dict() == {'x': 12.3, 'a': 123}
+    assert Bar().dict() == {'x': 12.3, 'a': 123.0}
 
 
 def test_invalid_type():
@@ -615,6 +615,33 @@ class Config:
     assert str(m) == "Child a=1 b='s'"
 
 
+def test_annotation_inheritance():
+    class A(BaseModel):
+        integer: int = 1
+
+    class B(A):
+        integer = 2
+
+    assert B.__annotations__['integer'] == int
+    assert B.__fields__['integer'].type_ == int
+
+    class C(A):
+        integer: str = 'G'
+
+    assert C.__annotations__['integer'] == str
+    assert C.__fields__['integer'].type_ == str
+
+    with pytest.raises(TypeError) as exc_info:
+
+        class D(A):
+            integer = 'G'
+
+    assert str(exc_info.value) == (
+        'The type of D.integer differs from the new default value; '
+        'if you wish to change the type of this field, please use a type annotation'
+    )
+
+
 def test_string_none():
     class Model(BaseModel):
         a: constr(min_length=20, max_length=1000) = ...