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

tests: remove empty [out]s #15475

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
19 changes: 15 additions & 4 deletions mypy/test/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def parse_test_case(case: DataDrivenTestCase) -> None:
else:
join = posixpath.join

out_section_missing = case.suite.required_out_section
had_out_section = False
had_useful_out_sections = False
had_effective_out_section = False

files: list[tuple[str, str]] = [] # path and contents
output_files: list[tuple[str, str | Pattern[str]]] = [] # output path and contents
Expand Down Expand Up @@ -148,6 +150,9 @@ def _item_fail(msg: str) -> NoReturn:
full = join(base_path, m.group(1))
deleted_paths.setdefault(num, set()).add(full)
elif re.match(r"out[0-9]*$", item.id):
had_out_section = True
if item.data or item.id != "out":
had_useful_out_sections = True
if item.arg is None:
args = []
else:
Expand Down Expand Up @@ -190,15 +195,20 @@ def _item_fail(msg: str) -> NoReturn:
passnum = int(item.id[len("out") :])
assert passnum > 1
output2[passnum] = tmp_output
out_section_missing = False
had_effective_out_section = True
elif item.id == "triggered" and item.arg is None:
triggered = item.data
else:
section_str = item.id + (f" {item.arg}" if item.arg else "")
_item_fail(f"Invalid section header [{section_str}] in case {case.name!r}")

if out_section_missing:
_case_fail(f"Required output section not found in case {case.name!r}")
if case.suite.required_out_section:
if not had_effective_out_section:
_case_fail(f"Required output section not found in case {case.name!r}")
elif not case.suite.allow_redundant_out_section and (
had_out_section and not had_useful_out_sections
):
_case_fail(f"Redundant [out] section(s) in {case.name!r}")

for passnum in stale_modules.keys():
if passnum not in rechecked_modules:
Expand Down Expand Up @@ -808,6 +818,7 @@ class DataSuite:
data_prefix = test_data_prefix

required_out_section = False
allow_redundant_out_section = False

native_sep = False

Expand Down
17 changes: 17 additions & 0 deletions mypy/test/meta/test_parse_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,20 @@ def test_bad_eq_version_check(self) -> None:

# Assert
assert "version==3.7 always false since minimum runtime version is (3, 8)" in actual

def test_redundant_out(self) -> None:
# Arrange
data = self._dedent(
"""
[case abc]
s: str = 42
[out]
[out version==3.7]
"""
)

# Act
actual = self._run_pytest(data)

# Assert
assert "Redundant [out] section(s) in 'abc'" in actual
1 change: 1 addition & 0 deletions mypy/test/testsemanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def get_semanal_options(program_text: str, testcase: DataDrivenTestCase) -> Opti
class SemAnalSuite(DataSuite):
files = semanal_files
native_sep = True
allow_redundant_out_section = True

def run_case(self, testcase: DataDrivenTestCase) -> None:
test_semanal(testcase)
Expand Down
1 change: 0 additions & 1 deletion mypyc/test-data/irbuild-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,6 @@ L0:
class A(B): pass
class B(C): pass
class C: pass
[out]

[case testDeletableSemanticAnalysis]
class Err1:
Expand Down
1 change: 0 additions & 1 deletion mypyc/test-data/run-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -2020,7 +2020,6 @@ assert g.x == 20
import other
import other_interpreted

[out]

[case testAttributeOverridesProperty]
from typing import Any
Expand Down
1 change: 0 additions & 1 deletion mypyc/test-data/run-loops.test
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ nested_list()
gen = nested_yield()
for k in range(12):
assert next(gen) == k % 4
[out]

[case testForIterable]
from typing import Iterable, Dict, Any, Tuple
Expand Down
1 change: 0 additions & 1 deletion mypyc/test-data/run-misc.test
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ with assertRaises(ValueError, "not enough values to unpack"):
with assertRaises(ValueError, "not enough values to unpack"):
unpack3([1])

[out]

[case testModuleTopLevel]
x = 1
Expand Down
3 changes: 0 additions & 3 deletions mypyc/test-data/run-traits.test
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ assert get_x(c2) == 1
assert get_y(c2) == 0
g(c1, c2)
assert get_y(c2) == 2
[out]

[case testTraitAttrsTriangle]
from mypy_extensions import trait
Expand Down Expand Up @@ -338,7 +337,6 @@ c.a = 1
c.x = 10

assert take_t(c) == take_c(c) == 11
[out]

[case testTraitAttrsTree]
from mypy_extensions import trait
Expand Down Expand Up @@ -382,7 +380,6 @@ assert c2.x == 1
g(c1, c2)
assert c1.x == 1
assert c2.x == 2
[out]

