Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stubgen removes Protocol from base classes list #12072

Closed
citruz opened this issue Jan 25, 2022 · 1 comment · Fixed by #12129
Closed

stubgen removes Protocol from base classes list #12072

citruz opened this issue Jan 25, 2022 · 1 comment · Fixed by #12129
Labels
bug mypy got something wrong topic-stubgen

Comments

@citruz
Copy link
Contributor

citruz commented Jan 25, 2022

Bug Report

Consider the following input:

from typing import Protocol

class Interface(Protocol):
    def dummy(self, arg: str) -> str:
        ...

stubgen produces:

class Interface:
    def dummy(self, arg: str) -> str: ...

Note that the Protocol class is removed from the list of base classes.

Obviously this causes problems when performing type checking against users of that generated typestub:

from interface import Interface

class InterfaceImpl:
    def dummy(self, arg: str) -> str:
        return arg


interf: Interface = InterfaceImpl()

mypy:

provider/__init__.py:8: error: Incompatible types in assignment (expression has type "InterfaceImpl", variable has type "Interface")

Expected Behavior

Protocol base class is not removed.

Actual Behavior

Protocol base class is removed.

Your Environment

  • Mypy version used: mypy 0.931
  • Python version used: Python 3.9.7
  • Operating system and version: macOS
@citruz citruz added the bug mypy got something wrong label Jan 25, 2022
@citruz
Copy link
Contributor Author

citruz commented Jan 25, 2022

This works as a fix:

diff --git a/mypy/stubgen.py b/mypy/stubgen.py
index b0a2c4e64..4e1a0fe08 100755
--- a/mypy/stubgen.py
+++ b/mypy/stubgen.py
@@ -849,6 +849,9 @@ class StubGenerator(mypy.traverser.TraverserVisitor):
             base_types.append('metaclass=abc.ABCMeta')
             self.import_tracker.add_import('abc')
             self.import_tracker.require_name('abc')
+        elif self.analyzed and o.info.is_protocol:
+            base_types.append('Protocol')
+            self.add_typing_import('Protocol')
         if base_types:
             self.add('(%s)' % ', '.join(base_types))
         self.add(':\n')

If you think this is the way to go, I can submit it as a PR.

JelleZijlstra pushed a commit that referenced this issue Mar 18, 2022
### Description

This PR fixes #12072 by correctly handling `Protocol` definitions. Previously, the `Protocol` base class was removed when generating type stubs which causes problems with other packages that want to use type definition (because they see it as a regular class, not as a `Protocol`).

## Test Plan

Added a testcase to the stubgen testset.

Co-authored-by: 97littleleaf11 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-stubgen
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants