Repository: Shoobx/mypy-zope

Issue:
Caching error (Metaclass conflict) with mypy 0.991
Hi. With the latest version of mypy (0.991) and mypy-zope (0.3.11) we're getting mypy errors that I think are cache related. The error goes away after `rm -rf .mypy_cache`

Here's the easiest repro I could make:

iface.py
```
from zope.interface import Interface
from zope.interface import implementer

class ISomething(Interface):
    pass

class ISomething2(Interface):
    pass

@implementer(ISomething)
class OneInterface:
    pass

@implementer(ISomething, ISomething2)
class TwoInterfaces:
    pass
```

foo.py
```
from iface import OneInterface, TwoInterfaces

class Good(OneInterface):
    pass

class Bad(TwoInterfaces):
    pass
```

I am able to reliably hit the problem by running the following commands:
```
$ rm -rf .mypy_cache
$ mypy iface.py 
Success: no issues found in 1 source file
$ mypy foo.py 
foo.py:6: error: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases  [misc]
Found 1 error in 1 file (checked 1 source file)
```

As you can tell this only happens when there are multiple interfaces.


Discussion:

Patch:
diff --git a/src/mypy_zope/plugin.py b/src/mypy_zope/plugin.py
index 46bdc1b..0c7971e 100644
--- a/src/mypy_zope/plugin.py
+++ b/src/mypy_zope/plugin.py
@@ -698,7 +698,10 @@ class ZopeInterfacePlugin(Plugin):
         if not any(promote in ti._promote for ti in impl.mro):
             faketi = TypeInfo(SymbolTable(), iface.defn, iface.module_name)
             faketi._promote = [promote]
-            impl.mro.append(faketi)
+            faketi.metaclass_type = iface.metaclass_type
+            # Insert the TypeInfo before the builtins.object that's at the end.
+            assert impl.mro[-1].fullname == 'builtins.object'
+            impl.mro.insert(len(impl.mro) - 1, faketi)
 
 
 def plugin(version: str) -> PyType[Plugin]:


Test patch:
diff --git a/tests/test_mro_calculation.py b/tests/test_mro_calculation.py
index a051dcc..eb9cf5d 100644
--- a/tests/test_mro_calculation.py
+++ b/tests/test_mro_calculation.py
@@ -59,10 +59,10 @@ def test_mro_computation_in_forward_reference_to_implementer(mypy_cache_dir: str
     mro: List[TypeInfo] = node.node.mro
     # Expected: [
     #   <TypeInfo forward_reference_to_implementer.Protocol@21>,
-    #   <TypeInfo builtins.object>,
     #   <TypeInfo forward_reference_to_implementer.IProtocol>,
+    #   <TypeInfo builtins.object>,
     # ]
     assert len(mro) == 3
     assert mro[0].fullname.startswith(f"{sample_name}.Protocol")
-    assert mro[1].fullname == "builtins.object"
-    assert mro[2].fullname == f"{sample_name}.IProtocol"
+    assert mro[1].fullname == f"{sample_name}.IProtocol"
+    assert mro[2].fullname == "builtins.object"