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

Cannot create consistent method ordering when creating a class with multiple inheritance from the typing module #361

Closed
chrisnorman7 opened this issue Sep 11, 2020 · 12 comments
Labels
bug Something isn't working fixed in next version (main) A fix has been implemented and will appear in an upcoming version

Comments

@chrisnorman7
Copy link

Environment data

  • Language Server version: 2020.9.4
  • OS and version: Microsoft Windows [Version 10.0.19041.508]
  • Python version (& distribution if applicable, e.g. Anaconda): Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32

Expected behaviour

I should be able to create a class with multiple inheritance, and Pylance should be able to figure everything out.

Actual behaviour

I get the following error:

{
	"resource": "/c:/Users/chris/src/breaking/breaking.py",
	"owner": "_generated_diagnostic_collection_name_#0",
	"severity": 8,
	"message": "Cannot create consistent method ordering",
	"source": "Pylance",
	"startLineNumber": 6,
	"startColumn": 7,
	"endLineNumber": 6,
	"endColumn": 8
}

Logs

[Info  - 15:28:11] Pylance language server 2020.9.4 (pyright 9983747f) starting
[Info  - 15:28:11] Server root directory: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist
[Error - 15:28:11] stubPath typings is not a valid directory.
[Info  - 15:38:50] No configuration file found.
[Info  - 15:38:50] Setting pythonPath for service "breaking": "c:\Users\chris\src\breaking\env\Scripts\python.exe"
[Error - 15:38:50] stubPath typings is not a valid directory.
[Info  - 15:38:51] Assuming Python version 3.8
[Info  - 15:38:51] Assuming Python platform Windows
[Info  - 15:38:51] Searching for source files
[Info  - 15:38:51] Auto-excluding c:\Users\chris\src\breaking\env
[Info  - 15:38:51] Found 1 source file
Background analysis message: setConfigOptions
Background analysis message: setTrackedFiles
Background analysis message: markAllFilesDirty
Background analysis message: analyze
Background analysis message: setFileOpened
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
[FG] parsing: c:\Users\chris\src\breaking\breaking.py (18ms)
[FG] parsing: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\2and3\builtins.pyi (1239ms)
[FG] binding: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\2and3\builtins.pyi (105ms)
[FG] binding: c:\Users\chris\src\breaking\breaking.py (5ms)
Background analysis message: analyze
[BG(1)] analyzing: c:\Users\chris\src\breaking\breaking.py ...
[BG(1)]   parsing: c:\Users\chris\src\breaking\breaking.py (16ms)
[BG(1)]   parsing: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\2and3\builtins.pyi (96ms)
[BG(1)]   binding: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\2and3\builtins.pyi (39ms)
[BG(1)]   binding: c:\Users\chris\src\breaking\breaking.py (0ms)
[BG(1)]   checking: c:\Users\chris\src\breaking\breaking.py ...
[BG(1)]     parsing: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\3\typing.pyi (32ms)
[BG(1)]     binding: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\3\typing.pyi (9ms)
[BG(1)]     parsing: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\3\abc.pyi (5ms)
[BG(1)]     binding: c:\Users\chris\.vscode\extensions\ms-python.vscode-pylance-2020.9.4\dist\typeshed-fallback\stdlib\3\abc.pyi (0ms)
[BG(1)]   checking: c:\Users\chris\src\breaking\breaking.py (85ms)
[BG(1)] analyzing: c:\Users\chris\src\breaking\breaking.py (236ms)
Background analysis message: getSemanticTokens
Background analysis message: getSemanticTokens
Background analysis message: resumeAnalysis
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: setFileOpened
Background analysis message: markFilesDirty
Background analysis message: getSemanticTokens
[BG(1)] parsing: c:\Users\chris\src\breaking\breaking.py (1ms)
[BG(1)] binding: c:\Users\chris\src\breaking\breaking.py (1ms)
Background analysis message: analyze
[BG(1)] analyzing: c:\Users\chris\src\breaking\breaking.py ...
[BG(1)]   checking: c:\Users\chris\src\breaking\breaking.py (13ms)
[BG(1)] analyzing: c:\Users\chris\src\breaking\breaking.py (13ms)
Background analysis message: resumeAnalysis
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: markFilesDirty
Background analysis message: analyze
[FG] parsing: c:\Users\chris\src\breaking\breaking.py (3ms)
[FG] binding: c:\Users\chris\src\breaking\breaking.py (1ms)
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: setFileOpened
Background analysis message: markFilesDirty
Background analysis message: getSemanticTokens
[BG(1)] parsing: c:\Users\chris\src\breaking\breaking.py (0ms)
[BG(1)] binding: c:\Users\chris\src\breaking\breaking.py (1ms)
Background analysis message: analyze
[BG(1)] analyzing: c:\Users\chris\src\breaking\breaking.py ...
[BG(1)]   checking: c:\Users\chris\src\breaking\breaking.py (46ms)
[BG(1)] analyzing: c:\Users\chris\src\breaking\breaking.py (46ms)
Background analysis message: resumeAnalysis
Background analysis message: markFilesDirty
Background analysis message: analyze
[FG] parsing: c:\Users\chris\src\breaking\breaking.py (4ms)
[FG] binding: c:\Users\chris\src\breaking\breaking.py (0ms)
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange

