Skip to content

Various improvements to stubgen #7921

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

Merged
merged 51 commits into from
Nov 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
aa0673f
Stubgen: Remove misplaced type comments before parsing
JukkaL Apr 11, 2019
ae33876
stubgen: Don't fail if docstring cannot be tokenized
JukkaL Apr 11, 2019
80108d3
stubgen: Handle None value for __file__
JukkaL Apr 12, 2019
37a1ab9
stubgen: Fix None-related crash
JukkaL Apr 12, 2019
020b11f
stubgen: Attempt to fix namespace packages
JukkaL Apr 12, 2019
e1de866
stubgen: Add --verbose and --quiet flags
JukkaL Apr 12, 2019
4473075
stubgen: Use __init__.pyi for C modules when needed
JukkaL Apr 12, 2019
3a0986d
stubgen: If we can't import a module, give more information
JukkaL Apr 12, 2019
049a2a4
stubgen: Work around crash
JukkaL Apr 12, 2019
bbf6268
stubgen: Don't fail if a class has a cyclic MRO
JukkaL Apr 12, 2019
a3ebf3c
stubgen: Log runtime imports in verbose mode
JukkaL Apr 12, 2019
a3a35fe
stubgen: More verbose output
JukkaL Apr 12, 2019
e287301
stubgen: Skip certain special cased packages
JukkaL Apr 12, 2019
819a77d
stubgen: Filter out additional things that look like type comments
JukkaL Apr 12, 2019
02d4184
stubgen: Survive inconsistent MROs
JukkaL Apr 12, 2019
67142d6
stubgen: Remove message when there are only C modules
JukkaL Apr 12, 2019
bc3ca08
Fix rebase issue
JukkaL Nov 4, 2019
b1814d9
Fix after rebase
JukkaL Nov 4, 2019
6f4a1fe
Add missing stuff
JukkaL Nov 4, 2019
25e3258
Fix signatures generated by stubgen for various dunder C methods
JukkaL Apr 10, 2019
c9d2987
Add missing line
JukkaL Nov 4, 2019
8777b5f
Ignore unreachable code in stubgen to avoid crashes
JukkaL Apr 9, 2019
5ccd902
Fix C dunder method inference tests
JukkaL Nov 4, 2019
09f1b13
Preserve @abstractproperty in stubgen
JukkaL Apr 10, 2019
a9721ed
Stubgen: Avoid name clashes between typing.Any and class Any etc.
JukkaL Apr 10, 2019
6cefdc4
Stubgen: special case certain names to be exported
JukkaL Apr 10, 2019
95ab57c
Fix None errors
JukkaL Nov 4, 2019
156fe17
Add some docstrings and comments to stubgen tests
JukkaL Apr 10, 2019
9b802e3
Stubgen: Generate exports for imported names that aren't referenced
JukkaL Apr 10, 2019
d7b2942
Stubgen: allow special casing internal definitions to be exported
JukkaL Apr 10, 2019
b739314
Stubgen: translate imports from vendored six to use real six
JukkaL Apr 10, 2019
add4a64
Stubgen: Remove generated header
JukkaL Apr 10, 2019
8da487d
Add unit tests for skipping blacklisted and test modules
JukkaL May 10, 2019
376513d
Add docstring
JukkaL Nov 4, 2019
41a1f22
Add test case for vendored package
JukkaL Nov 4, 2019
b6db629
Fix lint
JukkaL Nov 11, 2019
c6aca1b
Update test case
JukkaL Nov 11, 2019
3309f74
Always filter out tests
JukkaL Nov 4, 2019
575cecd
Simplify redundant note
JukkaL Nov 4, 2019
bde23a1
Skip conftest modules (used for pytest tests)
JukkaL Nov 4, 2019
b4554e6
Fix crash
JukkaL Nov 5, 2019
c84677b
Filter out more kinds of bad function type comments
JukkaL Nov 5, 2019
be7414e
Recognize more modules as test modules
JukkaL Nov 5, 2019
07e1955
Revert changes to imports
JukkaL Nov 11, 2019
e6bac88
Try to fix Windows
JukkaL Nov 11, 2019
548bb10
Attempt to fix compiled
JukkaL Nov 11, 2019
f876154
Fix lint
JukkaL Nov 11, 2019
56d1a73
Try to fix Python 3.5
JukkaL Nov 11, 2019
58ae038
Respond to feedback
JukkaL Nov 14, 2019
2989121
Merge branch 'master' into stubgen-fixes-batch
JukkaL Nov 14, 2019
073832e
Fix stuff
JukkaL Nov 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2285,6 +2285,7 @@ class is generic then it will be a type constructor of higher kind.
# Used to stash the names of the mro classes temporarily between
# deserialization and fixup. See deserialize() for why.
_mro_refs = None # type: Optional[List[str]]
bad_mro = False # Could not construct full MRO