[case testTraitErrorMessages]
from mypy_extensions import trait
Expand Down
30 changes: 0 additions & 30 deletions test-data/unit/check-abstract.test
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ class A(metaclass=ABCMeta):
class B(A):
def f(self): pass
B()
[out]

[case testInstantiatingAbstractClass]
from abc import abstractmethod, ABCMeta
Expand All @@ -160,7 +159,6 @@ class B(metaclass=ABCMeta):
def f(self): pass
A() # OK
B() # E: Cannot instantiate abstract class "B" with abstract attribute "f"
[out]

[case testInstantiatingClassWithInheritedAbstractMethod]
from abc import abstractmethod, ABCMeta
Expand All @@ -172,7 +170,6 @@ class A(metaclass=ABCMeta):
def g(self): pass
class B(A): pass
B() # E: Cannot instantiate abstract class "B" with abstract attributes "f" and "g"
[out]

[case testInstantiationAbstractsInTypeForFunctions]
from typing import Type
Expand All @@ -196,7 +193,6 @@ f(B) # E: Only concrete class can be given where "Type[A]" is expected
f(C) # OK
x: Type[B]
f(x) # OK
[out]

[case testAbstractTypeInADict]
from typing import Dict, Type
Expand Down Expand Up @@ -237,7 +233,6 @@ Alias() # E: Cannot instantiate abstract class "A" with abstract attribute "m"
GoodAlias()
f(Alias) # E: Only concrete class can be given where "Type[A]" is expected
f(GoodAlias)
[out]

[case testInstantiationAbstractsInTypeForVariables]
# flags: --no-strict-optional
Expand Down Expand Up @@ -269,7 +264,6 @@ if int():
var_old = B # E: Can only assign concrete classes to a variable of type "Type[A]"
if int():
var_old = C # OK
[out]

[case testInstantiationAbstractsInTypeForClassMethods]
from typing import Type
Expand All @@ -288,7 +282,6 @@ class C:
def m(self) -> None:
pass
[builtins fixtures/classmethod.pyi]
[out]

[case testInstantiatingClassWithInheritedAbstractMethodAndSuppression]
from abc import abstractmethod, ABCMeta
Expand All @@ -315,8 +308,6 @@ class A(metaclass=ABCMeta):
@abstractmethod
def j(self): pass
a = A() # E: Cannot instantiate abstract class "A" with abstract attributes "a", "b", ... and "j" (7 methods suppressed)
[out]


-- Implementing abstract methods
-- -----------------------------
Expand All @@ -337,7 +328,6 @@ class B(A):
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
return 0
def g(self, x: int) -> int: return 0
[out]

[case testImplementingAbstractMethodWithMultipleBaseClasses]
from abc import abstractmethod, ABCMeta
Expand All @@ -356,7 +346,6 @@ class A(I, J):
def g(self, x: str) -> int: return 0 \
# E: Return type "int" of "g" incompatible with return type "str" in supertype "J"
def h(self) -> int: return 0 # Not related to any base class
[out]

[case testImplementingAbstractMethodWithExtension]
from abc import abstractmethod, ABCMeta
Expand All @@ -370,7 +359,6 @@ class A(I):
# E: Argument 1 of "f" is incompatible with supertype "J"; supertype defines the argument type as "int" \
# N: This violates the Liskov substitution principle \
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
[out]

[case testInvalidOverridingAbstractMethod]
from abc import abstractmethod, ABCMeta
Expand All @@ -383,7 +371,6 @@ class I(J):
def f(self, x: 'I') -> None: pass # E: Argument 1 of "f" is incompatible with supertype "J"; supertype defines the argument type as "J" \
# N: This violates the Liskov substitution principle \
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
[out]

[case testAbstractClassCoAndContraVariance]
from abc import abstractmethod, ABCMeta
Expand Down Expand Up @@ -486,7 +473,6 @@ class I(metaclass=ABCMeta):
class A(I):
def f(self, x): pass
def g(self, x, y): pass
[out]

[case testAbstractClassWithImplementationUsingDynamicTypes]
from abc import abstractmethod, ABCMeta
Expand All @@ -499,8 +485,6 @@ class I(metaclass=ABCMeta):
class A(I):
def f(self, x): pass
def g(self, x, y): pass
[out]


-- Special cases
-- -------------
Expand Down Expand Up @@ -638,7 +622,6 @@ class A(metaclass=ABCMeta):
def f(self, x: int) -> int: pass
@overload
def f(self, x: str) -> str: pass
[out]