Code Snippet / Additional information

from typing import Generic, Iterator, Mapping, TypeVar

T = TypeVar('T')


class B(Generic[T], Mapping[str, T]):
    pass

    def __len__(self) -> int:
        return 0

    def __getitem__(self, k: str) -> T:
        return NotImplemented

    def __iter__(self) -> Iterator[str]:
        return iter([])

I created the above code in a clean virtualenv, with no extra packages installed.

@erictraut
Copy link
Contributor

Thanks for the report. The standard Python rules for constructing an MRO (method resolution ordering) would normally indicate that a proper MRO cannot be created in this case because Mapping derives from Generic. However, the Python interpreter isn't complaining in this case, so I presume that the Generic class is special-cased. There is nothing in the spec that indicates this, but empirical evidence would indicate as such. I can add this special-case handling to Pylance/Pyright to match the behavior of the interpreter.

As a workaround in the meantime, you can simply delete Generic[T] from your list of base classes. Generic[T] is unnecessary in this case because Mapping[str, T] already introduces the type variable T for your class B.

class B(Mapping[str, T]): ...

PEP 484 say:

The Generic[T] base class is redundant in simple cases where you subclass some other generic class and specify type variables for its parameters.

@erictraut erictraut added the bug Something isn't working label Sep 11, 2020
@github-actions github-actions bot removed the triage label Sep 11, 2020
@chrisnorman7
Copy link
Author

Brilliant, thank you. I didn't know that.

@erictraut
Copy link
Contributor

I'm going to keep this open for now because there's a bug that I'd still like to address.

@erictraut erictraut reopened this Sep 11, 2020
@erictraut
Copy link
Contributor

The incorrect error will be addressed in the next release of Pylance. Thanks again for reporting the problem.

@erictraut erictraut added the fixed in next version (main) A fix has been implemented and will appear in an upcoming version label Sep 12, 2020
@CatNofishing
Copy link

@erictraut Hello, can you solve this problem, no one responded😂,Two weeks have passed. #301

@erictraut
Copy link
Contributor

I responded four days ago saying that the problem was fixed, and the fix will be included in the next release of Pylance. We typically release Pylance Wed or Thurs of each week.

@chrisnorman7
Copy link
Author

chrisnorman7 commented Sep 16, 2020 via email

@jakebailey
Copy link
Member

This issue has been fixed in version 2020.9.5, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/master/CHANGELOG.md#202095-16-september-2020

@levrik
Copy link

levrik commented Oct 13, 2020

@jakebailey I've just did a first-time install of Pylance (2020.10.0) and hitting exactly this issue.
Was there some regression?

@jakebailey
Copy link
Member

This is a month old issue that should be fixed (and we typically add regression tests for these sorts of issues). If you see something again please file a new issue with a reproduction so we can track it. Thanks.

@lonelygo
Copy link

lonelygo commented Dec 5, 2020

This is a month old issue that should be fixed (and we typically add regression tests for these sorts of issues). If you see something again please file a new issue with a reproduction so we can track it. Thanks.

pylance : 2020.12.0
mac vscode : 1.51.1
Still get this error

@erictraut
Copy link
Contributor

@lonelygo, can you provide sample code for a repro?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed in next version (main) A fix has been implemented and will appear in an upcoming version
Projects
None yet
Development

No branches or pull requests

7 participants