diff --git a/setup.cfg b/setup.cfg
index 009dd13..4c54795 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -27,7 +27,7 @@ packages =
zope-stubs
package_dir = =src
install_requires =
- mypy==0.981
+ mypy==1.0.0
zope.interface
zope.schema
include_package_data = True
diff --git a/src/mypy_zope/plugin.py b/src/mypy_zope/plugin.py
index 46bdc1b..02ab413 100644
--- a/src/mypy_zope/plugin.py
+++ b/src/mypy_zope/plugin.py
@@ -96,6 +96,9 @@ def make_simple_type(
}
+HACK_IS_ABSTRACT_NON_PROPAGATING = -12345678
+
+
class ZopeInterfacePlugin(Plugin):
def __init__(self, options: Options):
super().__init__(options)
@@ -520,6 +523,27 @@ def _adjust_interface_function(
func_def.arg_kinds.insert(0, ARG_POS)
func_def.arguments.insert(0, selfarg)
+ # 1: We want mypy to consider this method abstract, so that it allows the
+ # method to have an empty body without causing a warning.
+ # 2: We want mypy to consider the interface class NOT abstract, so we can use the
+ # "adaption" pattern.
+ # Unfortunately whenever mypy sees (1) it will mark the class as abstract,
+ # forcing (2) to be false. This seems to be a change in mypy 0.990, namely
+ # https://github.com/python/mypy/pull/13729
+ #
+ # Mypy 1.0.0:
+ # - allows empty bodies for abstract methods in mypy/checker.py:1240
+ # by testing if
+ # abstract_status != NOT_ABSTRACT.
+ # - marks classes as abstract based on their methods in
+ # mypy/semanal_classprop.py:79 by testing if
+ # abstract_status in (IS_ABSTRACT, IMPLICITLY_ABSTRACT)
+ #
+ # Thus we can make (1) and (2) true by setting abstract_status to some value
+ # distinct from these three NOT_ABSTRACT, IS_ABSTRACT and IMPLICITLY_ABSTRACT.
+ # These are presently the integers 0, 1, and 2 defined in mypy/nodes.py:738-743.
+ func_def.abstract_status = HACK_IS_ABSTRACT_NON_PROPAGATING
+
return func_def
def _adjust_interface_overload(
diff --git a/tests/samples/contextmanager.py b/tests/samples/contextmanager.py
index ec6af36..cc6183b 100644
--- a/tests/samples/contextmanager.py
+++ b/tests/samples/contextmanager.py
@@ -9,7 +9,7 @@ class A(Generic[_T]):
@contextmanager
def m(x: _T) -> Iterator[A[_T]]:
- ...
+ return iter([A()])
with m(7) as x:
diff --git a/tests/samples/interface_meta.py b/tests/samples/interface_meta.py
index 2e04617..2f02c1f 100644
--- a/tests/samples/interface_meta.py
+++ b/tests/samples/interface_meta.py
@@ -5,9 +5,7 @@
class IBookmark(zope.interface.Interface):
- @staticmethod
- def create(url: str) -> 'IBookmark':
- pass
+ pass
def createOb(iface: Type[T]) -> T:
if zope.interface.interfaces.IInterface.providedBy(iface):
@@ -20,6 +18,6 @@ def main(self) -> None:
"""
-"""
\ No newline at end of file
+"""
diff --git a/tests/samples/interface_unknown_inherit.py b/tests/samples/interface_unknown_inherit.py
index 8cc0768..2e13e6c 100644
--- a/tests/samples/interface_unknown_inherit.py
+++ b/tests/samples/interface_unknown_inherit.py
@@ -20,7 +20,7 @@ class Bookmark(object):
diff --git a/tests/samples/overload_readme.py b/tests/samples/overload_readme.py
index acc0834..bcf8939 100644
--- a/tests/samples/overload_readme.py
+++ b/tests/samples/overload_readme.py
@@ -14,7 +14,7 @@ def say() -> str:
def say(count: int) -> List[str]:
...
- def say(count: int = None) -> Union[str, List[str]]:
+ def say(count: Optional[int] = None) -> Union[str, List[str]]:
pass
@@ -28,7 +28,7 @@ def say(self) -> str:
def say(self, count: int) -> List[str]:
...
- def say(self, count: int = None) -> Union[str, List[str]]:
+ def say(self, count: Optional[int] = None) -> Union[str, List[str]]:
if count is None:
return "Mooo"
return ["Mooo"] * count
diff --git a/tests/test_samples.py b/tests/test_samples.py
index b929ce0..f853009 100644
--- a/tests/test_samples.py
+++ b/tests/test_samples.py
@@ -25,6 +25,7 @@ def test_samples(samplefile, mypy_cache_dir):
opts.cache_dir = mypy_cache_dir
opts.show_traceback = True
opts.namespace_packages = True
+ opts.hide_error_codes = True
opts.plugins = ['mypy_zope:plugin']
# Config file is needed to load plugins, it doesn't not exist and is not
# supposed to.