Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions src/docstub/_stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,11 @@ def leave_Param(self, original_node, updated_node):
details=details,
)

# Potentially use "Incomplete" except for first param in (class)methods
elif not is_self_or_cls and updated_node.annotation is None:
has_missing_annotation = (
"annotation" not in node_changes and updated_node.annotation is None
)
# Fallback to "Incomplete" except for first param in (class)methods
if has_missing_annotation and not is_self_or_cls:
node_changes["annotation"] = self._Annotation_Incomplete
import_ = PyImport.typeshed_Incomplete()
self._required_imports.add(import_)
Expand Down
102 changes: 101 additions & 1 deletion tests/test_stubs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import re
from textwrap import dedent

Expand Down Expand Up @@ -278,6 +279,7 @@ def __init__(self, a):
)
expected = dedent(
"""
from _typeshed import Incomplete
from typing import ClassVar
class Foo:
a: int
Expand All @@ -286,7 +288,7 @@ class Foo:
c: list
d: ClassVar[bool]

def __init__(self, a) -> None: ...
def __init__(self, a: Incomplete) -> None: ...
"""
)
transformer = Py2StubTransformer()
Expand Down Expand Up @@ -335,6 +337,7 @@ def test_module_assign_conflict(self, caplog):

assert caplog.messages == ["Keeping existing inline annotation for assignment"]
assert "ignoring docstring: int" in caplog.records[0].details
assert caplog.records[0].levelno == logging.WARNING

def test_module_assign_no_conflict(self, capsys):
source = dedent(
Expand Down Expand Up @@ -405,6 +408,7 @@ class Foo:
assert expected == result

assert caplog.messages == ["Keeping existing inline annotation for assignment"]
assert caplog.records[0].levelno == logging.WARNING

def test_class_assign_no_conflict(self, caplog):
source = dedent(
Expand Down Expand Up @@ -475,6 +479,101 @@ def foo(a: int) -> None: ...

assert caplog.messages == ["Keeping existing inline parameter annotation"]
assert "ignoring docstring: Sized" in caplog.records[0].details
assert caplog.records[0].levelno == logging.WARNING

def test_missing_param(self, caplog):
source = dedent(
'''
def foo(a, b) -> None:
"""
Parameters
----------
a : int
"""
'''
)
expected = dedent(
"""
from _typeshed import Incomplete
def foo(a: int, b: Incomplete) -> None: ...
"""
)
transformer = Py2StubTransformer()
result = transformer.python_to_stub(source)
assert expected == result
assert caplog.messages == ["Missing annotation for parameter 'b'"]
assert caplog.records[0].levelno == logging.WARNING

def test_missing_param_inline(self, caplog):
source = dedent(
"""
def foo(a: int, b) -> None:
pass
"""
)
expected = dedent(
"""
from _typeshed import Incomplete
def foo(a: int, b: Incomplete) -> None: ...
"""
)
transformer = Py2StubTransformer()
result = transformer.python_to_stub(source)
assert expected == result
assert caplog.messages == ["Missing annotation for parameter 'b'"]
assert caplog.records[0].levelno == logging.WARNING

def test_missing_attr(self, caplog):
source = dedent(
'''
class Foo:
"""
Attributes
----------
a : ClassVar[int]
"""
a = 3
b = True
'''
)
expected = dedent(
"""
from _typeshed import Incomplete
from typing import ClassVar
class Foo:
a: ClassVar[int]
b: Incomplete
"""
)
transformer = Py2StubTransformer()
result = transformer.python_to_stub(source)
assert expected == result
assert caplog.messages == ["Missing annotation for assignment 'b'"]
assert caplog.records[0].levelno == logging.WARNING

def test_missing_attr_inline(self, caplog):
source = dedent(
"""
from typing import ClassVar
class Foo:
a: ClassVar[int] = 3
b = True
"""
)
expected = dedent(
"""
from _typeshed import Incomplete
from typing import ClassVar
class Foo:
a: ClassVar[int]
b: Incomplete
"""
)
transformer = Py2StubTransformer()
result = transformer.python_to_stub(source)
assert expected == result
assert caplog.messages == ["Missing annotation for assignment 'b'"]
assert caplog.records[0].levelno == logging.WARNING

def test_return_keep_inline_annotation(self):
source = dedent(
Expand Down Expand Up @@ -515,6 +614,7 @@ def foo() -> int: ...

assert caplog.messages == ["Keeping existing inline return annotation"]
assert "ignoring docstring: Sized" in caplog.records[0].details
assert caplog.records[0].levelno == logging.WARNING

def test_preserved_type_comment(self):
source = dedent(
Expand Down
Loading