declared_metaclass = None # type: Optional[mypy.types.Instance]
metaclass_type = None # type: Optional[mypy.types.Instance]
Expand Down
5 changes: 4 additions & 1 deletion mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import pprint
import sys

from typing import Dict, List, Mapping, Optional, Pattern, Set, Tuple
from typing_extensions import Final
from typing import Dict, List, Mapping, Optional, Pattern, Set, Tuple, Callable, Any

from mypy import defaults
from mypy.util import get_class_descriptors, replace_object_state
Expand Down Expand Up @@ -262,6 +262,9 @@ def __init__(self) -> None:
self.cache_map = {} # type: Dict[str, Tuple[str, str]]
# Don't properly free objects on exit, just kill the current process.
self.fast_exit = False
# Used to transform source code before parsing if not None
# TODO: Make the type precise (AnyStr -> AnyStr)
self.transform_source = None # type: Optional[Callable[[Any], Any]]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a TODO to make this more precise when the mypy issue is fixed?

# Print full path to each file in the report.
self.show_absolute_path = False # type: bool

Expand Down
2 changes: 2 additions & 0 deletions mypy/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def parse(source: Union[str, bytes],
The python_version (major, minor) option determines the Python syntax variant.
"""
is_stub_file = fnam.endswith('.pyi')
if options.transform_source is not None:
source = options.transform_source(source)
if options.python_version[0] >= 3 or is_stub_file:
import mypy.fastparse
return mypy.fastparse.parse(source,
Expand Down
22 changes: 13 additions & 9 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1490,8 +1490,7 @@ def configure_base_classes(self,

# Calculate the MRO.
if not self.verify_base_classes(defn):
# Give it an MRO consisting of just the class itself and object.
defn.info.mro = [defn.info, self.object_type().type]
self.set_dummy_mro(defn.info)
return
self.calculate_class_mro(defn, self.object_type)

Expand Down Expand Up @@ -1519,6 +1518,11 @@ def configure_tuple_base_class(self,

return base.partial_fallback

def set_dummy_mro(self, info: TypeInfo) -> None:
# Give it an MRO consisting of just the class itself and object.
info.mro = [info, self.object_type().type]
info.bad_mro = True

def calculate_class_mro(self, defn: ClassDef,
obj_type: Optional[Callable[[], Instance]] = None) -> None:
"""Calculate method resolution order for a class.
Expand All @@ -1530,9 +1534,9 @@ def calculate_class_mro(self, defn: ClassDef,
try:
calculate_mro(defn.info, obj_type)
except MroError:
self.fail_blocker('Cannot determine consistent method resolution '
'order (MRO) for "%s"' % defn.name, defn)
defn.info.mro = []
self.fail('Cannot determine consistent method resolution '
'order (MRO) for "%s"' % defn.name, defn)
self.set_dummy_mro(defn.info)
# Allow plugins to alter the MRO to handle the fact that `def mro()`
# on metaclasses permits MRO rewriting.
if defn.fullname:
Expand Down Expand Up @@ -1597,12 +1601,12 @@ def update_metaclass(self, defn: ClassDef) -> None:

def verify_base_classes(self, defn: ClassDef) -> bool:
info = defn.info
cycle = False
for base in info.bases:
baseinfo = base.type
if self.is_base_class(info, baseinfo):
self.fail('Cycle in inheritance hierarchy', defn, blocker=True)
# Clear bases to forcefully get rid of the cycle.
info.bases = []
self.fail('Cycle in inheritance hierarchy', defn)
cycle = True
if baseinfo.fullname == 'builtins.bool':
self.fail("'%s' is not a valid base class" %
baseinfo.name, defn, blocker=True)
Expand All @@ -1611,7 +1615,7 @@ def verify_base_classes(self, defn: ClassDef) -> bool:
if dup:
self.fail('Duplicate base class "%s"' % dup.name, defn, blocker=True)
return False
return True
return not cycle

def is_base_class(self, t: TypeInfo, s: TypeInfo) -> bool:
"""Determine if t is a base class of s (but do not use mro)."""
Expand Down
8 changes: 6 additions & 2 deletions mypy/stubdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,12 @@ def infer_sig_from_docstring(docstr: str, name: str) -> Optional[List[FunctionSi
state = DocStringParser(name)
# Return all found signatures, even if there is a parse error after some are found.
with contextlib.suppress(tokenize.TokenError):
for token in tokenize.tokenize(io.BytesIO(docstr.encode('utf-8')).readline):
state.add_token(token)
try:
tokens = tokenize.tokenize(io.BytesIO(docstr.encode('utf-8')).readline)
for token in tokens:
state.add_token(token)
except IndentationError:
return None
sigs = state.get_signatures()

def is_unique_args(sig: FunctionSig) -> bool:
Expand Down
Loading