[case testOverloadedAbstractMethodVariantMissingDecorator1]
from foo import *
Expand All @@ -653,7 +636,6 @@ class A(metaclass=ABCMeta):
@abstractmethod
@overload
def f(self, x: str) -> str: pass
[out]

[case testMultipleInheritanceAndAbstractMethod]
import typing
Expand Down Expand Up @@ -685,7 +667,6 @@ class A(metaclass=ABCMeta):
self.g(1) # E: Argument 1 to "g" of "A" has incompatible type "int"; expected "str"
@abstractmethod
def g(self, x: str) -> None: pass
[out]

[case testAbstractOperatorMethods1]
import typing
Expand All @@ -708,7 +689,6 @@ class B:
class C:
def __add__(self, other: int) -> B:
return cast(Any, None)
[out]

[case testAbstractClassWithAnyBase]
from typing import Any
Expand Down Expand Up @@ -738,7 +718,6 @@ class A(metaclass=ABCMeta):
def f(a: A) -> None:
a.x() # E: "int" not callable
a.x = 1 # E: Property "x" defined in "A" is read-only
[out]

[case testReadOnlyAbstractPropertyForwardRef]
from abc import abstractproperty, ABCMeta
Expand All @@ -748,7 +727,6 @@ def f(a: A) -> None:
class A(metaclass=ABCMeta):
@abstractproperty
def x(self) -> int: pass
[out]

[case testReadWriteAbstractProperty]
from abc import abstractproperty, ABCMeta
Expand Down Expand Up @@ -889,7 +867,6 @@ class B(A):
def x(self) -> int:
return super().x.y # E: "int" has no attribute "y"
[builtins fixtures/property.pyi]
[out]

[case testSuperWithReadWriteAbstractProperty]
from abc import abstractproperty, ABCMeta
Expand Down Expand Up @@ -935,7 +912,6 @@ class A(metaclass=ABCMeta):
def f(a: A) -> None:
a.x.y
a.x = 1 # E: Property "x" defined in "A" is read-only
[out]

[case testDynamicallyTypedReadOnlyAbstractPropertyForwardRef]
from abc import abstractproperty, ABCMeta
Expand All @@ -945,7 +921,6 @@ def f(a: A) -> None:
class A(metaclass=ABCMeta):
@abstractproperty
def x(self): pass
[out]

[case testDynamicallyTypedReadWriteAbstractProperty]
from abc import abstractproperty, ABCMeta
Expand All @@ -957,7 +932,6 @@ class A(metaclass=ABCMeta):
def x(self): pass
@x.setter
def x(self, x): pass
[out]

[case testMixinTypedAbstractProperty]
from abc import ABCMeta, abstractproperty
Expand All @@ -969,7 +943,6 @@ class Mixin:
foo = "foo"
class C(Mixin, A):
pass
[out]

[case testMixinTypedProperty]
class A:
Expand All @@ -981,7 +954,6 @@ class Mixin:
class C(Mixin, A):
pass
[builtins fixtures/property.pyi]
[out]

[case testMixinSubtypedProperty]
class X:
Expand All @@ -997,7 +969,6 @@ class Mixin:
class C(Mixin, A):
pass
[builtins fixtures/property.pyi]
[out]

[case testMixinTypedPropertyReversed]
class A:
Expand All @@ -1009,7 +980,6 @@ class Mixin:
class C(A, Mixin): # E: Definition of "foo" in base class "A" is incompatible with definition in base class "Mixin"
pass
[builtins fixtures/property.pyi]
[out]

-- Special cases
-- -------------
Expand Down
4 changes: 0 additions & 4 deletions test-data/unit/check-async-await.test
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ async def f() -> int:
return x
[builtins fixtures/async_await.pyi]
[typing fixtures/typing-async.pyi]
[out]

[case testAwaitDefaultContext]

Expand Down Expand Up @@ -633,7 +632,6 @@ async def decorated_host_coroutine() -> None:

[builtins fixtures/async_await.pyi]
[typing fixtures/typing-async.pyi]
[out]

[case testAsyncGenDisallowUntyped]
# flags: --disallow-untyped-defs
Expand All @@ -647,7 +645,6 @@ async def g() -> AsyncGenerator[Any, None]:
yield 0
[builtins fixtures/async_await.pyi]
[typing fixtures/typing-async.pyi]
[out]

[case testAsyncGenDisallowUntypedTriggers]
# flags: --disallow-untyped-defs
Expand All @@ -663,7 +660,6 @@ async def g(): # E: Function is missing a return type annotation
yield 0
[builtins fixtures/async_await.pyi]
[typing fixtures/typing-async.pyi]
[out]

[case testAsyncOverloadedFunction]
from typing import overload
Expand Down
Loading
Loading