From c9acd4ecb80334b444bea0ffc65b392ddbbbfbca Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 18 Sep 2026 23:10:41 +0800 Subject: [PATCH] =?UTF-8?q?chore(vipeye-internal):=20=E4=BF=AE=E5=89=AA=20?= =?UTF-8?q?samples=20=E6=AE=8B=E7=95=99=E4=B8=8E=E5=AD=A4=E5=84=BF?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=BE=85=E5=8A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - samples 根目录 1277 个散落 .py/.pyi 夹具删除,仅保留被现存用例引用的 15 个 (badToken1/test_file1/lines1/parser1-2/suiteExpectedColon1-3/maxParseDepth1-2/ parserRecovery1-3/fstring6/finallyExit1)+ 2 个 viper_*.vp;子目录夹具不动 - 删除已无引用的 harness/fourslash/runner.ts(fourslash 夹具与 testState.test 已删) - 保留 tests/lsp/languageServerTestUtils.ts:仍被 typeServer.virtualFileRedirect 引用 验证: 全量串行 53 套件通过、1 跳过,732 用例全绿 --- .../src/tests/harness/fourslash/runner.ts | 93 --- .../src/tests/samples/abstractClass1.py | 55 -- .../src/tests/samples/abstractClass10.py | 75 -- .../src/tests/samples/abstractClass11.py | 25 - .../src/tests/samples/abstractClass2.py | 30 - .../src/tests/samples/abstractClass3.py | 30 - .../src/tests/samples/abstractClass4.py | 30 - .../src/tests/samples/abstractClass5.py | 54 -- .../src/tests/samples/abstractClass6.py | 37 - .../src/tests/samples/abstractClass7.py | 22 - .../src/tests/samples/abstractClass8.py | 26 - .../src/tests/samples/abstractClass9.py | 22 - .../src/tests/samples/annotated1.py | 102 --- .../src/tests/samples/annotated2.py | 16 - .../src/tests/samples/annotatedVar1.py | 20 - .../src/tests/samples/annotatedVar2.py | 28 - .../src/tests/samples/annotatedVar3.py | 54 -- .../src/tests/samples/annotatedVar4.py | 24 - .../src/tests/samples/annotatedVar5.py | 37 - .../src/tests/samples/annotatedVar6.py | 22 - .../src/tests/samples/annotatedVar7.py | 13 - .../src/tests/samples/annotatedVar8.py | 29 - .../src/tests/samples/annotations1.py | 159 ---- .../src/tests/samples/annotations2.py | 33 - .../src/tests/samples/annotations3.py | 37 - .../src/tests/samples/annotations4.py | 67 -- .../src/tests/samples/annotations5.py | 9 - .../src/tests/samples/annotations6.py | 29 - .../vipeye-internal/src/tests/samples/any1.py | 45 -- .../src/tests/samples/assert1.py | 22 - .../src/tests/samples/assertType1.py | 48 -- .../src/tests/samples/assignment1.py | 72 -- .../src/tests/samples/assignment10.py | 83 -- .../src/tests/samples/assignment11.py | 20 - .../src/tests/samples/assignment12.py | 24 - .../src/tests/samples/assignment2.py | 43 -- .../src/tests/samples/assignment3.py | 51 -- .../src/tests/samples/assignment4.py | 20 - .../src/tests/samples/assignment5.py | 16 - .../src/tests/samples/assignment6.py | 25 - .../src/tests/samples/assignment7.py | 13 - .../src/tests/samples/assignment8.py | 38 - .../src/tests/samples/assignment9.py | 23 - .../src/tests/samples/assignmentExpr1.py | 26 - .../src/tests/samples/assignmentExpr2.py | 67 -- .../src/tests/samples/assignmentExpr3.py | 27 - .../src/tests/samples/assignmentExpr4.py | 49 -- .../src/tests/samples/assignmentExpr5.py | 23 - .../src/tests/samples/assignmentExpr6.py | 10 - .../src/tests/samples/assignmentExpr7.py | 23 - .../src/tests/samples/assignmentExpr8.py | 11 - .../src/tests/samples/assignmentExpr9.py | 42 -- .../src/tests/samples/async1.py | 49 -- .../src/tests/samples/augmentedAssignment1.py | 62 -- .../src/tests/samples/augmentedAssignment2.py | 18 - .../src/tests/samples/augmentedAssignment3.py | 21 - .../src/tests/samples/autoVariance1.py | 164 ---- .../src/tests/samples/autoVariance2.py | 30 - .../src/tests/samples/autoVariance3.py | 163 ---- .../src/tests/samples/autoVariance4.py | 51 -- .../src/tests/samples/autoVariance5.py | 20 - .../src/tests/samples/await1.py | 57 -- .../src/tests/samples/await2.py | 31 - .../src/tests/samples/await3.py | 37 - .../src/tests/samples/builtins1.py | 2 - .../src/tests/samples/builtins2.py | 7 - .../src/tests/samples/call1.py | 93 --- .../src/tests/samples/call10.py | 75 -- .../src/tests/samples/call11.py | 44 -- .../src/tests/samples/call12.py | 47 -- .../src/tests/samples/call13.py | 15 - .../src/tests/samples/call14.py | 57 -- .../src/tests/samples/call15.py | 66 -- .../src/tests/samples/call16.py | 38 - .../src/tests/samples/call17.py | 32 - .../src/tests/samples/call2.py | 183 ----- .../src/tests/samples/call3.py | 180 ----- .../src/tests/samples/call4.py | 11 - .../src/tests/samples/call5.py | 94 --- .../src/tests/samples/call6.py | 50 -- .../src/tests/samples/call7.py | 85 --- .../src/tests/samples/call8.py | 40 - .../src/tests/samples/call9.py | 51 -- .../src/tests/samples/callSite1.py | 35 - .../src/tests/samples/callSite2.py | 16 - .../src/tests/samples/callSite3.py | 50 -- .../src/tests/samples/callable1.py | 51 -- .../src/tests/samples/callable2.py | 55 -- .../src/tests/samples/callable3.py | 23 - .../src/tests/samples/callable4.py | 32 - .../src/tests/samples/callable5.py | 37 - .../src/tests/samples/callable6.py | 91 --- .../src/tests/samples/callable7.py | 33 - .../src/tests/samples/callbackProtocol1.py | 159 ---- .../src/tests/samples/callbackProtocol10.py | 61 -- .../src/tests/samples/callbackProtocol11.py | 21 - .../src/tests/samples/callbackProtocol2.py | 28 - .../src/tests/samples/callbackProtocol3.py | 20 - .../src/tests/samples/callbackProtocol4.py | 65 -- .../src/tests/samples/callbackProtocol5.py | 84 --- .../src/tests/samples/callbackProtocol6.py | 56 -- .../src/tests/samples/callbackProtocol7.py | 36 - .../src/tests/samples/callbackProtocol8.py | 14 - .../src/tests/samples/callbackProtocol9.py | 30 - .../src/tests/samples/capturedVariable1.py | 146 ---- .../src/tests/samples/capturedVariable2.py | 20 - .../src/tests/samples/circular1.py | 16 - .../src/tests/samples/circular2.py | 37 - .../src/tests/samples/circularBaseClass.py | 16 - .../src/tests/samples/classGetItem1.py | 28 - .../src/tests/samples/classVar1.py | 41 - .../src/tests/samples/classVar2.py | 29 - .../src/tests/samples/classVar3.py | 56 -- .../src/tests/samples/classVar4.py | 39 - .../src/tests/samples/classVar5.py | 16 - .../src/tests/samples/classVar6.py | 20 - .../src/tests/samples/classVar7.py | 38 - .../src/tests/samples/classes1.py | 88 --- .../src/tests/samples/classes10.py | 24 - .../src/tests/samples/classes11.py | 46 -- .../src/tests/samples/classes3.py | 125 --- .../src/tests/samples/classes4.py | 15 - .../src/tests/samples/classes5.py | 291 ------- .../src/tests/samples/classes6.py | 16 - .../src/tests/samples/classes7.py | 19 - .../src/tests/samples/classes8.py | 41 - .../src/tests/samples/classes9.py | 69 -- .../src/tests/samples/codeFlow1.py | 65 -- .../src/tests/samples/codeFlow10.py | 14 - .../src/tests/samples/codeFlow11.py | 46 -- .../src/tests/samples/codeFlow2.py | 26 - .../src/tests/samples/codeFlow3.py | 8 - .../src/tests/samples/codeFlow4.py | 142 ---- .../src/tests/samples/codeFlow5.py | 10 - .../src/tests/samples/codeFlow6.py | 29 - .../src/tests/samples/codeFlow7.py | 29 - .../src/tests/samples/codeFlow8.py | 27 - .../src/tests/samples/codeFlow9.py | 19 - .../src/tests/samples/comparison1.py | 77 -- .../src/tests/samples/comparison2.py | 158 ---- .../src/tests/samples/complex1.py | 16 - .../src/tests/samples/comprehension1.py | 65 -- .../src/tests/samples/comprehension10.py | 34 - .../src/tests/samples/comprehension11.py | 18 - .../src/tests/samples/comprehension2.py | 17 - .../src/tests/samples/comprehension3.py | 12 - .../src/tests/samples/comprehension4.py | 15 - .../src/tests/samples/comprehension5.py | 20 - .../src/tests/samples/comprehension6.py | 14 - .../src/tests/samples/comprehension7.py | 15 - .../src/tests/samples/comprehension8.py | 15 - .../src/tests/samples/comprehension9.py | 22 - .../src/tests/samples/conditional1.py | 93 --- .../src/tests/samples/constant1.py | 40 - .../src/tests/samples/constants1.py | 64 -- .../src/tests/samples/constrainedTypeVar1.py | 46 -- .../src/tests/samples/constrainedTypeVar10.py | 30 - .../src/tests/samples/constrainedTypeVar11.py | 29 - .../src/tests/samples/constrainedTypeVar12.py | 13 - .../src/tests/samples/constrainedTypeVar13.py | 126 ---- .../src/tests/samples/constrainedTypeVar14.py | 29 - .../src/tests/samples/constrainedTypeVar15.py | 31 - .../src/tests/samples/constrainedTypeVar16.py | 29 - .../src/tests/samples/constrainedTypeVar17.py | 48 -- .../src/tests/samples/constrainedTypeVar18.py | 36 - .../src/tests/samples/constrainedTypeVar19.py | 18 - .../src/tests/samples/constrainedTypeVar2.py | 103 --- .../src/tests/samples/constrainedTypeVar20.py | 25 - .../src/tests/samples/constrainedTypeVar3.py | 23 - .../src/tests/samples/constrainedTypeVar4.py | 37 - .../src/tests/samples/constrainedTypeVar5.py | 54 -- .../src/tests/samples/constrainedTypeVar6.py | 35 - .../src/tests/samples/constrainedTypeVar7.py | 63 -- .../src/tests/samples/constrainedTypeVar8.py | 32 - .../src/tests/samples/constrainedTypeVar9.py | 15 - .../src/tests/samples/constructor1.py | 41 - .../src/tests/samples/constructor10.py | 29 - .../src/tests/samples/constructor11.py | 32 - .../src/tests/samples/constructor12.py | 20 - .../src/tests/samples/constructor13.py | 17 - .../src/tests/samples/constructor14.py | 25 - .../src/tests/samples/constructor15.py | 40 - .../src/tests/samples/constructor16.py | 31 - .../src/tests/samples/constructor17.py | 50 -- .../src/tests/samples/constructor18.py | 44 -- .../src/tests/samples/constructor19.py | 15 - .../src/tests/samples/constructor2.py | 184 ----- .../src/tests/samples/constructor20.py | 42 -- .../src/tests/samples/constructor21.py | 33 - .../src/tests/samples/constructor22.py | 42 -- .../src/tests/samples/constructor23.py | 31 - .../src/tests/samples/constructor24.py | 88 --- .../src/tests/samples/constructor25.py | 45 -- .../src/tests/samples/constructor26.py | 58 -- .../src/tests/samples/constructor27.py | 35 - .../src/tests/samples/constructor28.py | 69 -- .../src/tests/samples/constructor29.py | 18 - .../src/tests/samples/constructor3.py | 18 - .../src/tests/samples/constructor30.py | 39 - .../src/tests/samples/constructor31.py | 15 - .../src/tests/samples/constructor32.py | 36 - .../src/tests/samples/constructor33.py | 41 - .../src/tests/samples/constructor4.py | 25 - .../src/tests/samples/constructor5.py | 25 - .../src/tests/samples/constructor6.py | 87 --- .../src/tests/samples/constructor7.py | 51 -- .../src/tests/samples/constructor9.py | 18 - .../src/tests/samples/constructorCallable1.py | 174 ----- .../src/tests/samples/constructorCallable2.py | 163 ---- .../src/tests/samples/coroutines1.py | 69 -- .../src/tests/samples/coroutines2.py | 23 - .../src/tests/samples/coroutines3.py | 39 - .../src/tests/samples/coroutines4.py | 17 - .../src/tests/samples/dataclass1.py | 128 ---- .../src/tests/samples/dataclass10.py | 44 -- .../src/tests/samples/dataclass11.py | 32 - .../src/tests/samples/dataclass12.py | 40 - .../src/tests/samples/dataclass13.py | 13 - .../src/tests/samples/dataclass14.py | 16 - .../src/tests/samples/dataclass15.py | 22 - .../src/tests/samples/dataclass16.py | 21 - .../src/tests/samples/dataclass17.py | 41 - .../src/tests/samples/dataclass18.py | 17 - .../src/tests/samples/dataclass2.py | 30 - .../src/tests/samples/dataclass3.py | 33 - .../src/tests/samples/dataclass4.py | 110 --- .../src/tests/samples/dataclass5.py | 83 -- .../src/tests/samples/dataclass6.py | 45 -- .../src/tests/samples/dataclass7.py | 53 -- .../src/tests/samples/dataclass8.py | 30 - .../src/tests/samples/dataclass9.py | 25 - .../src/tests/samples/dataclassConverter1.py | 159 ---- .../src/tests/samples/dataclassConverter2.py | 71 -- .../src/tests/samples/dataclassConverter3.py | 20 - .../tests/samples/dataclassDescriptors1.py | 41 - .../tests/samples/dataclassDescriptors2.py | 68 -- .../src/tests/samples/dataclassFrozen1.py | 54 -- .../src/tests/samples/dataclassHash1.py | 68 -- .../src/tests/samples/dataclassKwOnly1.py | 90 --- .../src/tests/samples/dataclassKwOnly2.py | 47 -- .../src/tests/samples/dataclassNamedTuple1.py | 63 -- .../src/tests/samples/dataclassNamedTuple2.py | 18 - .../src/tests/samples/dataclassPostInit1.py | 57 -- .../src/tests/samples/dataclassReplace1.py | 45 -- .../src/tests/samples/dataclassSlots1.py | 69 -- .../src/tests/samples/dataclassTransform1.py | 93 --- .../src/tests/samples/dataclassTransform2.py | 98 --- .../src/tests/samples/dataclassTransform3.py | 125 --- .../src/tests/samples/dataclassTransform4.py | 84 --- .../src/tests/samples/decorator1.py | 21 - .../src/tests/samples/decorator2.py | 26 - .../src/tests/samples/decorator3.py | 27 - .../src/tests/samples/decorator4.py | 37 - .../src/tests/samples/decorator5.py | 29 - .../src/tests/samples/decorator6.py | 34 - .../src/tests/samples/decorator7.py | 20 - .../src/tests/samples/defaultInitializer1.py | 26 - .../vipeye-internal/src/tests/samples/del1.py | 68 -- .../vipeye-internal/src/tests/samples/del2.py | 12 - .../src/tests/samples/deprecated2.py | 175 ----- .../src/tests/samples/deprecated3.py | 25 - .../src/tests/samples/deprecated4.py | 93 --- .../src/tests/samples/deprecated5.py | 15 - .../src/tests/samples/deprecated6.py | 50 -- .../src/tests/samples/deprecated7.py | 30 - .../src/tests/samples/deprecated8.py | 44 -- .../src/tests/samples/deprecatedAlias1.py | 62 -- .../src/tests/samples/deprecatedAlias2.py | 64 -- .../src/tests/samples/descriptor1.py | 165 ---- .../src/tests/samples/descriptor2.py | 29 - .../src/tests/samples/descriptor3.py | 24 - .../src/tests/samples/descriptor4.py | 67 -- .../src/tests/samples/dictionary1.py | 57 -- .../src/tests/samples/dictionary2.py | 34 - .../src/tests/samples/dictionary3.py | 30 - .../src/tests/samples/dictionary4.py | 106 --- .../src/tests/samples/dunderAll1.py | 32 - .../src/tests/samples/dunderAll2.py | 16 - .../src/tests/samples/dunderAll3.pyi | 16 - .../tests/samples/duplicateDeclaration1.py | 113 --- .../tests/samples/duplicateDeclaration2.py | 45 -- .../src/tests/samples/duplicateImports1.py | 13 - .../src/tests/samples/ellipsis1.pyi | 51 -- .../src/tests/samples/emptyContainers1.py | 85 --- .../src/tests/samples/enum1.py | 291 ------- .../src/tests/samples/enum10.py | 15 - .../src/tests/samples/enum11.py | 54 -- .../src/tests/samples/enum12.py | 18 - .../src/tests/samples/enum13.py | 39 - .../src/tests/samples/enum14.py | 16 - .../src/tests/samples/enum2.py | 24 - .../src/tests/samples/enum3.py | 23 - .../src/tests/samples/enum4.py | 16 - .../src/tests/samples/enum5.py | 33 - .../src/tests/samples/enum6.py | 53 -- .../src/tests/samples/enum7.py | 16 - .../src/tests/samples/enum8.py | 15 - .../src/tests/samples/enum9.py | 50 -- .../src/tests/samples/enumAuto1.py | 15 - .../src/tests/samples/enumGenNextValue1.py | 23 - .../src/tests/samples/exceptionGroup1.py | 127 ---- .../src/tests/samples/expression1.py | 54 -- .../src/tests/samples/expression2.py | 29 - .../src/tests/samples/expression3.py | 26 - .../src/tests/samples/expression4.py | 21 - .../src/tests/samples/expression5.py | 70 -- .../src/tests/samples/expression6.py | 14 - .../src/tests/samples/expression7.py | 37 - .../src/tests/samples/expression8.py | 26 - .../src/tests/samples/expression9.py | 12 - .../src/tests/samples/final1.py | 14 - .../src/tests/samples/final2.py | 162 ---- .../src/tests/samples/final3.py | 270 ------- .../src/tests/samples/final4.pyi | 21 - .../src/tests/samples/final5.py | 18 - .../src/tests/samples/final6.pyi | 25 - .../src/tests/samples/final7.py | 8 - .../src/tests/samples/final8.py | 20 - .../src/tests/samples/forLoop1.py | 118 --- .../src/tests/samples/forLoop2.py | 48 -- .../src/tests/samples/fstring1.py | 159 ---- .../src/tests/samples/fstring2.py | 12 - .../src/tests/samples/fstring3.py | 27 - .../src/tests/samples/fstring4.py | 15 - .../src/tests/samples/fstring5.py | 17 - .../src/tests/samples/function1.py | 10 - .../src/tests/samples/function10.py | 24 - .../src/tests/samples/function2.py | 7 - .../src/tests/samples/function3.py | 13 - .../src/tests/samples/function5.py | 13 - .../src/tests/samples/function6.py | 33 - .../src/tests/samples/function7.py | 75 -- .../src/tests/samples/function8.py | 20 - .../src/tests/samples/function9.py | 33 - .../src/tests/samples/functionAnnotation1.py | 61 -- .../src/tests/samples/functionAnnotation2.py | 27 - .../src/tests/samples/functionAnnotation3.py | 36 - .../src/tests/samples/functionAnnotation4.py | 23 - .../samples/functionAssignabilityMessage1.py | 22 - .../src/tests/samples/functionMember1.py | 18 - .../src/tests/samples/functionMember2.py | 61 -- .../src/tests/samples/futureImport1.py | 7 - .../src/tests/samples/futureImport2.py | 11 - .../src/tests/samples/futureImport3.py | 5 - .../src/tests/samples/generator1.py | 170 ----- .../src/tests/samples/generator10.py | 18 - .../src/tests/samples/generator11.py | 40 - .../src/tests/samples/generator12.py | 25 - .../src/tests/samples/generator13.py | 74 -- .../src/tests/samples/generator14.py | 24 - .../src/tests/samples/generator15.py | 26 - .../src/tests/samples/generator16.py | 20 - .../src/tests/samples/generator2.py | 66 -- .../src/tests/samples/generator3.py | 64 -- .../src/tests/samples/generator4.py | 71 -- .../src/tests/samples/generator5.py | 24 - .../src/tests/samples/generator6.py | 14 - .../src/tests/samples/generator7.py | 16 - .../src/tests/samples/generator8.py | 12 - .../src/tests/samples/generator9.py | 19 - .../src/tests/samples/generic1.py | 41 - .../src/tests/samples/generic2.py | 29 - .../src/tests/samples/generic3.py | 40 - .../src/tests/samples/genericType1.py | 38 - .../src/tests/samples/genericType10.py | 19 - .../src/tests/samples/genericType11.py | 49 -- .../src/tests/samples/genericType12.py | 60 -- .../src/tests/samples/genericType13.py | 17 - .../src/tests/samples/genericType14.py | 34 - .../src/tests/samples/genericType15.py | 24 - .../src/tests/samples/genericType16.py | 22 - .../src/tests/samples/genericType17.py | 23 - .../src/tests/samples/genericType18.py | 21 - .../src/tests/samples/genericType19.py | 12 - .../src/tests/samples/genericType2.py | 27 - .../src/tests/samples/genericType20.py | 15 - .../src/tests/samples/genericType21.py | 25 - .../src/tests/samples/genericType22.py | 15 - .../src/tests/samples/genericType23.py | 13 - .../src/tests/samples/genericType24.py | 19 - .../src/tests/samples/genericType25.py | 10 - .../src/tests/samples/genericType26.py | 82 -- .../src/tests/samples/genericType27.py | 17 - .../src/tests/samples/genericType28.py | 183 ----- .../src/tests/samples/genericType29.py | 17 - .../src/tests/samples/genericType3.py | 27 - .../src/tests/samples/genericType30.py | 16 - .../src/tests/samples/genericType31.py | 16 - .../src/tests/samples/genericType32.py | 20 - .../src/tests/samples/genericType33.py | 27 - .../src/tests/samples/genericType34.py | 18 - .../src/tests/samples/genericType35.py | 28 - .../src/tests/samples/genericType36.py | 26 - .../src/tests/samples/genericType37.py | 17 - .../src/tests/samples/genericType38.py | 48 -- .../src/tests/samples/genericType39.py | 8 - .../src/tests/samples/genericType4.py | 32 - .../src/tests/samples/genericType40.py | 29 - .../src/tests/samples/genericType41.py | 23 - .../src/tests/samples/genericType42.py | 56 -- .../src/tests/samples/genericType43.py | 25 - .../src/tests/samples/genericType44.py | 25 - .../src/tests/samples/genericType45.py | 57 -- .../src/tests/samples/genericType46.py | 36 - .../src/tests/samples/genericType47.py | 34 - .../src/tests/samples/genericType5.py | 41 - .../src/tests/samples/genericType6.py | 25 - .../src/tests/samples/genericType7.py | 69 -- .../src/tests/samples/genericType8.py | 24 - .../src/tests/samples/genericType9.py | 43 -- .../src/tests/samples/hashability1.py | 56 -- .../src/tests/samples/hashability2.py | 51 -- .../src/tests/samples/hashability3.py | 19 - .../src/tests/samples/import1.py | 7 - .../src/tests/samples/import10.py | 11 - .../src/tests/samples/import11.py | 11 - .../src/tests/samples/import12.py | 12 - .../src/tests/samples/import13.py | 5 - .../src/tests/samples/import14.py | 10 - .../src/tests/samples/import15.py | 11 - .../src/tests/samples/import16.py | 6 - .../src/tests/samples/import17.py | 8 - .../src/tests/samples/import18.py | 11 - .../src/tests/samples/import2.py | 27 - .../src/tests/samples/import3.py | 8 - .../src/tests/samples/import4.py | 15 - .../src/tests/samples/import5.py | 6 - .../src/tests/samples/import6.py | 17 - .../src/tests/samples/import7.py | 14 - .../src/tests/samples/import8.py | 7 - .../src/tests/samples/import9.py | 7 - .../tests/samples/inconsistentConstructor1.py | 34 - .../tests/samples/inconsistentSpaceTab1.py | 9 - .../tests/samples/inconsistentSpaceTab2.py | 10 - .../src/tests/samples/index1.py | 128 ---- .../src/tests/samples/inferredTypes1.py | 25 - .../src/tests/samples/inferredTypes2.py | 16 - .../src/tests/samples/inferredTypes3.py | 32 - .../src/tests/samples/initVar1.py | 23 - .../src/tests/samples/initsubclass1.py | 75 -- .../src/tests/samples/initsubclass2.py | 16 - .../src/tests/samples/initsubclass3.py | 24 - .../src/tests/samples/isinstance1.py | 8 - .../src/tests/samples/isinstance2.py | 45 -- .../src/tests/samples/isinstance3.py | 119 --- .../src/tests/samples/isinstance4.py | 70 -- .../src/tests/samples/isinstance5.py | 45 -- .../src/tests/samples/isinstance6.py | 39 - .../src/tests/samples/kwargsUnpack1.py | 142 ---- .../src/tests/samples/kwargsUnpack2.py | 34 - .../src/tests/samples/lambda1.py | 93 --- .../src/tests/samples/lambda10.py | 26 - .../src/tests/samples/lambda11.py | 28 - .../src/tests/samples/lambda12.py | 12 - .../src/tests/samples/lambda13.py | 43 -- .../src/tests/samples/lambda14.py | 8 - .../src/tests/samples/lambda15.py | 24 - .../src/tests/samples/lambda2.py | 32 - .../src/tests/samples/lambda3.py | 33 - .../src/tests/samples/lambda4.py | 78 -- .../src/tests/samples/lambda5.py | 21 - .../src/tests/samples/lambda6.py | 15 - .../src/tests/samples/lambda7.py | 9 - .../src/tests/samples/lambda8.py | 19 - .../src/tests/samples/lambda9.py | 35 - .../src/tests/samples/lazyImport1.py | 18 - .../src/tests/samples/list1.py | 104 --- .../src/tests/samples/list2.py | 13 - .../src/tests/samples/list3.py | 18 - .../src/tests/samples/literalForLoop1.py | 167 ---- .../src/tests/samples/literalString1.py | 92 --- .../src/tests/samples/literalString2.py | 17 - .../src/tests/samples/literalString3.py | 25 - .../src/tests/samples/literals1.py | 69 -- .../src/tests/samples/literals2.py | 29 - .../src/tests/samples/literals3.py | 40 - .../src/tests/samples/literals4.py | 10 - .../src/tests/samples/literals5.py | 28 - .../src/tests/samples/literals6.py | 93 --- .../src/tests/samples/literals7.py | 42 -- .../src/tests/samples/loop1.py | 45 -- .../src/tests/samples/loop10.py | 11 - .../src/tests/samples/loop11.py | 22 - .../src/tests/samples/loop12.py | 17 - .../src/tests/samples/loop13.py | 13 - .../src/tests/samples/loop14.py | 20 - .../src/tests/samples/loop15.py | 22 - .../src/tests/samples/loop16.py | 322 -------- .../src/tests/samples/loop17.py | 12 - .../src/tests/samples/loop18.py | 22 - .../src/tests/samples/loop19.py | 15 - .../src/tests/samples/loop2.py | 22 - .../src/tests/samples/loop20.py | 40 - .../src/tests/samples/loop21.py | 18 - .../src/tests/samples/loop22.py | 21 - .../src/tests/samples/loop23.py | 16 - .../src/tests/samples/loop24.py | 11 - .../src/tests/samples/loop25.py | 45 -- .../src/tests/samples/loop26.py | 12 - .../src/tests/samples/loop27.py | 16 - .../src/tests/samples/loop28.py | 28 - .../src/tests/samples/loop29.py | 16 - .../src/tests/samples/loop3.py | 10 - .../src/tests/samples/loop30.py | 10 - .../src/tests/samples/loop31.py | 14 - .../src/tests/samples/loop32.py | 10 - .../src/tests/samples/loop33.py | 9 - .../src/tests/samples/loop34.py | 33 - .../src/tests/samples/loop35.py | 8 - .../src/tests/samples/loop36.py | 15 - .../src/tests/samples/loop37.py | 13 - .../src/tests/samples/loop38.py | 20 - .../src/tests/samples/loop39.py | 19 - .../src/tests/samples/loop4.py | 16 - .../src/tests/samples/loop40.py | 13 - .../src/tests/samples/loop41.py | 34 - .../src/tests/samples/loop42.py | 14 - .../src/tests/samples/loop43.py | 16 - .../src/tests/samples/loop44.py | 13 - .../src/tests/samples/loop45.py | 17 - .../src/tests/samples/loop46.py | 10 - .../src/tests/samples/loop47.py | 14 - .../src/tests/samples/loop48.py | 24 - .../src/tests/samples/loop49.py | 13 - .../src/tests/samples/loop5.py | 14 - .../src/tests/samples/loop50.py | 15 - .../src/tests/samples/loop51.py | 21 - .../src/tests/samples/loop52.py | 13 - .../src/tests/samples/loop6.py | 25 - .../src/tests/samples/loop7.py | 14 - .../src/tests/samples/loop8.py | 17 - .../src/tests/samples/loop9.py | 25 - .../src/tests/samples/match1.py | 227 ------ .../src/tests/samples/match2.py | 65 -- .../src/tests/samples/match3.py | 99 --- .../src/tests/samples/matchClass1.py | 553 -------------- .../src/tests/samples/matchClass2.py | 20 - .../src/tests/samples/matchClass3.py | 80 -- .../src/tests/samples/matchClass4.py | 47 -- .../src/tests/samples/matchClass5.py | 64 -- .../src/tests/samples/matchClass6.py | 65 -- .../src/tests/samples/matchClass7.py | 34 - .../src/tests/samples/matchClass8.py | 27 - .../src/tests/samples/matchExhaustion1.py | 116 --- .../src/tests/samples/matchLiteral1.py | 121 --- .../src/tests/samples/matchLiteral2.py | 32 - .../src/tests/samples/matchMapping1.py | 154 ---- .../tests/samples/matchNamedTupleGeneric1.py | 142 ---- .../src/tests/samples/matchSequence1.py | 711 ------------------ .../src/tests/samples/matchSequence2.py | 187 ----- .../tests/samples/matchSequenceVariadic.py | 34 - .../src/tests/samples/matchUnnecessary1.py | 97 --- .../src/tests/samples/matchValue1.py | 169 ----- .../src/tests/samples/memberAccess1.py | 134 ---- .../src/tests/samples/memberAccess10.py | 63 -- .../src/tests/samples/memberAccess11.py | 37 - .../src/tests/samples/memberAccess12.py | 31 - .../src/tests/samples/memberAccess13.py | 16 - .../src/tests/samples/memberAccess14.py | 55 -- .../src/tests/samples/memberAccess15.py | 20 - .../src/tests/samples/memberAccess16.py | 12 - .../src/tests/samples/memberAccess17.py | 47 -- .../src/tests/samples/memberAccess18.py | 31 - .../src/tests/samples/memberAccess19.py | 86 --- .../src/tests/samples/memberAccess2.py | 46 -- .../src/tests/samples/memberAccess20.py | 15 - .../src/tests/samples/memberAccess21.py | 35 - .../src/tests/samples/memberAccess22.py | 15 - .../src/tests/samples/memberAccess23.py | 53 -- .../src/tests/samples/memberAccess24.py | 33 - .../src/tests/samples/memberAccess25.py | 75 -- .../src/tests/samples/memberAccess26.py | 39 - .../src/tests/samples/memberAccess27.py | 19 - .../src/tests/samples/memberAccess28.py | 18 - .../src/tests/samples/memberAccess3.py | 64 -- .../src/tests/samples/memberAccess4.py | 120 --- .../src/tests/samples/memberAccess5.py | 26 - .../src/tests/samples/memberAccess6.py | 48 -- .../src/tests/samples/memberAccess7.py | 36 - .../src/tests/samples/memberAccess8.py | 68 -- .../src/tests/samples/memberAccess9.py | 10 - .../src/tests/samples/metaclass1.py | 48 -- .../src/tests/samples/metaclass10.py | 21 - .../src/tests/samples/metaclass11.py | 49 -- .../src/tests/samples/metaclass2.py | 52 -- .../src/tests/samples/metaclass3.py | 61 -- .../src/tests/samples/metaclass4.py | 26 - .../src/tests/samples/metaclass5.py | 33 - .../src/tests/samples/metaclass6.py | 15 - .../src/tests/samples/metaclass7.py | 63 -- .../src/tests/samples/metaclass8.py | 17 - .../src/tests/samples/metaclass9.py | 66 -- .../src/tests/samples/methodOverride1.py | 546 -------------- .../src/tests/samples/methodOverride2.py | 94 --- .../src/tests/samples/methodOverride3.py | 199 ----- .../src/tests/samples/methodOverride4.py | 53 -- .../src/tests/samples/methodOverride5.py | 21 - .../src/tests/samples/methodOverride6.py | 240 ------ .../src/tests/samples/methodOverride7.py | 116 --- .../tests/samples/methodOverrideCallable1.py | 18 - .../src/tests/samples/methods1.py | 115 --- .../src/tests/samples/missingSuper1.py | 73 -- .../src/tests/samples/missingTypeArg1.py | 59 -- .../src/tests/samples/module1.py | 13 - .../src/tests/samples/module2.py | 40 - .../src/tests/samples/module3.py | 15 - .../vipeye-internal/src/tests/samples/mro1.py | 16 - .../vipeye-internal/src/tests/samples/mro2.py | 47 -- .../vipeye-internal/src/tests/samples/mro3.py | 30 - .../vipeye-internal/src/tests/samples/mro4.py | 25 - .../src/tests/samples/nameBinding1.py | 48 -- .../src/tests/samples/nameBinding2.py | 9 - .../src/tests/samples/nameBinding3.py | 36 - .../src/tests/samples/nameBinding4.py | 10 - .../src/tests/samples/nameBinding5.py | 53 -- .../src/tests/samples/namedTuple1.py | 110 --- .../src/tests/samples/namedTuple10.py | 22 - .../src/tests/samples/namedTuple11.py | 22 - .../src/tests/samples/namedTuple2.py | 56 -- .../src/tests/samples/namedTuple3.py | 16 - .../src/tests/samples/namedTuple4.py | 24 - .../src/tests/samples/namedTuple5.py | 15 - .../src/tests/samples/namedTuple6.py | 39 - .../src/tests/samples/namedTuple7.py | 27 - .../src/tests/samples/namedTuple8.py | 16 - .../src/tests/samples/namedTuple9.py | 24 - .../src/tests/samples/never1.py | 57 -- .../src/tests/samples/never2.py | 35 - .../src/tests/samples/newType1.py | 93 --- .../src/tests/samples/newType2.py | 38 - .../src/tests/samples/newType3.py | 33 - .../src/tests/samples/newType4.py | 20 - .../src/tests/samples/newType5.py | 16 - .../src/tests/samples/newType6.py | 12 - .../src/tests/samples/newType7.py | 15 - .../src/tests/samples/newTypeIsLiteral1.py | 65 -- .../src/tests/samples/noTypeCheck1.py | 28 - .../src/tests/samples/none1.py | 30 - .../src/tests/samples/none2.py | 24 - .../src/tests/samples/noreturn1.py | 92 --- .../src/tests/samples/noreturn2.py | 37 - .../src/tests/samples/noreturn3.py | 13 - .../src/tests/samples/noreturn4.py | 27 - .../src/tests/samples/operator1.py | 119 --- .../src/tests/samples/operator10.py | 16 - .../src/tests/samples/operator11.py | 23 - .../src/tests/samples/operator12.py | 14 - .../src/tests/samples/operator2.py | 30 - .../src/tests/samples/operator3.py | 42 -- .../src/tests/samples/operator4.py | 22 - .../src/tests/samples/operator5.py | 5 - .../src/tests/samples/operator6.py | 10 - .../src/tests/samples/operator7.py | 24 - .../src/tests/samples/operator8.py | 261 ------- .../src/tests/samples/operator9.py | 23 - .../src/tests/samples/optional1.py | 87 --- .../src/tests/samples/optional2.py | 22 - .../src/tests/samples/overload1.py | 27 - .../src/tests/samples/overload2.py | 91 --- .../src/tests/samples/overload3.py | 39 - .../src/tests/samples/overload4.py | 17 - .../src/tests/samples/overload5.py | 60 -- .../src/tests/samples/overloadCall1.py | 44 -- .../src/tests/samples/overloadCall10.py | 30 - .../src/tests/samples/overloadCall2.py | 27 - .../src/tests/samples/overloadCall3.py | 21 - .../src/tests/samples/overloadCall4.py | 284 ------- .../src/tests/samples/overloadCall5.py | 107 --- .../src/tests/samples/overloadCall6.py | 321 -------- .../src/tests/samples/overloadCall7.py | 5 - .../src/tests/samples/overloadCall8.py | 9 - .../src/tests/samples/overloadCall9.py | 131 ---- .../src/tests/samples/overloadImpl1.py | 262 ------- .../src/tests/samples/overloadImpl2.py | 146 ---- .../src/tests/samples/overloadImpl3.py | 41 - .../src/tests/samples/overloadOverlap1.py | 511 ------------- .../src/tests/samples/overloadOverride1.py | 56 -- .../src/tests/samples/override1.py | 121 --- .../src/tests/samples/override2.py | 46 -- .../src/tests/samples/paramInference1.py | 46 -- .../src/tests/samples/paramInference2.py | 36 - .../src/tests/samples/paramNames1.py | 89 --- .../src/tests/samples/paramSpec1.py | 60 -- .../src/tests/samples/paramSpec10.py | 54 -- .../src/tests/samples/paramSpec11.py | 36 - .../src/tests/samples/paramSpec12.py | 87 --- .../src/tests/samples/paramSpec13.py | 129 ---- .../src/tests/samples/paramSpec14.py | 53 -- .../src/tests/samples/paramSpec15.py | 25 - .../src/tests/samples/paramSpec16.py | 29 - .../src/tests/samples/paramSpec17.py | 30 - .../src/tests/samples/paramSpec18.py | 38 - .../src/tests/samples/paramSpec19.py | 91 --- .../src/tests/samples/paramSpec2.py | 25 - .../src/tests/samples/paramSpec20.py | 73 -- .../src/tests/samples/paramSpec21.py | 56 -- .../src/tests/samples/paramSpec22.py | 28 - .../src/tests/samples/paramSpec23.py | 22 - .../src/tests/samples/paramSpec24.py | 69 -- .../src/tests/samples/paramSpec25.py | 29 - .../src/tests/samples/paramSpec26.py | 22 - .../src/tests/samples/paramSpec27.py | 61 -- .../src/tests/samples/paramSpec28.py | 36 - .../src/tests/samples/paramSpec29.py | 37 - .../src/tests/samples/paramSpec3.py | 131 ---- .../src/tests/samples/paramSpec30.py | 52 -- .../src/tests/samples/paramSpec31.py | 15 - .../src/tests/samples/paramSpec32.py | 59 -- .../src/tests/samples/paramSpec33.py | 28 - .../src/tests/samples/paramSpec34.py | 21 - .../src/tests/samples/paramSpec35.py | 25 - .../src/tests/samples/paramSpec36.py | 42 -- .../src/tests/samples/paramSpec37.py | 28 - .../src/tests/samples/paramSpec38.py | 24 - .../src/tests/samples/paramSpec39.py | 16 - .../src/tests/samples/paramSpec4.py | 159 ---- .../src/tests/samples/paramSpec40.py | 42 -- .../src/tests/samples/paramSpec41.py | 19 - .../src/tests/samples/paramSpec42.py | 51 -- .../src/tests/samples/paramSpec43.py | 17 - .../src/tests/samples/paramSpec44.py | 20 - .../src/tests/samples/paramSpec45.py | 29 - .../src/tests/samples/paramSpec46.py | 35 - .../src/tests/samples/paramSpec47.py | 32 - .../src/tests/samples/paramSpec48.py | 15 - .../src/tests/samples/paramSpec49.py | 64 -- .../src/tests/samples/paramSpec5.py | 27 - .../src/tests/samples/paramSpec50.py | 34 - .../src/tests/samples/paramSpec51.py | 51 -- .../src/tests/samples/paramSpec52.py | 19 - .../src/tests/samples/paramSpec53.py | 22 - .../src/tests/samples/paramSpec54.py | 31 - .../src/tests/samples/paramSpec55.py | 24 - .../src/tests/samples/paramSpec56.py | 58 -- .../src/tests/samples/paramSpec6.py | 15 - .../src/tests/samples/paramSpec7.py | 20 - .../src/tests/samples/paramSpec8.py | 51 -- .../src/tests/samples/paramSpec9.py | 78 -- .../src/tests/samples/paramType1.py | 59 -- .../src/tests/samples/parameters1.py | 14 - .../src/tests/samples/partial1.py | 175 ----- .../src/tests/samples/partial2.py | 29 - .../src/tests/samples/partial3.py | 31 - .../src/tests/samples/partial4.py | 36 - .../src/tests/samples/partial5.py | 50 -- .../src/tests/samples/partial6.py | 25 - .../src/tests/samples/partial7.py | 28 - .../src/tests/samples/partial8.py | 17 - .../src/tests/samples/private1.py | 55 -- .../src/tests/samples/private2.py | 11 - .../src/tests/samples/private3.py | 16 - .../src/tests/samples/private4.py | 12 - .../src/tests/samples/private5.py | 15 - .../src/tests/samples/private6.py | 10 - .../src/tests/samples/property1.py | 93 --- .../src/tests/samples/property10.py | 19 - .../src/tests/samples/property11.py | 43 -- .../src/tests/samples/property12.py | 23 - .../src/tests/samples/property13.py | 14 - .../src/tests/samples/property14.py | 23 - .../src/tests/samples/property15.py | 24 - .../src/tests/samples/property16.py | 40 - .../src/tests/samples/property17.py | 38 - .../src/tests/samples/property18.py | 44 -- .../src/tests/samples/property19.py | 39 - .../src/tests/samples/property2.py | 34 - .../src/tests/samples/property20.py | 31 - .../src/tests/samples/property21.py | 30 - .../src/tests/samples/property22.py | 30 - .../src/tests/samples/property23.py | 36 - .../src/tests/samples/property3.py | 93 --- .../src/tests/samples/property4.py | 16 - .../src/tests/samples/property5.py | 29 - .../src/tests/samples/property6.py | 35 - .../src/tests/samples/property7.py | 30 - .../src/tests/samples/property8.py | 26 - .../src/tests/samples/property9.py | 24 - .../src/tests/samples/protocol1.py | 137 ---- .../src/tests/samples/protocol10.py | 33 - .../src/tests/samples/protocol11.py | 31 - .../src/tests/samples/protocol12.py | 12 - .../src/tests/samples/protocol13.py | 19 - .../src/tests/samples/protocol14.py | 26 - .../src/tests/samples/protocol15.py | 24 - .../src/tests/samples/protocol16.py | 19 - .../src/tests/samples/protocol17.py | 95 --- .../src/tests/samples/protocol18.py | 24 - .../src/tests/samples/protocol19.py | 48 -- .../src/tests/samples/protocol2.py | 37 - .../src/tests/samples/protocol20.py | 21 - .../src/tests/samples/protocol21.py | 25 - .../src/tests/samples/protocol22.py | 39 - .../src/tests/samples/protocol23.py | 39 - .../src/tests/samples/protocol24.py | 101 --- .../src/tests/samples/protocol25.py | 28 - .../src/tests/samples/protocol26.py | 35 - .../src/tests/samples/protocol28.py | 29 - .../src/tests/samples/protocol29.py | 26 - .../src/tests/samples/protocol3.py | 328 -------- .../src/tests/samples/protocol30.py | 30 - .../src/tests/samples/protocol31.py | 21 - .../src/tests/samples/protocol32.py | 79 -- .../src/tests/samples/protocol33.py | 35 - .../src/tests/samples/protocol34.py | 20 - .../src/tests/samples/protocol35.py | 33 - .../src/tests/samples/protocol36.py | 18 - .../src/tests/samples/protocol37.py | 19 - .../src/tests/samples/protocol38.py | 38 - .../src/tests/samples/protocol39.py | 16 - .../src/tests/samples/protocol4.py | 49 -- .../src/tests/samples/protocol40.py | 39 - .../src/tests/samples/protocol41.py | 73 -- .../src/tests/samples/protocol42.py | 21 - .../src/tests/samples/protocol43.py | 37 - .../src/tests/samples/protocol44.py | 22 - .../src/tests/samples/protocol45.py | 31 - .../src/tests/samples/protocol46.py | 42 -- .../src/tests/samples/protocol47.py | 40 - .../src/tests/samples/protocol48.py | 25 - .../src/tests/samples/protocol49.py | 21 - .../src/tests/samples/protocol5.py | 25 - .../src/tests/samples/protocol50.py | 18 - .../src/tests/samples/protocol51.py | 6 - .../src/tests/samples/protocol52.py | 24 - .../src/tests/samples/protocol53.py | 212 ------ .../src/tests/samples/protocol6.py | 86 --- .../src/tests/samples/protocol7.py | 24 - .../src/tests/samples/protocol8.py | 30 - .../src/tests/samples/protocol9.py | 49 -- .../src/tests/samples/protocolExplicit1.py | 120 --- .../src/tests/samples/protocolExplicit2.pyi | 28 - .../src/tests/samples/protocolExplicit3.py | 77 -- .../src/tests/samples/protocolModule1.py | 13 - .../src/tests/samples/protocolModule2.py | 100 --- .../src/tests/samples/protocolModule3.py | 13 - .../src/tests/samples/protocolModule4.py | 25 - .../src/tests/samples/pseudoGeneric1.py | 38 - .../src/tests/samples/pseudoGeneric2.py | 38 - .../src/tests/samples/pseudoGeneric3.py | 30 - .../src/tests/samples/python2.py | 32 - .../src/tests/samples/recursiveTypeAlias1.py | 77 -- .../src/tests/samples/recursiveTypeAlias10.py | 32 - .../src/tests/samples/recursiveTypeAlias11.py | 46 -- .../src/tests/samples/recursiveTypeAlias12.py | 25 - .../src/tests/samples/recursiveTypeAlias13.py | 22 - .../src/tests/samples/recursiveTypeAlias14.py | 23 - .../src/tests/samples/recursiveTypeAlias15.py | 32 - .../src/tests/samples/recursiveTypeAlias16.py | 23 - .../src/tests/samples/recursiveTypeAlias17.py | 35 - .../src/tests/samples/recursiveTypeAlias2.py | 32 - .../src/tests/samples/recursiveTypeAlias3.py | 24 - .../src/tests/samples/recursiveTypeAlias4.py | 55 -- .../src/tests/samples/recursiveTypeAlias5.pyi | 11 - .../src/tests/samples/recursiveTypeAlias6.py | 23 - .../src/tests/samples/recursiveTypeAlias7.py | 15 - .../src/tests/samples/recursiveTypeAlias8.py | 38 - .../src/tests/samples/recursiveTypeAlias9.py | 22 - .../src/tests/samples/required1.py | 50 -- .../src/tests/samples/required2.py | 57 -- .../src/tests/samples/required3.py | 25 - .../src/tests/samples/returnTypes1.py | 42 -- .../src/tests/samples/returnTypes2.py | 59 -- .../src/tests/samples/revealedType1.py | 30 - .../src/tests/samples/self1.py | 112 --- .../src/tests/samples/self10.py | 15 - .../src/tests/samples/self11.py | 17 - .../src/tests/samples/self2.py | 196 ----- .../src/tests/samples/self3.py | 8 - .../src/tests/samples/self4.py | 15 - .../src/tests/samples/self5.py | 23 - .../src/tests/samples/self6.py | 13 - .../src/tests/samples/self7.py | 11 - .../src/tests/samples/self8.py | 26 - .../src/tests/samples/self9.py | 23 - .../src/tests/samples/sentinel1.py | 58 -- .../src/tests/samples/sentinel2.py | 32 - .../src/tests/samples/slice1.py | 15 - .../src/tests/samples/slots1.py | 63 -- .../src/tests/samples/slots2.py | 38 - .../src/tests/samples/slots3.py | 32 - .../src/tests/samples/slots4.py | 33 - .../src/tests/samples/solver1.py | 26 - .../src/tests/samples/solver10.py | 24 - .../src/tests/samples/solver11.py | 34 - .../src/tests/samples/solver12.py | 15 - .../src/tests/samples/solver13.py | 30 - .../src/tests/samples/solver14.py | 54 -- .../src/tests/samples/solver15.py | 37 - .../src/tests/samples/solver16.py | 29 - .../src/tests/samples/solver17.py | 28 - .../src/tests/samples/solver18.py | 74 -- .../src/tests/samples/solver19.py | 27 - .../src/tests/samples/solver2.py | 25 - .../src/tests/samples/solver20.py | 16 - .../src/tests/samples/solver21.py | 26 - .../src/tests/samples/solver22.py | 17 - .../src/tests/samples/solver23.py | 18 - .../src/tests/samples/solver24.py | 58 -- .../src/tests/samples/solver25.py | 25 - .../src/tests/samples/solver26.py | 10 - .../src/tests/samples/solver27.py | 52 -- .../src/tests/samples/solver28.py | 26 - .../src/tests/samples/solver29.py | 32 - .../src/tests/samples/solver3.py | 21 - .../src/tests/samples/solver30.py | 35 - .../src/tests/samples/solver31.py | 18 - .../src/tests/samples/solver32.py | 36 - .../src/tests/samples/solver33.py | 9 - .../src/tests/samples/solver34.py | 21 - .../src/tests/samples/solver35.py | 20 - .../src/tests/samples/solver36.py | 31 - .../src/tests/samples/solver37.py | 22 - .../src/tests/samples/solver38.py | 37 - .../src/tests/samples/solver39.py | 11 - .../src/tests/samples/solver4.py | 11 - .../src/tests/samples/solver40.py | 15 - .../src/tests/samples/solver41.py | 13 - .../src/tests/samples/solver42.py | 21 - .../src/tests/samples/solver43.py | 28 - .../src/tests/samples/solver44.py | 13 - .../src/tests/samples/solver45.py | 33 - .../src/tests/samples/solver5.py | 13 - .../src/tests/samples/solver6.py | 25 - .../src/tests/samples/solver7.py | 45 -- .../src/tests/samples/solver8.py | 27 - .../src/tests/samples/solver9.py | 54 -- .../src/tests/samples/solverHigherOrder1.py | 42 -- .../src/tests/samples/solverHigherOrder10.py | 17 - .../src/tests/samples/solverHigherOrder11.py | 35 - .../src/tests/samples/solverHigherOrder12.py | 26 - .../src/tests/samples/solverHigherOrder13.py | 21 - .../src/tests/samples/solverHigherOrder14.py | 34 - .../src/tests/samples/solverHigherOrder2.py | 25 - .../src/tests/samples/solverHigherOrder3.py | 32 - .../src/tests/samples/solverHigherOrder4.py | 57 -- .../src/tests/samples/solverHigherOrder5.py | 227 ------ .../src/tests/samples/solverHigherOrder6.py | 57 -- .../src/tests/samples/solverHigherOrder7.py | 12 - .../src/tests/samples/solverHigherOrder8.py | 24 - .../src/tests/samples/solverHigherOrder9.py | 27 - .../src/tests/samples/solverLiteral1.py | 65 -- .../src/tests/samples/solverLiteral2.py | 20 - .../src/tests/samples/solverScoring1.py | 45 -- .../src/tests/samples/solverScoring2.py | 66 -- .../src/tests/samples/solverScoring3.py | 13 - .../src/tests/samples/solverScoring4.py | 41 - .../src/tests/samples/solverUnknown1.py | 10 - .../src/tests/samples/specialForm1.py | 17 - .../src/tests/samples/specialForm2.py | 56 -- .../src/tests/samples/specialForm3.py | 48 -- .../src/tests/samples/specialForm4.py | 116 --- .../src/tests/samples/specialization1.py | 77 -- .../src/tests/samples/specialization2.py | 49 -- .../src/tests/samples/staticExpression1.py | 76 -- .../src/tests/samples/staticExpression2.py | 32 - .../tests/samples/staticExpressionLiteral1.py | 154 ---- .../src/tests/samples/strings1.py | 22 - .../src/tests/samples/strings2.py | 16 - .../src/tests/samples/structUnpack1.py | 99 --- .../src/tests/samples/subscript1.py | 80 -- .../src/tests/samples/subscript2.py | 55 -- .../src/tests/samples/subscript3.py | 10 - .../src/tests/samples/subscript4.py | 36 - .../src/tests/samples/super1.py | 97 --- .../src/tests/samples/super10.py | 21 - .../src/tests/samples/super11.py | 40 - .../src/tests/samples/super12.py | 15 - .../src/tests/samples/super13.py | 12 - .../src/tests/samples/super2.py | 100 --- .../src/tests/samples/super3.py | 10 - .../src/tests/samples/super4.py | 37 - .../src/tests/samples/super5.py | 28 - .../src/tests/samples/super6.py | 38 - .../src/tests/samples/super7.py | 87 --- .../src/tests/samples/super8.py | 7 - .../src/tests/samples/super9.py | 34 - .../src/tests/samples/totalOrdering1.py | 72 -- .../src/tests/samples/tryExcept1.py | 79 -- .../src/tests/samples/tryExcept10.py | 13 - .../src/tests/samples/tryExcept11.py | 22 - .../src/tests/samples/tryExcept12.py | 16 - .../src/tests/samples/tryExcept2.py | 16 - .../src/tests/samples/tryExcept3.py | 10 - .../src/tests/samples/tryExcept4.py | 49 -- .../src/tests/samples/tryExcept5.py | 30 - .../src/tests/samples/tryExcept6.py | 27 - .../src/tests/samples/tryExcept7.py | 17 - .../src/tests/samples/tryExcept8.py | 71 -- .../src/tests/samples/tryExcept9.py | 42 -- .../src/tests/samples/tstring1.py | 22 - .../src/tests/samples/tstring2.py | 20 - .../src/tests/samples/tuple1.py | 312 -------- .../src/tests/samples/tuple10.py | 30 - .../src/tests/samples/tuple11.py | 27 - .../src/tests/samples/tuple12.py | 31 - .../src/tests/samples/tuple13.py | 99 --- .../src/tests/samples/tuple15.py | 33 - .../src/tests/samples/tuple16.py | 11 - .../src/tests/samples/tuple17.py | 12 - .../src/tests/samples/tuple18.py | 17 - .../src/tests/samples/tuple19.py | 11 - .../src/tests/samples/tuple2.py | 26 - .../src/tests/samples/tuple3.py | 37 - .../src/tests/samples/tuple4.py | 21 - .../src/tests/samples/tuple5.py | 27 - .../src/tests/samples/tuple6.py | 66 -- .../src/tests/samples/tuple7.py | 59 -- .../src/tests/samples/tuple8.py | 97 --- .../src/tests/samples/tuple9.py | 14 - .../src/tests/samples/tupleUnpack1.py | 75 -- .../src/tests/samples/tupleUnpack2.py | 55 -- .../src/tests/samples/tupleUnpack3.py | 27 - .../src/tests/samples/tupleUnpack4.py | 30 - .../src/tests/samples/tupleUnpack5.py | 29 - .../src/tests/samples/type1.py | 135 ---- .../src/tests/samples/typeAlias1.py | 67 -- .../src/tests/samples/typeAlias10.py | 50 -- .../src/tests/samples/typeAlias11.py | 38 - .../src/tests/samples/typeAlias12.py | 21 - .../src/tests/samples/typeAlias13.py | 55 -- .../src/tests/samples/typeAlias14.py | 27 - .../src/tests/samples/typeAlias15.py | 23 - .../src/tests/samples/typeAlias16.py | 24 - .../src/tests/samples/typeAlias17.py | 60 -- .../src/tests/samples/typeAlias18.py | 41 - .../src/tests/samples/typeAlias19.py | 4 - .../src/tests/samples/typeAlias2.py | 26 - .../src/tests/samples/typeAlias20.py | 10 - .../src/tests/samples/typeAlias21.py | 14 - .../src/tests/samples/typeAlias22.py | 135 ---- .../src/tests/samples/typeAlias3.py | 50 -- .../src/tests/samples/typeAlias4.py | 78 -- .../src/tests/samples/typeAlias5.py | 58 -- .../src/tests/samples/typeAlias6.py | 45 -- .../src/tests/samples/typeAlias7.py | 56 -- .../src/tests/samples/typeAlias8.py | 23 - .../src/tests/samples/typeAlias9.py | 35 - .../src/tests/samples/typeAliasStatement1.py | 91 --- .../src/tests/samples/typeAliasStatement2.py | 5 - .../src/tests/samples/typeAliasStatement3.py | 18 - .../src/tests/samples/typeAliasStatement4.py | 40 - .../src/tests/samples/typeAliasStatement5.py | 16 - .../src/tests/samples/typeAliasType1.py | 63 -- .../src/tests/samples/typeAliasType2.py | 81 -- .../src/tests/samples/typeCheckOnly1.py | 40 - .../src/tests/samples/typeForm1.py | 32 - .../src/tests/samples/typeForm2.py | 231 ------ .../src/tests/samples/typeForm3.py | 27 - .../src/tests/samples/typeForm4.py | 241 ------ .../src/tests/samples/typeForm5.py | 49 -- .../src/tests/samples/typeForm6.py | 62 -- .../src/tests/samples/typeForm7.py | 22 - .../src/tests/samples/typeForm8.py | 44 -- .../src/tests/samples/typeGuard1.py | 132 ---- .../src/tests/samples/typeGuard2.py | 54 -- .../src/tests/samples/typeGuard3.py | 51 -- .../src/tests/samples/typeIgnore1.py | 10 - .../src/tests/samples/typeIgnore2.py | 20 - .../src/tests/samples/typeIgnore3.py | 22 - .../src/tests/samples/typeIgnore4.py | 10 - .../src/tests/samples/typeIgnore5.py | 7 - .../src/tests/samples/typeIs1.py | 190 ----- .../src/tests/samples/typeIs2.py | 35 - .../src/tests/samples/typeIs3.py | 51 -- .../src/tests/samples/typeIs4.py | 38 - .../src/tests/samples/typeNarrowing1.py | 68 -- .../src/tests/samples/typeNarrowing2.py | 10 - .../src/tests/samples/typeNarrowing3.py | 41 - .../src/tests/samples/typeNarrowing4.py | 22 - .../src/tests/samples/typeNarrowing5.py | 35 - .../src/tests/samples/typeNarrowing6.py | 27 - .../src/tests/samples/typeNarrowing7.py | 69 -- .../src/tests/samples/typeNarrowing8.py | 25 - .../src/tests/samples/typeNarrowingAny1.py | 37 - .../src/tests/samples/typeNarrowingAssert1.py | 21 - .../tests/samples/typeNarrowingCallable1.py | 85 --- .../src/tests/samples/typeNarrowingEnum1.py | 70 -- .../src/tests/samples/typeNarrowingEnum2.py | 77 -- .../src/tests/samples/typeNarrowingFalsy1.py | 244 ------ .../src/tests/samples/typeNarrowingIn1.py | 226 ------ .../src/tests/samples/typeNarrowingIn2.py | 25 - .../tests/samples/typeNarrowingIsClass1.py | 69 -- .../tests/samples/typeNarrowingIsEllipsis1.py | 50 -- .../src/tests/samples/typeNarrowingIsNone1.py | 115 --- .../src/tests/samples/typeNarrowingIsNone2.py | 8 - .../samples/typeNarrowingIsNoneTuple1.py | 42 -- .../samples/typeNarrowingIsNoneTuple2.py | 45 -- .../tests/samples/typeNarrowingIsinstance1.py | 291 ------- .../samples/typeNarrowingIsinstance10.py | 15 - .../samples/typeNarrowingIsinstance11.py | 18 - .../samples/typeNarrowingIsinstance12.py | 46 -- .../samples/typeNarrowingIsinstance13.py | 15 - .../samples/typeNarrowingIsinstance14.py | 26 - .../samples/typeNarrowingIsinstance15.py | 41 - .../samples/typeNarrowingIsinstance16.py | 19 - .../samples/typeNarrowingIsinstance17.py | 79 -- .../samples/typeNarrowingIsinstance18.py | 63 -- .../samples/typeNarrowingIsinstance19.py | 89 --- .../tests/samples/typeNarrowingIsinstance2.py | 50 -- .../samples/typeNarrowingIsinstance20.py | 16 - .../samples/typeNarrowingIsinstance21.py | 77 -- .../tests/samples/typeNarrowingIsinstance3.py | 93 --- .../tests/samples/typeNarrowingIsinstance4.py | 66 -- .../tests/samples/typeNarrowingIsinstance5.py | 66 -- .../tests/samples/typeNarrowingIsinstance6.py | 91 --- .../tests/samples/typeNarrowingIsinstance7.py | 19 - .../tests/samples/typeNarrowingIsinstance8.py | 27 - .../tests/samples/typeNarrowingLiteral1.py | 61 -- .../tests/samples/typeNarrowingLiteral2.py | 82 -- .../samples/typeNarrowingLiteralMember1.py | 204 ----- .../tests/samples/typeNarrowingLocalConst1.py | 133 ---- .../tests/samples/typeNarrowingNoneMember1.py | 100 --- .../src/tests/samples/typeNarrowingTuple1.py | 69 -- .../samples/typeNarrowingTupleLength1.py | 161 ---- .../tests/samples/typeNarrowingTypeEquals1.py | 110 --- .../src/tests/samples/typeNarrowingTypeIs1.py | 153 ---- .../tests/samples/typeNarrowingTypedDict1.py | 117 --- .../tests/samples/typeNarrowingTypedDict2.py | 98 --- .../tests/samples/typeNarrowingTypedDict3.py | 45 -- .../src/tests/samples/typeParams1.py | 115 --- .../src/tests/samples/typeParams2.py | 10 - .../src/tests/samples/typeParams3.py | 109 --- .../src/tests/samples/typeParams4.py | 17 - .../src/tests/samples/typeParams5.py | 58 -- .../src/tests/samples/typeParams6.py | 23 - .../src/tests/samples/typeParams7.py | 47 -- .../src/tests/samples/typeParams8.py | 13 - .../src/tests/samples/typePrinter1.py | 27 - .../src/tests/samples/typePrinter2.py | 3 - .../src/tests/samples/typePrinter3.py | 18 - .../src/tests/samples/typePromotions1.py | 43 -- .../src/tests/samples/typeVar1.py | 23 - .../src/tests/samples/typeVar10.py | 19 - .../src/tests/samples/typeVar11.py | 12 - .../src/tests/samples/typeVar2.py | 26 - .../src/tests/samples/typeVar3.py | 73 -- .../src/tests/samples/typeVar4.py | 62 -- .../src/tests/samples/typeVar5.py | 75 -- .../src/tests/samples/typeVar6.py | 115 --- .../src/tests/samples/typeVar7.py | 167 ---- .../src/tests/samples/typeVar8.py | 82 -- .../src/tests/samples/typeVar9.py | 148 ---- .../src/tests/samples/typeVarDefault1.py | 99 --- .../src/tests/samples/typeVarDefault2.py | 116 --- .../src/tests/samples/typeVarDefault3.py | 53 -- .../src/tests/samples/typeVarDefault4.py | 17 - .../src/tests/samples/typeVarDefault5.py | 30 - .../src/tests/samples/typeVarDefaultClass1.py | 130 ---- .../src/tests/samples/typeVarDefaultClass2.py | 185 ----- .../src/tests/samples/typeVarDefaultClass3.py | 142 ---- .../src/tests/samples/typeVarDefaultClass4.py | 22 - .../tests/samples/typeVarDefaultFunction1.py | 60 -- .../tests/samples/typeVarDefaultFunction2.py | 63 -- .../tests/samples/typeVarDefaultFunction3.py | 20 - .../tests/samples/typeVarDefaultTypeAlias1.py | 98 --- .../tests/samples/typeVarDefaultTypeAlias2.py | 139 ---- .../tests/samples/typeVarDefaultTypeAlias3.py | 125 --- .../src/tests/samples/typeVarTuple1.py | 62 -- .../src/tests/samples/typeVarTuple10.py | 64 -- .../src/tests/samples/typeVarTuple11.py | 71 -- .../src/tests/samples/typeVarTuple12.py | 30 - .../src/tests/samples/typeVarTuple13.py | 37 - .../src/tests/samples/typeVarTuple14.py | 109 --- .../src/tests/samples/typeVarTuple15.py | 24 - .../src/tests/samples/typeVarTuple16.py | 26 - .../src/tests/samples/typeVarTuple17.py | 57 -- .../src/tests/samples/typeVarTuple18.py | 18 - .../src/tests/samples/typeVarTuple19.py | 76 -- .../src/tests/samples/typeVarTuple2.py | 57 -- .../src/tests/samples/typeVarTuple20.py | 26 - .../src/tests/samples/typeVarTuple21.py | 19 - .../src/tests/samples/typeVarTuple22.py | 49 -- .../src/tests/samples/typeVarTuple23.py | 84 --- .../src/tests/samples/typeVarTuple24.py | 27 - .../src/tests/samples/typeVarTuple25.py | 15 - .../src/tests/samples/typeVarTuple26.py | 57 -- .../src/tests/samples/typeVarTuple27.py | 47 -- .../src/tests/samples/typeVarTuple28.py | 41 - .../src/tests/samples/typeVarTuple29.py | 30 - .../src/tests/samples/typeVarTuple3.py | 129 ---- .../src/tests/samples/typeVarTuple30.py | 12 - .../src/tests/samples/typeVarTuple31.py | 81 -- .../src/tests/samples/typeVarTuple4.py | 75 -- .../src/tests/samples/typeVarTuple5.py | 127 ---- .../src/tests/samples/typeVarTuple6.py | 109 --- .../src/tests/samples/typeVarTuple7.py | 57 -- .../src/tests/samples/typeVarTuple8.py | 116 --- .../src/tests/samples/typeVarTuple9.py | 51 -- .../src/tests/samples/typedDict1.py | 91 --- .../src/tests/samples/typedDict10.py | 34 - .../src/tests/samples/typedDict11.py | 20 - .../src/tests/samples/typedDict12.py | 123 --- .../src/tests/samples/typedDict13.py | 51 -- .../src/tests/samples/typedDict14.py | 25 - .../src/tests/samples/typedDict15.py | 51 -- .../src/tests/samples/typedDict16.py | 80 -- .../src/tests/samples/typedDict17.py | 24 - .../src/tests/samples/typedDict18.py | 134 ---- .../src/tests/samples/typedDict19.py | 59 -- .../src/tests/samples/typedDict2.py | 59 -- .../src/tests/samples/typedDict20.py | 62 -- .../src/tests/samples/typedDict21.py | 53 -- .../src/tests/samples/typedDict22.py | 11 - .../src/tests/samples/typedDict23.py | 45 -- .../src/tests/samples/typedDict24.py | 18 - .../src/tests/samples/typedDict25.py | 13 - .../src/tests/samples/typedDict3.py | 40 - .../src/tests/samples/typedDict4.py | 68 -- .../src/tests/samples/typedDict5.py | 61 -- .../src/tests/samples/typedDict6.py | 97 --- .../src/tests/samples/typedDict7.py | 22 - .../src/tests/samples/typedDict8.py | 19 - .../src/tests/samples/typedDict9.py | 47 -- .../src/tests/samples/typedDictClosed1.py | 60 -- .../src/tests/samples/typedDictClosed10.py | 15 - .../src/tests/samples/typedDictClosed2.py | 39 - .../src/tests/samples/typedDictClosed3.py | 152 ---- .../src/tests/samples/typedDictClosed4.py | 70 -- .../src/tests/samples/typedDictClosed5.py | 56 -- .../src/tests/samples/typedDictClosed6.py | 62 -- .../src/tests/samples/typedDictClosed7.py | 69 -- .../src/tests/samples/typedDictClosed8.py | 41 - .../src/tests/samples/typedDictClosed9.py | 37 - .../src/tests/samples/typedDictInline1.py | 50 -- .../src/tests/samples/typedDictReadOnly1.py | 46 -- .../src/tests/samples/typedDictReadOnly2.py | 248 ------ .../src/tests/samples/unbound1.py | 18 - .../src/tests/samples/unbound2.py | 12 - .../src/tests/samples/unbound3.py | 13 - .../src/tests/samples/unbound4.py | 25 - .../src/tests/samples/unbound5.py | 31 - .../src/tests/samples/unbound6.py | 64 -- .../src/tests/samples/unicode1.py | 42 -- .../tests/samples/uninitializedVariable1.py | 46 -- .../tests/samples/uninitializedVariable2.py | 68 -- .../tests/samples/uninitializedVariable3.py | 13 - .../src/tests/samples/unions1.py | 76 -- .../src/tests/samples/unions2.py | 15 - .../src/tests/samples/unions3.py | 49 -- .../src/tests/samples/unions4.py | 30 - .../src/tests/samples/unions5.py | 44 -- .../src/tests/samples/unions6.py | 58 -- .../src/tests/samples/unnecessaryCast1.py | 57 -- .../src/tests/samples/unnecessaryContains1.py | 65 -- .../tests/samples/unnecessaryIsInstance1.py | 83 -- .../tests/samples/unnecessaryIsInstance2.py | 35 - .../tests/samples/unnecessaryIsSubclass1.py | 20 - .../src/tests/samples/unpack1.py | 53 -- .../src/tests/samples/unpack2.py | 27 - .../src/tests/samples/unpack3.py | 16 - .../src/tests/samples/unpack4.py | 19 - .../src/tests/samples/unpack5.py | 86 --- .../src/tests/samples/unreachable1.py | 132 ---- .../src/tests/samples/unusedCallResult1.py | 67 -- .../src/tests/samples/unusedCoroutine1.py | 23 - .../src/tests/samples/unusedExpression1.py | 50 -- .../src/tests/samples/unusedImport1.py | 5 - .../src/tests/samples/unusedImport2.py | 17 - .../src/tests/samples/unusedVariable1.py | 21 - .../src/tests/samples/viperComment1.py | 28 - .../src/tests/samples/viperIgnore1.py | 15 - .../src/tests/samples/viperIgnore2.py | 22 - .../src/tests/samples/with1.py | 115 --- .../src/tests/samples/with2.py | 78 -- .../src/tests/samples/with3.py | 81 -- .../src/tests/samples/with4.py | 24 - .../src/tests/samples/with5.py | 31 - .../src/tests/samples/with6.py | 22 - .../src/tests/samples/with7.py | 38 - 1269 files changed, 61780 deletions(-) delete mode 100644 packages/vipeye-internal/src/tests/harness/fourslash/runner.ts delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/abstractClass9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotated1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotated2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotatedVar8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotations1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotations2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotations3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotations4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotations5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/annotations6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/any1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assert1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assertType1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignment9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/assignmentExpr9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/async1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/augmentedAssignment1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/augmentedAssignment2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/augmentedAssignment3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/autoVariance1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/autoVariance2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/autoVariance3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/autoVariance4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/autoVariance5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/await1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/await2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/await3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/builtins1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/builtins2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/call9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callSite1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callSite2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callSite3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callable7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/callbackProtocol9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/capturedVariable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/capturedVariable2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/circular1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/circular2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/circularBaseClass.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classGetItem1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classVar7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/classes9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/codeFlow9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comparison1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comparison2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/complex1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/comprehension9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/conditional1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constant1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constants1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constrainedTypeVar9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor32.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor33.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructor9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructorCallable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/constructorCallable2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/coroutines1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/coroutines2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/coroutines3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/coroutines4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclass9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassConverter1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassConverter2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassConverter3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassDescriptors1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassDescriptors2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassFrozen1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassHash1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassKwOnly1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassKwOnly2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassNamedTuple1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassNamedTuple2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassPostInit1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassReplace1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassSlots1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassTransform1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassTransform2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassTransform3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dataclassTransform4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/decorator7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/defaultInitializer1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/del1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/del2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecated8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecatedAlias1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/deprecatedAlias2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/descriptor1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/descriptor2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/descriptor3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/descriptor4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dictionary1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dictionary2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dictionary3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dictionary4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dunderAll1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dunderAll2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/dunderAll3.pyi delete mode 100644 packages/vipeye-internal/src/tests/samples/duplicateDeclaration1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/duplicateDeclaration2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/duplicateImports1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/ellipsis1.pyi delete mode 100644 packages/vipeye-internal/src/tests/samples/emptyContainers1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enum9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enumAuto1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/enumGenNextValue1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/exceptionGroup1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/expression9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/final1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/final2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/final3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/final4.pyi delete mode 100644 packages/vipeye-internal/src/tests/samples/final5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/final6.pyi delete mode 100644 packages/vipeye-internal/src/tests/samples/final7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/final8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/forLoop1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/forLoop2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/fstring1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/fstring2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/fstring3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/fstring4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/fstring5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/function9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionAnnotation1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionAnnotation2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionAnnotation3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionAnnotation4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionAssignabilityMessage1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionMember1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/functionMember2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/futureImport1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/futureImport2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/futureImport3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generator9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generic1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generic2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/generic3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType32.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType33.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType34.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType35.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType36.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType37.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType38.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType39.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType40.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType41.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType42.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType43.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType44.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType45.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType46.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType47.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/genericType9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/hashability1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/hashability2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/hashability3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/import9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/inconsistentConstructor1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/index1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/inferredTypes1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/inferredTypes2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/inferredTypes3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/initVar1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/initsubclass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/initsubclass2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/initsubclass3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/isinstance1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/isinstance2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/isinstance3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/isinstance4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/isinstance5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/isinstance6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/kwargsUnpack1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/kwargsUnpack2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lambda9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/lazyImport1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/list1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/list2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/list3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literalForLoop1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literalString1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literalString2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literalString3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/literals7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop32.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop33.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop34.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop35.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop36.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop37.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop38.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop39.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop40.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop41.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop42.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop43.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop44.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop45.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop46.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop47.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop48.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop49.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop50.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop51.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop52.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/loop9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/match1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/match2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/match3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchClass8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchExhaustion1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchLiteral1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchLiteral2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchMapping1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchNamedTupleGeneric1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchSequence1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchSequence2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchSequenceVariadic.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchUnnecessary1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/matchValue1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/memberAccess9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/metaclass9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverride7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methodOverrideCallable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/methods1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/missingSuper1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/missingTypeArg1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/module1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/module2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/module3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/mro1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/mro2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/mro3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/mro4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/nameBinding1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/nameBinding2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/nameBinding3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/nameBinding4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/nameBinding5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/namedTuple9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/never1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/never2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newType7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/newTypeIsLiteral1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/noTypeCheck1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/none1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/none2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/noreturn1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/noreturn2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/noreturn3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/noreturn4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/operator9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/optional1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/optional2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overload1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overload2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overload3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overload4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overload5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadCall9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadImpl1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadImpl2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadImpl3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadOverlap1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/overloadOverride1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/override1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/override2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramInference1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramInference2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramNames1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec32.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec33.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec34.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec35.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec36.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec37.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec38.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec39.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec40.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec41.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec42.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec43.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec44.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec45.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec46.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec47.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec48.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec49.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec50.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec51.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec52.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec53.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec54.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec55.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec56.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramSpec9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/paramType1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/parameters1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/partial8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/private1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/private2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/private3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/private4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/private5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/private6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/property9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol32.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol33.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol34.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol35.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol36.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol37.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol38.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol39.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol40.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol41.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol42.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol43.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol44.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol45.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol46.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol47.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol48.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol49.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol50.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol51.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol52.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol53.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocol9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolExplicit1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolExplicit2.pyi delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolExplicit3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolModule1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolModule2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolModule3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/protocolModule4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/pseudoGeneric1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/pseudoGeneric2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/pseudoGeneric3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/python2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias5.pyi delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/recursiveTypeAlias9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/required1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/required2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/required3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/returnTypes1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/returnTypes2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/revealedType1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/self9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/sentinel1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/sentinel2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/slice1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/slots1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/slots2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/slots3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/slots4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver32.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver33.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver34.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver35.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver36.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver37.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver38.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver39.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver40.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver41.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver42.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver43.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver44.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver45.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solver9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverHigherOrder9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverLiteral1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverLiteral2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverScoring1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverScoring2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverScoring3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverScoring4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/solverUnknown1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/specialForm1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/specialForm2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/specialForm3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/specialForm4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/specialization1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/specialization2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/staticExpression1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/staticExpression2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/staticExpressionLiteral1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/strings1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/strings2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/structUnpack1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/subscript1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/subscript2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/subscript3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/subscript4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/super9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/totalOrdering1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tryExcept9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tstring1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tstring2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tuple9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tupleUnpack1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tupleUnpack2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tupleUnpack3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tupleUnpack4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/tupleUnpack5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/type1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAlias9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasStatement1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasStatement2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasStatement3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasStatement4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasStatement5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasType1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeAliasType2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeCheckOnly1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeForm8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeGuard1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeGuard2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeGuard3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIgnore1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIgnore2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIgnore3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIgnore4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIgnore5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIs1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIs2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIs3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeIs4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowing8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingAny1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingAssert1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingCallable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingEnum1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingEnum2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingFalsy1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIn1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIn2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsClass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsEllipsis1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingLiteralMember1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingLocalConst1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingNoneMember1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTuple1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTupleLength1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTypeEquals1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTypeIs1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeParams8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typePrinter1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typePrinter2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typePrinter3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typePromotions1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVar9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefault1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefault2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefault3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefault4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefault5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultClass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultClass2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultClass3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultClass4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple26.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple27.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple28.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple29.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple30.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple31.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typeVarTuple9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict11.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict12.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict13.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict14.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict15.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict16.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict17.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict18.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict19.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict20.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict21.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict22.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict23.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict24.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict25.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDict9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed10.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed7.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed8.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictClosed9.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictInline1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictReadOnly1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/typedDictReadOnly2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unbound1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unbound2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unbound3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unbound4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unbound5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unbound6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unicode1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/uninitializedVariable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/uninitializedVariable2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/uninitializedVariable3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unions1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unions2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unions3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unions4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unions5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unions6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unnecessaryCast1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unnecessaryContains1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unnecessaryIsSubclass1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unpack1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unpack2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unpack3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unpack4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unpack5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unreachable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unusedCallResult1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unusedCoroutine1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unusedExpression1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unusedImport1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unusedImport2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/unusedVariable1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/viperComment1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/viperIgnore1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/viperIgnore2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with1.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with2.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with3.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with4.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with5.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with6.py delete mode 100644 packages/vipeye-internal/src/tests/samples/with7.py diff --git a/packages/vipeye-internal/src/tests/harness/fourslash/runner.ts b/packages/vipeye-internal/src/tests/harness/fourslash/runner.ts deleted file mode 100644 index 79f07fe9..00000000 --- a/packages/vipeye-internal/src/tests/harness/fourslash/runner.ts +++ /dev/null @@ -1,93 +0,0 @@ -/* - * runner.ts - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - * - * Provide APIs to run fourslash tests from provided fourslash markup contents - */ - -import * as ts from 'typescript'; - -import { combinePaths } from '../../../common/pathUtils'; -import * as host from '../testHost'; -import { parseTestData } from './fourSlashParser'; -import { FourSlashData } from './fourSlashTypes'; -import { TestState, TestStateOptions } from './testState'; -import { Consts } from './testState.Consts'; - -export type TestStateFactory = (basePath: string, testData: FourSlashData, options?: TestStateOptions) => TestState; - -/** - * run given fourslash test file - * - * @param basePath this is used as a base path of the virtual file system the test will run upon - * @param fileName this is the file path where fourslash test file will be read from - */ -export function runFourSlashTest( - basePath: string, - fileName: string, - cb?: jest.DoneCallback, - stateOptions?: TestStateOptions, - testStateFactory?: TestStateFactory -) { - const content = host.HOST.readFile(fileName)!; - runFourSlashTestContent(basePath, fileName, content, cb, stateOptions, testStateFactory); -} - -/** - * run given fourslash markup content - * - * @param basePath this is used as a base path of the virtual file system the test will run upon - * @param fileName this will be used as a filename of the given `content` in the virtual file system - * if fourslash markup `content` doesn't have explicit `@filename` option - * @param content this is fourslash markup string - */ -export function runFourSlashTestContent( - basePath: string, - fileName: string, - content: string, - cb?: jest.DoneCallback, - stateOptions?: TestStateOptions, - testStateFactory?: TestStateFactory -) { - // give file paths an absolute path for the virtual file system - const absoluteBasePath = combinePaths('/', basePath); - const absoluteFileName = combinePaths('/', fileName); - - // parse out the files and their metadata - const testData = parseTestData(absoluteBasePath, content, absoluteFileName); - const state = - testStateFactory !== undefined - ? testStateFactory(absoluteBasePath, testData, stateOptions) - : new TestState(absoluteBasePath, testData, stateOptions); - const output = ts.transpileModule(content, { - reportDiagnostics: true, - compilerOptions: { target: ts.ScriptTarget.ES2019 }, - }); - if (output.diagnostics!.length > 0) { - throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics![0].messageText}`); - } - - runCode(output.outputText, state, cb); -} - -async function runCode(code: string, state: TestState, cb?: jest.DoneCallback) { - // Compile and execute the test - try { - const wrappedCode = `(async function(helper, Consts) { -${code} -})`; - const f = eval(wrappedCode); // CodeQL [SM01632] test code that doesn't need to be secure. - await f(state, Consts); - markDone(); - } catch (ex) { - markDone(ex); - } - - function markDone(...args: any[]) { - if (cb) { - cb(...args); - } - state.dispose(); - } -} diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass1.py b/packages/vipeye-internal/src/tests/samples/abstractClass1.py deleted file mode 100644 index 5a4f916d..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass1.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests the type analyzer's ability to flag attempts -# to instantiate abstract base classes. - -from abc import ABC, abstractmethod - - -class AbstractClassA(ABC): - @abstractmethod - def foo1(self): - pass - - @abstractmethod - def foo2(self): - pass - - def foo3(self): - return 3 - - @classmethod - def foo4(cls): - # This should not generate an error even though - # it would appear to be attempting to instantiate - # an abstract class. That's because we need to - # assume that the caller is making this call on - # a non-abstract subclass. - return cls() - - -v1 = [subclass() for subclass in AbstractClassA.__subclasses__()] -reveal_type(v1, expected_text="list[AbstractClassA]") - - -# This should generate an error because AbstractFoo -# is an abstract class. -a = AbstractClassA() - - -class AbstractClassB(AbstractClassA): - def foo1(self): - pass - - -# This should generate an error because AbstractBar1 -# is an abstract class. -b = AbstractClassB() - - -class AbstractClassC(AbstractClassB): - def foo2(self): - pass - - -# This should not generate an error because AbstractBar2 -# overrides all of the abstract methods it inherits. -c = AbstractClassC() diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass10.py b/packages/vipeye-internal/src/tests/samples/abstractClass10.py deleted file mode 100644 index 3a6624dd..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass10.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests the detection of static or class method invocations -# where the method is marked abstract. - -from abc import ABC, abstractmethod - - -class A(ABC): - @staticmethod - @abstractmethod - def method1() -> None: ... - - @staticmethod - @abstractmethod - def method2() -> None: - pass - - @classmethod - @abstractmethod - def method3(cls) -> None: - raise NotImplementedError - - @classmethod - @abstractmethod - def method4(cls) -> None: - pass - - -# This should generate an error. -A.method1() - -A.method2() - -# This should generate an error. -A.method3() - -A.method4() - - -class B(A): - @staticmethod - def method1() -> None: - # This should generate an error. - return super(B).method1() - - @staticmethod - def method2() -> None: - return super(B).method2() - - @classmethod - def method3(cls) -> None: - # This should generate an error. - return super().method3() - - @classmethod - def method4(cls) -> None: - return super().method4() - - -B.method1() -B.method2() - - -def func1(a: type[A]): - a.method1() - a.method3() - - -class C(A): ... - - -# This should generate an error. -C.method1() - -# This should generate an error. -C.method3() diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass11.py b/packages/vipeye-internal/src/tests/samples/abstractClass11.py deleted file mode 100644 index 21a77820..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass11.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the handling of a class that is created from a subclass -# of ABCMeta. - -from abc import ABCMeta, abstractmethod -from typing import final - - -class CustomMeta(ABCMeta): - pass - - -class A(metaclass=CustomMeta): - @abstractmethod - def abstract(self): - pass - - -@final -# This should generate an error. -class B(A): - pass - - -# This should generate an error. -B() diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass2.py b/packages/vipeye-internal/src/tests/samples/abstractClass2.py deleted file mode 100644 index dcbed833..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass2.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the cases where a mixin class -# overrides an abstract method, making it no longer abstract. - -import abc - - -class InterfaceA(abc.ABC): - @abc.abstractmethod - def a(self) -> None: - print("InterfaceA.a") - - -class MixinA(InterfaceA): - def a(self) -> None: - print("MixinA.a") - - -class InterfaceAB(InterfaceA): - @abc.abstractmethod - def b(self) -> None: - print("InterfaceAB.b") - - -class ClassAB(InterfaceAB, MixinA): - def b(self) -> None: - print("ClassAB.b") - - -ab = ClassAB() -ab.a() diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass3.py b/packages/vipeye-internal/src/tests/samples/abstractClass3.py deleted file mode 100644 index ada173ee..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass3.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the checks for abstract method -# overrides. They depend on the order of the subclasses. - -import abc - - -class MixinA(abc.ABC): - pass - - -class MixinB(abc.ABC): - def get_model(self): - print("MixinB.get_model") - - -class MixinC(abc.ABC): - @abc.abstractmethod - def get_model(self): - pass - - def use_model(self): - print("MixinC.get_model") - - -class Trainer_1a(MixinA, MixinB, MixinC): - pass - - -# This should not generate an error -trainer = Trainer_1a() diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass4.py b/packages/vipeye-internal/src/tests/samples/abstractClass4.py deleted file mode 100644 index 52c70313..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass4.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the checks for abstract method -# overrides. They depend on the order of the subclasses. - -import abc - - -class MixinA(abc.ABC): - pass - - -class MixinB(abc.ABC): - def get_model(self): - print("MixinB.get_model") - - -class MixinC(abc.ABC): - @abc.abstractmethod - def get_model(self): - pass - - def use_model(self): - print("MixinC.get_model") - - -class Trainer_1b(MixinA, MixinC, MixinB): - pass - - -# This should generate an error -trainer = Trainer_1b() diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass5.py b/packages/vipeye-internal/src/tests/samples/abstractClass5.py deleted file mode 100644 index 4e1932a8..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass5.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the type checker's reporting of abstract -# overload mismatches. - -from abc import ABC, abstractmethod -from typing import Union, overload - - -class ClassA(ABC): - @overload - def func1(self, a: int) -> int: - pass - - @overload - @abstractmethod - # This should generate an error because this overload is - # missing an abstractmethod overload. - def func1(self, a: float) -> float: - pass - - @overload - def func1(self, a: str) -> str: ... - - def func1(self, a: Union[int, float, str]) -> Union[int, float, str]: - raise NotImplementedError() - - @overload - def func2(self, a: str) -> str: ... - - @overload - @abstractmethod - def func2(self, a: int) -> int: - pass - - @abstractmethod - def func2(self, a: Union[int, str]) -> Union[int, str]: - raise NotImplementedError() - - @overload - def func3(self, a: str) -> str: # viper: ignore[reportNoOverloadImplementation] - ... - - @overload - @abstractmethod - # This should generate an error because the abstract status is inconsistent. - def func3(self, a: int) -> int: ... - - @overload - @abstractmethod - def func4(self, a: str) -> str: # viper: ignore[reportNoOverloadImplementation] - ... - - @overload - # This should generate an error because the abstract status is inconsistent. - def func4(self, a: int) -> int: ... diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass6.py b/packages/vipeye-internal/src/tests/samples/abstractClass6.py deleted file mode 100644 index 38d0feee..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass6.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample validates that a variable that is annotated as -# Type[X] where X refers to an abstract base class does not -# emit an error when the variable is instantiated. - -from abc import ABC, abstractmethod -from typing import Type, TypeVar - - -class Base(ABC): - @abstractmethod - def method1(self, x: int) -> int: - pass - - -def func1(base_cls: Type[Base]): - base_cls() - - -def func2(): - # This should generate an error. - Base() - - -def func3(base_cls: type[Base]): - base_cls() - - -T = TypeVar("T") - - -def create_instance(cls: Type[T]) -> T: - return cls() - - -def func4(): - base = create_instance(Base) - base.method1(1) diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass7.py b/packages/vipeye-internal/src/tests/samples/abstractClass7.py deleted file mode 100644 index bfe40cc1..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass7.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample verifies that Protocol classes are treated as -# abstract even though they don't derive from ABCMeta. - -from typing import Protocol, Tuple -from abc import abstractmethod - - -class RGB(Protocol): - rgb: Tuple[int, int, int] - - @abstractmethod - def intensity(self) -> int: - return 0 - - -class Point(RGB): - def __init__(self, red: int, green: int, blue: int) -> None: - self.rgb = red, green, blue - - -# This should generate an error because "intensity" is not implemented. -p = Point(1, 2, 3) diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass8.py b/packages/vipeye-internal/src/tests/samples/abstractClass8.py deleted file mode 100644 index e12f1ddf..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass8.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the check for abstract methods on a final class. - -from typing import final -from abc import ABC, abstractmethod - - -class Foo(ABC): - @abstractmethod - def foo(self): - pass - - -class Bar(Foo): - @abstractmethod - def bar(self): - pass - - @abstractmethod - def bar2(self): - pass - - -@final -# This should generate an error because Foo.foo, Bar.bar, and Bar.bar1 -# are abstract. -class Baz(Bar): ... diff --git a/packages/vipeye-internal/src/tests/samples/abstractClass9.py b/packages/vipeye-internal/src/tests/samples/abstractClass9.py deleted file mode 100644 index ae8002fd..00000000 --- a/packages/vipeye-internal/src/tests/samples/abstractClass9.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests that named tuple fields override abstract methods. - -# viper: reportIncompatibleVariableOverride=false - -from abc import ABC, abstractmethod -from typing import NamedTuple - - -class ClassA(ABC): - @property - @abstractmethod - def myproperty(self) -> str: ... - - -MixinB = NamedTuple("MixinB", [("myproperty", str)]) - - -class ClassB(MixinB, ClassA): - pass - - -ClassB(myproperty="myproperty") diff --git a/packages/vipeye-internal/src/tests/samples/annotated1.py b/packages/vipeye-internal/src/tests/samples/annotated1.py deleted file mode 100644 index 5993c530..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotated1.py +++ /dev/null @@ -1,102 +0,0 @@ -# This sample tests handling of the Python 3.9 "Annotated" feature -# described in PEP 593. - -from dataclasses import InitVar, dataclass -from typing import Annotated, ClassVar, Final, TypeVar - - -class struct2: - @staticmethod - def ctype(a: str): - pass - - class Packed: - pass - - -UnsignedShort = Annotated[int, struct2.ctype("H")] -SignedChar = Annotated[int, struct2.ctype("b")] - - -class Student(struct2.Packed): - name: Annotated[str, struct2.ctype("<10s")] - serial_num: UnsignedShort - school: SignedChar - - -def ValueRange(a: int, b: int): - pass - - -T1 = Annotated[int, ValueRange(-10, 5)] -T2 = Annotated[T1, ValueRange(-20, 3)] - -a: Annotated[Annotated[int, "hi"], "hi"] = 3 -b: T2 = 5 - -TypeWithStringArg = Annotated["int", "this string should not be parsed"] - - -def func2(a: TypeWithStringArg): - return 3 - - -# This should generate an error because the first type argument -# is not a valid type. -c: Annotated["this", "should generate an error"] - -# This should generate an error because all Annotated types should -# include at least two type arguments. -d: Annotated[int] - -# Verify that generic type aliases can be defined using Annotated. -_T = TypeVar("_T") -Param = Annotated[_T, "x"] - -x1: Param[int] = 3 -print(Param[int]) - - -class A: - classvar: Annotated[ClassVar[int], (2, 5)] = 4 - const: Annotated[Final[int], "metadata"] = 4 - - -@dataclass -class B: - x: Annotated[InitVar[int], "metadata"] - - -d1 = B(x=4) - -# This should generate an error because x is not an actual member. -d1.x - -Alias1 = Annotated[_T, ""] -Alias2 = str -Alias3 = Alias1[Alias2] - -reveal_type(Alias3, expected_text="type[str]") - -x2: Annotated[str, [*(1, 2)]] -x3: Annotated[str, (temp := 1)] - - -async def func3(): - x4: Annotated[str, await func3()] - - -x5: Annotated[str, f""] -x6: Annotated[str, "abc"] -x7: Annotated[str, "a\nb"] -x8: Annotated[str, *(1, 2, 3)] - - -def func4(): - return Annotated[int, 2 + 2] - - -reveal_type(func4(), expected_text="Annotated") - -x9 = list[Annotated[int, ""]]() -reveal_type(x9, expected_text="list[int]") diff --git a/packages/vipeye-internal/src/tests/samples/annotated2.py b/packages/vipeye-internal/src/tests/samples/annotated2.py deleted file mode 100644 index a9226f80..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotated2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where Annotated is used with deferred -# annotation evaluation. - -from __future__ import annotations -from typing import Annotated - - -v1: Annotated[str, ClassA, func1(), v2[0]] = "" - -v2 = [1, 2, 3] - - -class ClassA: ... - - -def func1(): ... diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar1.py b/packages/vipeye-internal/src/tests/samples/annotatedVar1.py deleted file mode 100644 index 0094dcae..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar1.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests type annotations on variables. - -array1 = [1, 2, 3] - -# This should generate an error because the LHS can't -# have a declared type. -array1[2] = 4 # type: int - -dict1 = {} - -# This should generate an error because the LHS can't -# have a declared type. -dict1["hello"] = 4 # type: int - - -def foo(): - a: int = 3 - b: float = 4.5 - c: str = "" - d: int = yield 42 diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar2.py b/packages/vipeye-internal/src/tests/samples/annotatedVar2.py deleted file mode 100644 index 76ed1e13..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar2.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests annotated types on global variables. - -# This should generate an error because the declared -# type below does not match the assigned type. -glob_var1 = 4 - -# This should generate an error because the declared -# type doesn't match the later declared type. -glob_var1 = Exception() # type: str - -glob_var1 = Exception() # type: Exception - -# This should generate an error because the assigned -# type doesn't match the declared type. -glob_var1 = "hello" # type: Exception - -# This should generate an error. -glob_var2 = 5 - - -def func1(): - global glob_var1 - global glob_var2 - - # This should generate an error. - glob_var1 = 3 - - glob_var2 = "hello" # type: str diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar3.py b/packages/vipeye-internal/src/tests/samples/annotatedVar3.py deleted file mode 100644 index a979cf7a..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar3.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests annotated types on local variables. - -from typing import Any, Optional, Union - - -class ClassB(object): - def __enter__(self) -> bytes: - return b"hello" - - def __exit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -def func2(): - local_var = 3 # type: Union[int, str] - local_var = "hello" - - # This should generate an error because the assigned - # type doesn't match the declared type. - local_var = b"hello" - - local_var2 = 3 # type: int - - if local_var: - # This should generate an error because the - # assigned type doesn't match. - local_var = 3.4 - else: - # This should generate an error because the assigned - # type doesn't match the declared type. - local_var2 = b"hello" - - # This should generate an error because the declared type - # of local_var is not compatible. - with ClassB() as local_var: - pass - - bytes_list = [b"hello"] - - # This should generate an error because the declared type - # of local_var is not compatible. - for local_var in bytes_list: - pass - - # This should generate an error. - (local_var, local_var2) = (b"hello", 3) - - # This should generate an error. - (local_var, local_var2) = ("hello", b"h") diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar4.py b/packages/vipeye-internal/src/tests/samples/annotatedVar4.py deleted file mode 100644 index df13ede8..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar4.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests annotated types for class variables. - - -class ClassA(object): - # This should generate an error because the declared - # type doesn't match the latter declared type. - class_var1 = 4 # type: str - - # This should generate an error because the assigned - # value doesn't match the declared type. - class_var1 = "hello" # type: int - - class_var1 = 3 # type: int - - # This should generate an error because the declared - # type doesn't match the latter declared type. - class_var2 = 3 # type: int - - def __init__(self): - # This should generate an error because the assigned - # type doesn't match the declared type. - self.class_var2 = 3 # type: str - - self.class_var2 = "hello" diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar5.py b/packages/vipeye-internal/src/tests/samples/annotatedVar5.py deleted file mode 100644 index bb56dbf0..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar5.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests type annotations for instance variables. - - -class ClassC(object): - def __init__(self): - self.inst_var1 = 3 - - @property - def prop1(self): - return 1 - - @prop1.setter - def prop1(self, val): - pass - - def foo(self): - # This should generate an error because the assigned - # type doesn't match the declared type. - self.inst_var1 = 3 # type: str - - self.inst_var1: str = "hello" - - # This should generate an error because the declared - # type doesn't match the previously declared type. - self.inst_var1: int = "hello" - - # This should generate an error because the assigned - # type doesn't match the declared type. - self.inst_var1 = "hello" # type: int - - self.prop1 = 3 - - -class ClassE(ClassC): - def __init__(self): - # This should generate an error. - self.inst_var1 = 3 diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar6.py b/packages/vipeye-internal/src/tests/samples/annotatedVar6.py deleted file mode 100644 index 7cb8db34..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar6.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests that class-scoped variables with a declared type -# but without a ClassVar designation are treated as instance variables. -# Notably, Callable variables should be assumed to be pre-bound to -# the object. - -from typing import Callable - - -def add1(n: int): - return n + 1 - - -class Foo: - f: Callable[[int], int] - - def m(self): - print(self.f(1)) - - -foo = Foo() -foo.f = add1 -foo.m() diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar7.py b/packages/vipeye-internal/src/tests/samples/annotatedVar7.py deleted file mode 100644 index cda75b1e..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar7.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the reportTypeCommentUsage diagnostic check. - -# This should generate an error if reportTypeCommentUsage is enabled. -x = 3 # type: int - - -class Foo: - # This should generate an error if reportTypeCommentUsage is enabled. - y = 0 # type: int - - def __init__(self): - # This should generate an error if reportTypeCommentUsage is enabled. - self.x = 2 # type: int diff --git a/packages/vipeye-internal/src/tests/samples/annotatedVar8.py b/packages/vipeye-internal/src/tests/samples/annotatedVar8.py deleted file mode 100644 index 3d90b3d0..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotatedVar8.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests that incompatible types implicitly assigned -# to an annotated variable via an import statement are flagged -# as an error. - -from typing import Callable, Final - -# This should generate an error because random is already declared. -import random - -random: int = 3 - -# This should generate an error because os is Final -import os.path - -os: Final = 3 - - -# This should generate an error because x is already declared. -from math import pow as x - -x: Callable[[], None] - -# This should generate an error because pow is already declared. -from math import pow - -pow: int = 3 - -y: Callable[[float, float], float] -from math import pow as y diff --git a/packages/vipeye-internal/src/tests/samples/annotations1.py b/packages/vipeye-internal/src/tests/samples/annotations1.py deleted file mode 100644 index 78ab76ac..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotations1.py +++ /dev/null @@ -1,159 +0,0 @@ -# This sample tests the handling of type annotations within a -# python source file (as opposed to a stub file). - -from typing import Any, Callable, TypeVar, Union -import uuid -from datetime import datetime - - -class ClassA: - # This should generate an error because ClassA - # is not yet defined at the time it's used. - def func0(self) -> ClassA | None: - return None - - -class ClassB(ClassA): - def func1(self) -> ClassA: - return ClassA() - - # This should generate an error because ClassC - # is a forward reference, which is not allowed - # in a python source file. - def func2(self) -> ClassC | None: - return None - - def func3(self) -> "ClassC | None": - return None - - def func4(self) -> "ClassC | None": - return None - - def func5(self) -> "int | None": - return None - - -class ClassC: - pass - - -def func10(): - pass - - -# This should generate an error because function calls -# are not allowed within a type annotation. -x1: func10() - -x2: """ - Union[ - int, - str - ] -""" - - -class ClassD: - ClassA: "ClassA" - - # This should generate an error because ClassF refers - # to itself, and there is no ClassF declared at the module - # level. It should also generate a second error because - # ClassF is a variable and can't be used as an annotation. - ClassF: "ClassF" - - str: "str" - - def int(self): ... - - foo: "int" - - # This should generate an error because it refers to the local - # "int" symbol rather than the builtins "int". - bar: int - - -# This should generate an error because modules are not allowed in -# type annotations. -x3: typing - - -class ClassG: - uuid = uuid.uuid4() - - -class ClassH: - # This should generate an error because uuid refers to the local - # symbol in this case, which is a circular reference. - uuid: uuid.UUID = uuid.uuid4() - - -def func11(): - for t in [str, float]: - # This should generate an error because t is not a valid annotation. - def f(x: str) -> t: - return t(x) + 1 - - f("") - - -def func12(x: type[int]): - # These should not generate an error because they are used - # in a location that is not considered a type annotation, so the - # normal annotation limitations do not apply here. - print(Union[x, x]) - print(x | None) - - -# This should generate an error because x4 isn't defined. -x4: int = x4 - - -class ClassJ: - datetime: datetime - - -T = TypeVar("T") - - -x5: type[int] = int - -# This should generate an error because variables are not allowed -# in a type annotation. -x6: x5 = 1 - -# This should generate an error because variables are not allowed -# in a type annotation. -x7: list[x5] = [1] - -# This should generate an error because a Callable isn't allowed -# in a "type". -x8: type[Callable] - -# This should generate an error because a Callable isn't allowed -# in a "type". -x9: type[func11] - -# This should generate an error because a Callable isn't allowed -# in a "type". -x10: type[Callable[..., Any]] - -# This should generate an error because raw strings aren't allowed. -x11: r"int" - -# This should generate an error because bytes strings aren't allowed. -x12: b"int" - -# This should generate an error because format strings aren't allowed. -x13: f"int" - - -class A: - def method1(self): - # This should result in an error. - x: self - - @classmethod - def method2(cls): - # This should result in an error. - x: cls diff --git a/packages/vipeye-internal/src/tests/samples/annotations2.py b/packages/vipeye-internal/src/tests/samples/annotations2.py deleted file mode 100644 index fea1ce5b..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotations2.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the parser and type checker's ability to use -# type annotations in comments following assignment expressions. -# These are used in some older typestub files because they're -# compatible with versions of Python before 3.6. - -from typing import List, Optional, Tuple - -a = 3 # type: int - -b = "3" # type: str - -c = [1, 2, 3] # type: Optional[List[int]] - - -# A type on the next line shouldn't be honored -d = "hello" -# type: int - -# A type comment with a space between the type and -# the colon is also not honored. -e = "hello" # type : int - -# Neither is a capital "Type" -f = "hello" # Type: int - - -# This should generate an error because the type doesn't match -g = "hello" # type: int - - -# This should generate an error because the last entry -# of the tuple is the wrong type. -h = (1, "hello", (5,)) # type: Tuple[int, str, Tuple[str]] diff --git a/packages/vipeye-internal/src/tests/samples/annotations3.py b/packages/vipeye-internal/src/tests/samples/annotations3.py deleted file mode 100644 index a05db66b..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotations3.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the handling of type annotations within a -# python source file with the __future__ annotations symbol present. - -from __future__ import annotations - -from typing import Optional - - -class ClassA: - def func0(self) -> Optional[ClassA]: - return None - - -class ClassB(ClassA): - def func1(self) -> ClassA: - return ClassA() - - def func2(self) -> Optional[ClassC]: - return None - - def func3(self) -> "Optional[ClassC]": - return None - - def func4(self) -> Optional["ClassC"]: - return None - - def func5(self, x: ClassA): - x.func0() - - class ClassA: ... - - def func6(self, x: ClassC): - x.my_int - - -class ClassC: - my_int: int diff --git a/packages/vipeye-internal/src/tests/samples/annotations4.py b/packages/vipeye-internal/src/tests/samples/annotations4.py deleted file mode 100644 index 2ed6621e..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotations4.py +++ /dev/null @@ -1,67 +0,0 @@ -# This sample tests the type checker's reporting of -# incompatible declared types. - -from collections.abc import Callable - - -def a(): - pass - - -# This should generate an error for an incompatible assignment. -a = 1 - - -# This should generate an error for an obscured type. -def b(): - pass - - -b: int = 1 - -# This should generate an error for an obscured type. -c: int = 1 -c: float = 1.1 - -# This should generate two errors - one for an -# obscured type, the second for an incompatible assignment. -d: int = 2 - - -def d(): - pass - - -class Foo: - # This should generate an error because aa is redeclared. - aa: int - - def aa(self): - return 3 - - -# This should generate two errors, one for each param. -def my_func(param1: int, param2): - param1: int = 3 - param2: int = 4 - - -# This should be fine because both declarations of 'e' -# use the same type. -e: list[int] -e = [3] -e: list[int] - - -def register(fn: Callable[[], None]) -> None: ... - - -# These should be be fine because they use the "_" name. -@register -def _(): - print("Callback 1 called") - - -@register -def _(): - print("Callback 2 called") diff --git a/packages/vipeye-internal/src/tests/samples/annotations5.py b/packages/vipeye-internal/src/tests/samples/annotations5.py deleted file mode 100644 index 865e3134..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotations5.py +++ /dev/null @@ -1,9 +0,0 @@ -# This sample tests the handling of tuple expressions within a subscript -# when used with type annotations. - -a1: dict[(str, str)] = {"hi": "there"} - -# This should generate an error because there are too many type arguments. -a2: dict[(str, str, str)] = {"hi": "there"} - -b1: list[(int,)] = [3, 4, 5] diff --git a/packages/vipeye-internal/src/tests/samples/annotations6.py b/packages/vipeye-internal/src/tests/samples/annotations6.py deleted file mode 100644 index 77284613..00000000 --- a/packages/vipeye-internal/src/tests/samples/annotations6.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample verifies that the Type[] and type[] annotations work -# as expected when the type argument is Any. - -from typing import Type, Any - - -def is_type1(x: object, y: Type[Any]) -> bool: - return isinstance(x, y) - - -is_type1(1, int) - -# This should generate an error. -is_type1(1, 1) - - -def is_type2(x: object, y: type[Any]) -> bool: - return isinstance(x, y) - - -is_type2(1, int) - -# This should generate an error. -is_type2(1, 1) - - -def func1(v1: Type[Any], v2: type[Any]): - reveal_type(v1, expected_text="Type[Any]") - reveal_type(v2, expected_text="type[Any]") diff --git a/packages/vipeye-internal/src/tests/samples/any1.py b/packages/vipeye-internal/src/tests/samples/any1.py deleted file mode 100644 index 4b0a1f38..00000000 --- a/packages/vipeye-internal/src/tests/samples/any1.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests certain uses of Any that should be flagged as illegal. - -import typing -from typing import Any, cast - -# This should generate an error because Any is not valid for isinstance. -isinstance(0, Any) - -# This should generate an error because Any is not valid for isinstance. -isinstance(0, typing.Any) - -v1 = cast(Any, 0) -v2 = cast(typing.Any, 0) - - -class A(Any): ... - - -class B(typing.Any): ... - - -# This should generate an error because Any is not callable. -Any() - -# This should generate an error because Any is not callable. -typing.Any() - - -def func1() -> int: - # This should generate an error because Any cannot be used as a value. - return Any - - -def func2() -> int: - # This should generate an error because Any cannot be used as a value. - return typing.Any - - -v3: type[Any] = type(Any) - -# This should generate an error. -v4: type[type] = type(Any) - -# This should generate an error. -v5: type = Any diff --git a/packages/vipeye-internal/src/tests/samples/assert1.py b/packages/vipeye-internal/src/tests/samples/assert1.py deleted file mode 100644 index 3c981608..00000000 --- a/packages/vipeye-internal/src/tests/samples/assert1.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the ability to detect errant assert calls -# that are always true - the "reportAssertAlwaysTrue" option. - -from typing import Any, Tuple - - -# This should generate a warning. -assert (1 != 2, "Error message") - - -def foo(a: Tuple[int, ...]): - assert a - - -b = () -assert b - - -c = (2, 3) - -# This should generate a warning. -assert c diff --git a/packages/vipeye-internal/src/tests/samples/assertType1.py b/packages/vipeye-internal/src/tests/samples/assertType1.py deleted file mode 100644 index ebd3d094..00000000 --- a/packages/vipeye-internal/src/tests/samples/assertType1.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests the assert_type call. - -from typing import Any, Literal -from typing_extensions import assert_type # viper: ignore[reportMissingModuleSource] - - -def func1(): - # This should generate an error. - assert_type() - - # This should generate an error. - assert_type(1) - - # This should generate an error. - assert_type(1, 2, 3) - - # This should generate an error. - assert_type(*[]) - - -def func2(x: int, y: int | str, z: list): - assert_type(x, int) - - # This should generate an error. - assert_type(x, str) - - # This should generate an error. - assert_type(x, Any) - - x = 3 - assert_type(x, Literal[3]) - - # This should generate an error. - assert_type(x, int) - - assert_type(y, int | str) - assert_type(y, str | int) - - # This should generate an error. - assert_type(y, str) - - # This should generate an error. - assert_type(y, None) - - # This should generate two errors. - assert_type(y, 3) - - assert_type(z[0], Any) diff --git a/packages/vipeye-internal/src/tests/samples/assignment1.py b/packages/vipeye-internal/src/tests/samples/assignment1.py deleted file mode 100644 index 85375f7c..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment1.py +++ /dev/null @@ -1,72 +0,0 @@ -# This sample tests the type checker's handling of -# member assignments. - -from not_present import NotPresentClass # type: ignore - - -class ClassA: - def __init__(self): - self.string_list: list[str] = [] - - def do_something(self, num: int) -> str: - return "" - - -a = ClassA() - -a.string_list = ["yep"] - -# This should generate an error because of a type mismatch. -a.string_list = "bbb" - -# This should generate an error because of a type mismatch. -a.string_list = {} - -# This should generate an error because of a type mismatch. -a.string_list = [1] - -# This should generate an error because there is no member -# called string_list2 defined. -a.string_list2 = 4 - - -def patch1(num: int) -> str: - return "" - - -def patch2(self, num: int) -> str: - return "" - - -a.do_something = lambda num: "hello" -a.do_something = patch1 - -# This should generate an error because of a param count mismatch -a.do_something = lambda: "hello" - -# This should generate an error because of a return type mismatch -a.do_something = lambda x: 1 - - -ClassA.do_something = patch2 - -# This should generate an error because of a param count mismatch -ClassA.do_something = patch1 - - -class ClassB: - # This should generate an error because assignment expressions - # can't be used within a class. - [(j := i) for i in range(5)] - - -class ClassC: - def __init__(self): - self.x = NotPresentClass # type: int - self.y: int - self.y = NotPresentClass - self.z: int = NotPresentClass - - reveal_type(self.x, expected_text="Unknown | int") - reveal_type(self.y, expected_text="Unknown | int") - reveal_type(self.z, expected_text="Unknown | int") diff --git a/packages/vipeye-internal/src/tests/samples/assignment10.py b/packages/vipeye-internal/src/tests/samples/assignment10.py deleted file mode 100644 index 502b400b..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment10.py +++ /dev/null @@ -1,83 +0,0 @@ -# This sample tests some cases where types are narrowed on assignment, -# including some cases that involve "Any". - -from typing import Any, Generic, Iterable, TypeVar - - -class A: - instance: "A | None" - - def __init__(self) -> None: - self.foo: bool - - @classmethod - def method1(cls) -> bool: - if cls.instance is None: - cls.instance = cls() - return cls.instance.foo - - -T = TypeVar("T") - - -class B(Generic[T]): ... - - -def func1(v1: list[Any | None], v2: list[int | str]): - x1: list[int | None] = v1 - reveal_type(x1, expected_text="list[int | None]") - - x2: list[Any] = v2 - reveal_type(x2, expected_text="list[Any]") - - x3: list[Any | str] = v2 - reveal_type(x3, expected_text="list[Any | str]") - - -def func2(v1: dict[int, Any | None], v2: dict[int, int | str]): - x1: dict[int, int | None] = v1 - reveal_type(x1, expected_text="dict[int, int | None]") - - x2: dict[Any, Any] = v2 - reveal_type(x2, expected_text="dict[Any, Any]") - - x3: dict[Any, Any | str] = v2 - reveal_type(x3, expected_text="dict[Any, Any | str]") - - -def func3(y: list[int]): - x1: Iterable[int | B[Any]] = y - reveal_type(x1, expected_text="list[int]") - - x2: Iterable[Any | B[Any]] = y - reveal_type(x2, expected_text="list[int]") - - x3: Iterable[Any] = y - reveal_type(x3, expected_text="list[int]") - - -def func4(y: list[Any]): - x1: Iterable[int | B[Any]] = y - reveal_type(x1, expected_text="list[Any]") - - x2: Iterable[Any | B[Any]] = y - reveal_type(x2, expected_text="list[Any]") - - x3: Iterable[Any] = y - reveal_type(x3, expected_text="list[Any]") - - -def func5(v1: list[Any | None]): - x1: list[int | None] = v1 - reveal_type(x1, expected_text="list[int | None]") - - -def func6(v1: tuple[Any], v2: tuple[int, Any], v3: tuple[Any, ...]): - x1: tuple[int] = v1 - reveal_type(x1, expected_text="tuple[int]") - - x2: tuple[int, str] = v2 - reveal_type(x2, expected_text="tuple[int, str]") - - x3: tuple[str, ...] = v3 - reveal_type(x3, expected_text="tuple[str, ...]") diff --git a/packages/vipeye-internal/src/tests/samples/assignment11.py b/packages/vipeye-internal/src/tests/samples/assignment11.py deleted file mode 100644 index c9a91859..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment11.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the type checker's handling of chained assignments. - -a1 = b1 = c1 = d1 = 3 - -my_list = [10] -a2 = my_list[a2] = b2 = my_list[b2] = 0 - -# This should generate an error because a3 is read before written. -my_list[a3] = a3 = 0 - - -# This should generate an error because type comments are not -# allowed for chained assignments. -x1 = x2 = x3 = [3] # type: list[float] - - -# Bidirectional type inference should be used in this case. -y2: list[list[float]] -y1 = y2 = [[3]] -reveal_type(y1, expected_text="list[list[float]]") diff --git a/packages/vipeye-internal/src/tests/samples/assignment12.py b/packages/vipeye-internal/src/tests/samples/assignment12.py deleted file mode 100644 index 1034a0e6..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment12.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a variable with a declared type -# is assigned an unknown value or partially-unknown value. - - -def a_test(x1: int, x2: list): - u = x1.upper() # type: ignore - reveal_type(u, expected_text="Unknown") - - # This should generate an error if reportUnknownVariableType is enabled. - y: str = u - reveal_type(y, expected_text="Unknown | str") - - # This should generate an error if reportUnknownVariableType is enabled. - z: list[str] = x2 - reveal_type(z, expected_text="list[str]") - - -def b_test(x: int | str): - u = x.upper() # type: ignore - reveal_type(u, expected_text="str | Unknown") - - # This should generate an error if reportUnknownVariableType is enabled. - y: str = u - reveal_type(y, expected_text="str | Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/assignment2.py b/packages/vipeye-internal/src/tests/samples/assignment2.py deleted file mode 100644 index 89ce2085..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment2.py +++ /dev/null @@ -1,43 +0,0 @@ -# This sample tests assignments to indexed expressions -# where the base is a specialized object. - -# Enable the reportUnknownArgumentType check so we can verify that it -# doesn't generate an error when assigning an empty list to an indexed -# expression. -# viper: reportUnknownArgumentType=true - - -v1: list[int] = [1, 2, 3, 4, 5] -# This should generate an error because the assigned type is wrong. -v1[0] = "a" - -v2: dict[int, str] = {1: "str"} -# This should generate an error because the assigned type is wrong. -v2[1] = 123 - -v3: list[int | str] = ["a"] -v3[0] = 3 -reveal_type(v3[0], expected_text="Literal[3]") - - -v4: dict[str, int | str] = {} -v4["aaa"] = 3 -v4["bbb"] = "bbb" -reveal_type(v4["aaa"], expected_text="Literal[3]") -reveal_type(v4["bbb"], expected_text="Literal['bbb']") -reveal_type(v4["ccc"], expected_text="int | str") - - -class Asymmetric: - def __setitem__(self, i: int, value: object) -> None: ... - - def __getitem__(self, i: int) -> int: ... - - -v5 = Asymmetric() -v5[0] = 3 -reveal_type(v5[0], expected_text="int") - - -v6 = [1, 2, 3] -v6[1:] = [] diff --git a/packages/vipeye-internal/src/tests/samples/assignment3.py b/packages/vipeye-internal/src/tests/samples/assignment3.py deleted file mode 100644 index 076159ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment3.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests various assignment scenarios where -# there is an expected type, so bidirectional type -# inference is used. - -from typing import Callable, Literal, Protocol - -f1: Callable[[int, int], int] = lambda a, b: a + b - -# This should generate an error because x should be -# determined to be an "int", so "len(x)" is invalid. -map(lambda x: len(x), [1, 2, 3]) - - -def must_be_int(val: int): - return val - - -d1: dict[str, tuple[int, Callable[[int], int]]] = { - "hello": (3, lambda x: must_be_int(x)) -} - -d2: dict[str, tuple[int, Callable[[int], int]]] = { - # This should generate an error because the key is not a str. - 3: (3, lambda x: must_be_int(x)) -} - -d3: dict[str, tuple[int, Callable[[int], int]]] = { - # This should generate an error because the first element - # of the tuple is not the correct type. - "3": (3.0, lambda x: must_be_int(x)) -} - -d4: dict[str, tuple[int, Callable[[int], int]]] = { - # This should generate an error because the lambda - # type doesn't match. - "3": (3, lambda _: 3.4) -} - - -class Adder(Protocol): - def __call__(self, x: int, y: dict[str, int]) -> int: ... - - -v1: Adder = lambda x, y: x + y["hi"] -reveal_type(v1, expected_text="(x: int, y: dict[str, int]) -> int") - - -class A: - @classmethod - def method1(cls): - cls.v1: list[Literal[0]] = [] if issubclass(cls, int) else [0] diff --git a/packages/vipeye-internal/src/tests/samples/assignment4.py b/packages/vipeye-internal/src/tests/samples/assignment4.py deleted file mode 100644 index a74a3a10..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment4.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests various assignment scenarios where -# there is an expected type, so bidirectional type -# inference is used. - -# viper: strict - -from typing import Callable, Sequence - -AAA = float -BBB = int -CCC = str -DDD = str -AAATuple = tuple[AAA, BBB, Callable[[Sequence[int], AAA], Sequence[float]]] - - -def foo(): - var1: dict[str, tuple[AAA, BBB, CCC, DDD]] = {} - var2: dict[str, AAATuple] = {} - for k, (var3, var4, _, _) in var1.items(): - var2[k] = (var3, var4, lambda var5, var6: [v * var6 for v in var5]) diff --git a/packages/vipeye-internal/src/tests/samples/assignment5.py b/packages/vipeye-internal/src/tests/samples/assignment5.py deleted file mode 100644 index fdb39aa1..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment5.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the handling of tuple assignments -# where the order of assignment within the tuple is important. - -from typing import Optional - - -class Node: - key: str - next: Optional["Node"] = None - - -node = Node() - -# This should analyze fine because node.next should be assigned -# None before node is assigned None. -node.next, node = None, None diff --git a/packages/vipeye-internal/src/tests/samples/assignment6.py b/packages/vipeye-internal/src/tests/samples/assignment6.py deleted file mode 100644 index 6be62e16..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment6.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests that the type checker handles the case -# where a symbol within a class scope is assigned an expression -# that includes the same symbol, but that same symbol is defined -# in an outer scope. - -a = 0 -b = 1 -c = 4 - - -class MyClass: - # This should not generate an error because - # the RHS of the assignment refers to a different - # "a", declared in an outer scope. - a = a - - # Same with "b" here. - (b, a) = (b, 3) - - # Same with "c" here. - [c] = [c] - - # This should generate an error because "d" is - # not declared in the outer scope. - e = d diff --git a/packages/vipeye-internal/src/tests/samples/assignment7.py b/packages/vipeye-internal/src/tests/samples/assignment7.py deleted file mode 100644 index 9f8f1ece..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment7.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests a particularly difficult set of dependent -# assignments that involve tuple packing and unpacking. - -# viper: strict - -v1 = "" -v3 = "" - -v2, _ = v1, v3 -v4 = v2 -for _ in range(1): - v1 = v4 - v2, v3 = v1, "" diff --git a/packages/vipeye-internal/src/tests/samples/assignment8.py b/packages/vipeye-internal/src/tests/samples/assignment8.py deleted file mode 100644 index 59c5cf4d..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment8.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample ensures that a variable of type "object" can be -# assigned any other type. - -import os -from typing import Any, TypeVar, overload - - -class Foo: - @overload - def bar(self, obj: None) -> object: ... - - @overload - def bar(self, obj: object) -> Any: ... - - def bar(self, obj: object | None) -> Any: - pass - - @staticmethod - def baz(): - return 3 - - -_T = TypeVar("_T") - -my_obj: object - -my_obj = None -my_obj = os -my_obj = Foo -my_obj = Foo() -my_obj = Foo.bar -my_obj = Foo.baz -my_obj = () -my_obj = lambda x: x -my_obj = _T - -# This should generate an error because a is unbound. -my_obj = a diff --git a/packages/vipeye-internal/src/tests/samples/assignment9.py b/packages/vipeye-internal/src/tests/samples/assignment9.py deleted file mode 100644 index e017aa00..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignment9.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests assignment when the types are invariant and the -# source or destination are unions that contains subtypes which are -# subclasses of each other. - -from datetime import datetime - - -class FloatSubclass(float): - pass - - -float_list: list[float] = [1.0, 2.0] - -v1: list[float | FloatSubclass] = float_list - -v2: list[int | float] = float_list - -# This should generate an error. -v3: list[int | float | datetime] = float_list - - -v4: list[FloatSubclass | float] = [] -v5: list[float] = v4 diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr1.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr1.py deleted file mode 100644 index 9531cd54..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr1.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the Python 3.8 assignment expressions. - -# viper: reportUnusedExpression=false - -def func1(): - b = 'a' - d = 'b' - - a = (b := 3) - - # This should generate an error because the - # item to the left of an assignment expression - # must be a name. - a + 3 := 3 - - # This should generate an error because parens - # are required in this case. - c = d := 3 - -# This should generate an error because parens are required in this case. -val if val := 1 + 2 else None - -val2 if (val2 := 1 + 2) else None - -# This should generate an error because parens are not allowed in asserts. -assert e := 1 diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr2.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr2.py deleted file mode 100644 index 555d3e1e..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr2.py +++ /dev/null @@ -1,67 +0,0 @@ -# This sample tests the Python 3.8 assignment expressions. This sample -# is taken from PEP 257. - -# viper: reportUnusedExpression=false - -import re - -def func1(x: float): - ... - -def pep572_examples(): - if (match := re.search('123', '252')) is not None: - print(match) - print(match) - - file = open('hello') - while chunk := file.read(8192): - print(chunk) - print(chunk) - - def f(x: float): - return x - mylist = [y := f(25), y**2, y**3] - - data = [1, 2, 3] - filtered_data = [y for x in data if (y := f(x)) is not None] - print(filtered_data) - - # This should generate an error. - y := f(25) # INVALID - (y := f(25)) # Valid, though not recommended - - y1 = 1 - - # This should generate an error. - y0 = y1 := f(25) # INVALID - y0 = (y1 := f(25)) # Valid, though discouraged - - # This should generate an error. - func1(x = y := f(25)) # INVALID - func1(x=(y := f(25))) # Valid, though probably confusing - - # This should generate an error. - [y for x in [0, 1] if y := x - 1] - - [y for x in [0, 1] if (y := x - 1)] - - -def func2(): - # This should generate an error. - yield y := 1 - -def func3(): - # This should generate an error. - yield from y := [1] - -def func4(): - # This should generate an error. - v1 = {x := 'a': 0} - - v2 = {(x := 'a'): 0} - - # This should generate an error. - v3 = {x := 'a': i for i in range(4)} - - v4 = {(x := 'a'): i for i in range(4)} - diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr3.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr3.py deleted file mode 100644 index fbfcb7ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr3.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the Python 3.8 assignment expressions. - -import re - -def foo1(x: float): - ... - -p = 3 - -# This should generate an error. -def foo2(answer = p := 42): # INVALID - ... - -def foo3(answer=(p := 42)): # Valid, though not great style - ... - -default_value: int = 3 - -# This should generate two errors. -def foo4(answer: p := default_value = 5): # INVALID - ... - -# This should generate an error. -(lambda: x := 1) # INVALID -lambda: (x := 1) # Valid, but unlikely to be useful -(x := lambda: 1) # Valid -lambda line: (m := re.match('pattern', 'line')) and m.group(1) # Valid diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr4.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr4.py deleted file mode 100644 index f11043bb..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr4.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests error detection for certain cases that -# are explicitly disallowed by PEP 572 for assignment expressions -# when used in context of a list comprehension. - -pairs = [] -stuff = [] - -# These should generate an error because assignment -# expressions aren't allowed within an iterator expression -# in a "for" clause of a list comprehension. -[x for x, y in (pairs2 := pairs) if x % 2 == 0] -[x for x, y in ([1, 2, 3, pairs2 := pairs]) if x % 2 == 0] -{x: y for x, y in (pairs2 := pairs) if x % 2 == 0} -{x for x, y in (pairs2 := pairs) if x % 2 == 0} -foo = (x for x, y in ([1, 2, 3, pairs2 := pairs]) if x % 2 == 0) - -# This should generate an error because 'j' is used as a -# "for target" and the target of an assignment expression. -[[(j := j) for i in range(5)] for j in range(5)] -[i := 0 for i, j in stuff] -[i + 1 for i in (i := stuff)] - -[False and (i := 0) for i, j in stuff] -[i for i, j in stuff if True or (j := 1)] - -# These should generate an error because assignment -# expressions aren't allowed within an iterator expression -# in a "for" clause of a list comprehension. -[i + 1 for i in (j := stuff)] -[i + 1 for i in range(2) for j in (k := stuff)] -[i + 1 for i in [j for j in (k := stuff)]] -[i + 1 for i in (lambda: (j := stuff))()] - - -class Example: - # This should generate an error because the containing - # scope for the list comprehension is a class. - [(j := i) for i in range(5)] - - x = ((y := 1), (z := 2)) - - -Example.x -Example.y -Example.z - -# This should generate an error because 'j' is used as a -# "for target" and the target of an assignment expression. -[i for i in [1, 2] if True or (j := 1) for j in range(10)] diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr5.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr5.py deleted file mode 100644 index 435797e4..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr5.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the scoping rules for assignment expressions -# within a list comprehension. - -# viper: strict - -from typing import Tuple - - -def func1() -> Tuple[str, int]: - a = 3 - y = 4 - _ = [(a := x) for x in ["1", "2"] for _ in ["1", "2"]] - - # The type of "y" should be int because the "y" within - # the list comprehension doesn't leak outside. On the - # other hand, "a" does leak outside the list comprehension. - return (a, y) - - -def get_value(x: int) -> int: ... - - -x = sum(max(value for x in range(10) if (value := get_value(x))) for _ in range(10)) diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr6.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr6.py deleted file mode 100644 index 9c7f26a0..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr6.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that type guards work correctly -# with the walrus operator. - -import re - - -def foo(s: str) -> str: - if m := re.fullmatch("(test).+", s): - return m.group(1) - return "oops" diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr7.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr7.py deleted file mode 100644 index 741963a3..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr7.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests assignment expressions used within arguments. - -from dataclasses import dataclass -from typing import Mapping -import collections - - -class NearestKeyDict(collections.UserDict): - def method1(self, key): - a = len(keys := [k for k in sorted(self.data) if k >= key]) - - # This should generate an error because walrus operators - # are not allowed with named arguments. - b = list(iterable = keys := [k for k in sorted(self.data) if k >= key]) - - -@dataclass -class DC1: - x: str - - -def func1(mapping: Mapping[str, dict]): - return [DC1(temp := "x", **mapping[temp])] diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr8.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr8.py deleted file mode 100644 index 1cf63222..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr8.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample checks that parsing for the assignment expression -# operator is using the correct precedence. It should be parsing -# the RHS as a "test expression" which allows for ternary -# expressions. - -result = None - -if items := 3 if result else None: - pass - -print(items) diff --git a/packages/vipeye-internal/src/tests/samples/assignmentExpr9.py b/packages/vipeye-internal/src/tests/samples/assignmentExpr9.py deleted file mode 100644 index 867cbe49..00000000 --- a/packages/vipeye-internal/src/tests/samples/assignmentExpr9.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the case where an assignment expression target -# is found within a function decorator or a function default value expression. - -from typing import Any, Callable, TypeVar, overload - - -_T = TypeVar("_T") - - -def decorator(*args: Any, **kwargs: Any) -> Callable[[_T], _T]: ... - - -@decorator( - [ - walrus_target_1 - for combination in [[1]] - if None not in (walrus_target_1 := set(combination)) - ], -) -def decorated( - x: list[str] = [x for x in ["a", "b"] if x in (walrus_target_2 := ["a", "b"])], -): - pass - - -reveal_type(walrus_target_1, expected_text="set[int]") -reveal_type(walrus_target_2, expected_text="list[str]") - - -@overload -def func1(value: None = None) -> None: ... - - -@overload -def func1(value: str) -> str: ... - - -def func1(value: str | None = None) -> str | None: - return value - - -func1(value=(param_value := "test")) diff --git a/packages/vipeye-internal/src/tests/samples/async1.py b/packages/vipeye-internal/src/tests/samples/async1.py deleted file mode 100644 index 47abf92d..00000000 --- a/packages/vipeye-internal/src/tests/samples/async1.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample validates that "async" is flagged as an error when -# used in inappropriate locations. - -from contextlib import AsyncExitStack - - -async def b(): - for i in range(5): - yield i - - -cm = AsyncExitStack() - - -def func1(): - # This should generate an error because - # "async" cannot be used in a non-async function. - async for x in b(): - print("") - - # This is allowed because it's in a generator. - y = (x async for x in b()) - - # This should generate an error because - # "async" cannot be used in a non-async function. - async with cm: - pass - - # This should generate an error because - # "async" cannot be used in a non-async function. - return [x async for x in b()] - - -# This should generate an error because -# "async" cannot be used in a non-async function. -async for x in b(): - print("") - -# This is allowed because it's in a generator. -y = (x async for x in b()) - -# This should generate an error because -# "async" cannot be used in a non-async function. -async with cm: - pass - -# This should generate an error because -# "async" cannot be used in a non-async function. -[x async for x in b()] diff --git a/packages/vipeye-internal/src/tests/samples/augmentedAssignment1.py b/packages/vipeye-internal/src/tests/samples/augmentedAssignment1.py deleted file mode 100644 index a4f07c5c..00000000 --- a/packages/vipeye-internal/src/tests/samples/augmentedAssignment1.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests the type checker's handling of -# augmented assignments (combining a binary operator -# with an assignment). - - -a = 1 -b = 3.4 - -a += b -reveal_type(a, expected_text="float") - -a -= b -reveal_type(a, expected_text="float") - -a *= b -reveal_type(a, expected_text="float") - -a /= b -reveal_type(a, expected_text="float") - -a //= b -reveal_type(a, expected_text="float") - -a %= b -reveal_type(a, expected_text="float") - -a **= b -reveal_type(a, expected_text="Any") - -a = 1 - -# This should generate an error because -# matrix multiply isn't supported by int. -a @= b - -a |= b -a &= b -a ^= b -a <<= b -a >>= b - - -list1 = [1, 2, 3] -list1 += [4] - -# This should generate an error -list1 += 4 - -# This should generate an error -list2 = [1] -list2 *= 4 - -# This should generate an error -list2 *= [4] - - -# Test __iadd__ override in list class, which accepts -# any iterator as an argument. -bar = ("d",) -foo = ["a", "b"] -foo += ["c"] -foo += bar diff --git a/packages/vipeye-internal/src/tests/samples/augmentedAssignment2.py b/packages/vipeye-internal/src/tests/samples/augmentedAssignment2.py deleted file mode 100644 index 3d170fa0..00000000 --- a/packages/vipeye-internal/src/tests/samples/augmentedAssignment2.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests expected diagnostics for augmented assignment -# expressions. - - -def func1(values1: list[float] = [], values2: list[float] | None = None) -> None: - values3 = None - - # This should generate an error - values1 += values2 - - if values2 is not None: - values1 += values2 - - # This should generate an error - values1 -= values2 - - # This should generate an error - values1 += values3 diff --git a/packages/vipeye-internal/src/tests/samples/augmentedAssignment3.py b/packages/vipeye-internal/src/tests/samples/augmentedAssignment3.py deleted file mode 100644 index eb257871..00000000 --- a/packages/vipeye-internal/src/tests/samples/augmentedAssignment3.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a class-scoped variable -# type needs to be inferred from an augmented assignment. - - -class ClassA: - y = 0 - z = 0 - z += 0.5 - - def __init__(self): - self.x = 0 - self.x += 0.5 - - @classmethod - def method1(cls): - cls.y += 0.5 - - -reveal_type(ClassA().x, expected_text="int | float") -reveal_type(ClassA.y, expected_text="int | float") -reveal_type(ClassA.z, expected_text="int | float") diff --git a/packages/vipeye-internal/src/tests/samples/autoVariance1.py b/packages/vipeye-internal/src/tests/samples/autoVariance1.py deleted file mode 100644 index 7e5af1cd..00000000 --- a/packages/vipeye-internal/src/tests/samples/autoVariance1.py +++ /dev/null @@ -1,164 +0,0 @@ -# This sample tests variance inference for type variables that use -# autovariance. - -from dataclasses import dataclass -from typing import Final, Iterator, Sequence, overload - - -class ShouldBeCovariant1[T]: - def __getitem__(self, index: int) -> T: ... - - def __iter__(self) -> Iterator[T]: ... - - -vco1_1: ShouldBeCovariant1[float] = ShouldBeCovariant1[int]() - -# This should generate an error based on variance. -vco1_2: ShouldBeCovariant1[int] = ShouldBeCovariant1[float]() - - -class ShouldBeCovariant2[T](Sequence[T]): - def __len__(self) -> int: ... - @overload - def __getitem__(self, index: int) -> T: ... - @overload - def __getitem__(self, index: slice) -> Sequence[T]: ... - def __getitem__(self, index: int | slice) -> T | Sequence[T]: ... - - -vco2_1: ShouldBeCovariant2[float] = ShouldBeCovariant2[int]() -# This should generate an error based on variance. -vco2_2: ShouldBeCovariant2[int] = ShouldBeCovariant2[float]() - - -class ShouldBeCovariant3[T]: - def method1(self) -> "ShouldBeCovariant2[T]": ... - - -vco3_1: ShouldBeCovariant3[float] = ShouldBeCovariant3[int]() -# This should generate an error based on variance. -vco3_2: ShouldBeCovariant3[int] = ShouldBeCovariant3[float]() - - -@dataclass(frozen=True) -class ShouldBeCovariant4[T]: - x: T - - -vo4_1: ShouldBeCovariant4[float] = ShouldBeCovariant4[int](1) -# This should generate an error based on variance. -vo4_2: ShouldBeCovariant4[int] = ShouldBeCovariant4[float](1) - - -class ShouldBeCovariant5[T]: - def __init__(self, x: T) -> None: - self._x = x - - @property - def x(self) -> T: - return self._x - - -vo5_1: ShouldBeCovariant5[float] = ShouldBeCovariant5[int](1) -# This should generate an error based on variance. -vo5_2: ShouldBeCovariant5[int] = ShouldBeCovariant5[float](1) - - -class ShouldBeCovariant6[T]: - def f1[T2: int](self: "ShouldBeCovariant6[T2]") -> T2: ... - - @property - def f2[T2: int](self: "ShouldBeCovariant6[T2]") -> T2: ... - - -# This should generate an error based on variance. -vo6_1: ShouldBeCovariant6[int] = ShouldBeCovariant6[float]() - -vo6_2: ShouldBeCovariant6[float] = ShouldBeCovariant6[int]() - - -class ShouldBeInvariant1[T]: - def __init__(self, value: T) -> None: - self._value = value - - @property - def value(self): - return self._value - - @value.setter - def value(self, value: T): - self._value = value - - -# This should generate an error based on variance. -vinv1_1: ShouldBeInvariant1[float] = ShouldBeInvariant1[int](1) - -# This should generate an error based on variance. -vinv1_2: ShouldBeInvariant1[int] = ShouldBeInvariant1[float](1.1) - - -class ShouldBeInvariant2[T]: - def __init__(self, value: T) -> None: - self._value = value - - def get_value(self) -> T: - return self._value - - def set_value(self, value: T): - self._value = value - - -# This should generate an error based on variance. -vinv2_1: ShouldBeInvariant2[float] = ShouldBeInvariant2[int](1) - -# This should generate an error based on variance -vinv2_2: ShouldBeInvariant2[int] = ShouldBeInvariant2[float](1.1) - - -class ShouldBeInvariant3[K, V](dict[K, V]): - pass - - -# This should generate an error based on variance. -vinv3_1: ShouldBeInvariant3[float, str] = ShouldBeInvariant3[int, str]() - -# This should generate an error based on variance. -vinv3_2: ShouldBeInvariant3[int, str] = ShouldBeInvariant3[float, str]() - -# This should generate an error based on variance. -vinv3_3: ShouldBeInvariant3[str, float] = ShouldBeInvariant3[str, int]() - -# This should generate an error based on variance. -vinv3_4: ShouldBeInvariant3[str, int] = ShouldBeInvariant3[str, float]() - - -@dataclass -class ShouldBeInvariant4[T]: - x: T - - -# This should generate an error based on variance -vinv4_1: ShouldBeInvariant4[float] = ShouldBeInvariant4[int](1) - - -class ShouldBeInvariant5[T]: - def __init__(self, x: T) -> None: - self.x = x - - -# This should generate an error based on variance. -vinv5_1: ShouldBeInvariant5[float] = ShouldBeInvariant5[int](1) - - -class ShouldBeContravariant1[T]: - def __init__(self, value: T) -> None: - pass - - def set_value(self, value: T) -> None: - pass - - -# This should generate an error based on variance. -vcontra1_1: ShouldBeContravariant1[float] = ShouldBeContravariant1[int](1) - -vcontra1_2: ShouldBeContravariant1[int] = ShouldBeContravariant1[float](1.2) diff --git a/packages/vipeye-internal/src/tests/samples/autoVariance2.py b/packages/vipeye-internal/src/tests/samples/autoVariance2.py deleted file mode 100644 index de200cf0..00000000 --- a/packages/vipeye-internal/src/tests/samples/autoVariance2.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests an auto-invariance case that involves recursive types. - -from __future__ import annotations - -from collections.abc import Callable -from dataclasses import dataclass -from typing import Concatenate, Protocol - - -@dataclass -class Node[T]: - left: Node[T] - right: Node[T] - value: T - - -class MyPartial[**P, R]: - def __init__(self, first: int, func: Callable[Concatenate[int, P], R]) -> None: - self.first = first - self.func = func - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -class CallbackKeyed[*Ts](Protocol): - def __call__(self, *args: *Ts, keyed: bool) -> tuple[*Ts]: ... - - -def invoke_keyed[*Ts](fn: CallbackKeyed[*Ts], *args: *Ts) -> tuple[*Ts]: - return fn(*args, keyed=True) diff --git a/packages/vipeye-internal/src/tests/samples/autoVariance3.py b/packages/vipeye-internal/src/tests/samples/autoVariance3.py deleted file mode 100644 index 25227a9f..00000000 --- a/packages/vipeye-internal/src/tests/samples/autoVariance3.py +++ /dev/null @@ -1,163 +0,0 @@ -# This sample tests variance inference for traditional type variables. - -from typing import Generic, Iterator, Sequence, overload -from typing_extensions import TypeVar # viper: ignore[reportMissingModuleSource] -from dataclasses import dataclass - -T = TypeVar("T", infer_variance=True) -K = TypeVar("K", infer_variance=True) -V = TypeVar("V", infer_variance=True) - -# This should generate an error because covariant cannot be used -# with infer_variance. -S1 = TypeVar("S1", covariant=True, infer_variance=True) - -# This should generate an error because contravariant cannot be used -# with infer_variance. -S2 = TypeVar("S2", contravariant=True, infer_variance=True) - - -class ShouldBeCovariant1(Generic[T]): - def __getitem__(self, index: int) -> T: ... - - def __iter__(self) -> Iterator[T]: ... - - -vco1_1: ShouldBeCovariant1[float] = ShouldBeCovariant1[int]() - -# This should generate an error based on variance. -vco1_2: ShouldBeCovariant1[int] = ShouldBeCovariant1[float]() - - -class ShouldBeCovariant2(Sequence[T]): - def __len__(self) -> int: ... - @overload - def __getitem__(self, index: int) -> T: ... - @overload - def __getitem__(self, index: slice) -> Sequence[T]: ... - def __getitem__(self, index: int | slice) -> T | Sequence[T]: ... - - -vco2_1: ShouldBeCovariant2[float] = ShouldBeCovariant2[int]() -# This should generate an error based on variance. -vco2_2: ShouldBeCovariant2[int] = ShouldBeCovariant2[float]() - - -class ShouldBeCovariant3(Generic[T]): - def method1(self) -> "ShouldBeCovariant2[T]": ... - - -vco3_1: ShouldBeCovariant3[float] = ShouldBeCovariant3[int]() -# This should generate an error based on variance. -vco3_2: ShouldBeCovariant3[int] = ShouldBeCovariant3[float]() - - -@dataclass(frozen=True) -class ShouldBeCovariant4(Generic[T]): - x: T - - -vo4_1: ShouldBeCovariant4[float] = ShouldBeCovariant4[int](1) -# This should generate an error based on variance. -vo4_4: ShouldBeCovariant4[int] = ShouldBeCovariant4[float](1.0) - - -class ShouldBeCovariant5(Generic[T]): - def __init__(self, x: T) -> None: - self._x = x - - @property - def x(self) -> T: - return self._x - - -vo5_1: ShouldBeCovariant5[float] = ShouldBeCovariant5[int](1) -# This should generate an error based on variance. -vo5_2: ShouldBeCovariant5[int] = ShouldBeCovariant5[float](1.0) - - -class ShouldBeInvariant1(Generic[T]): - def __init__(self, value: T) -> None: - self._value = value - - @property - def value(self): - return self._value - - @value.setter - def value(self, value: T): - self._value = value - - -# This should generate an error based on variance. -vinv1_1: ShouldBeInvariant1[float] = ShouldBeInvariant1[int](1) - -# This should generate an error based on variance. -vinv1_2: ShouldBeInvariant1[int] = ShouldBeInvariant1[float](1.1) - - -class ShouldBeInvariant2(Generic[T]): - def __init__(self, value: T) -> None: - self._value = value - - def get_value(self) -> T: - return self._value - - def set_value(self, value: T): - self._value = value - - -# This should generate an error based on variance. -vinv2_1: ShouldBeInvariant2[float] = ShouldBeInvariant2[int](1) - -# This should generate an error based on variance. -vinv2_2: ShouldBeInvariant2[int] = ShouldBeInvariant2[float](1.1) - - -class ShouldBeInvariant3(dict[K, V]): - pass - - -# This should generate an error based on variance. -vinv3_1: ShouldBeInvariant3[float, str] = ShouldBeInvariant3[int, str]() - -# This should generate an error based on variance. -vinv3_2: ShouldBeInvariant3[int, str] = ShouldBeInvariant3[float, str]() - -# This should generate an error based on variance. -vinv3_3: ShouldBeInvariant3[str, float] = ShouldBeInvariant3[str, int]() - -# This should generate an error based on variance. -vinv3_4: ShouldBeInvariant3[str, int] = ShouldBeInvariant3[str, float]() - - -@dataclass -class ShouldBeInvariant4[T]: - x: T - - -# This should generate an error based on variance. -vinv4_1: ShouldBeInvariant4[float] = ShouldBeInvariant4[int](1) - - -class ShouldBeInvariant5[T]: - def __init__(self, x: T) -> None: - self.x = x - - -# This should generate an error based on variance. -vinv5_1: ShouldBeInvariant5[float] = ShouldBeInvariant5[int](1) - - -class ShouldBeContravariant1(Generic[T]): - def __init__(self, value: T) -> None: - pass - - def set_value(self, value: T): - pass - - -# This should generate an error based on variance. -vcontra1_1: ShouldBeContravariant1[float] = ShouldBeContravariant1[int](1) - -vcontra1_2: ShouldBeContravariant1[int] = ShouldBeContravariant1[float](1.2) diff --git a/packages/vipeye-internal/src/tests/samples/autoVariance4.py b/packages/vipeye-internal/src/tests/samples/autoVariance4.py deleted file mode 100644 index 795d6d5c..00000000 --- a/packages/vipeye-internal/src/tests/samples/autoVariance4.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the case where a class uses auto-variance but derives -# from a class that does not. - -from typing import Generic, TypeVar - -T = TypeVar("T") -T_co = TypeVar("T_co", covariant=True) -T_contra = TypeVar("T_contra", contravariant=True) - - -class Parent_Invariant(Generic[T]): - pass - - -class ShouldBeInvariant[T](Parent_Invariant[T]): - pass - - -# This should generate an error. -a1: ShouldBeInvariant[int] = ShouldBeInvariant[float]() - -# This should generate an error. -a2: ShouldBeInvariant[float] = ShouldBeInvariant[int]() - - -class Parent_Covariant(Generic[T_co]): - pass - - -class ShouldBeCovariant[T](Parent_Covariant[T]): - pass - - -# This should generate an error. -b1: ShouldBeCovariant[int] = ShouldBeCovariant[float]() - -b2: ShouldBeCovariant[float] = ShouldBeCovariant[int]() - - -class Parent_Contravariant(Generic[T_contra]): - pass - - -class ShouldBeContravariant[T](Parent_Contravariant[T]): - pass - - -c1: ShouldBeContravariant[int] = ShouldBeContravariant[float]() - -# This should generate an error. -c2: ShouldBeContravariant[float] = ShouldBeContravariant[int]() diff --git a/packages/vipeye-internal/src/tests/samples/autoVariance5.py b/packages/vipeye-internal/src/tests/samples/autoVariance5.py deleted file mode 100644 index 9d6b4157..00000000 --- a/packages/vipeye-internal/src/tests/samples/autoVariance5.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests a case that involves an interaction between a class -# that uses auto-variance and a decorator that uses a generic type alias. - -from typing import Any, Concatenate, Generic, ParamSpec, TypeAlias, Callable -from typing_extensions import TypeVar # viper: ignore[reportMissingModuleSource] - -T = TypeVar("T", infer_variance=True) -P = ParamSpec("P") -R = TypeVar("R") -S = TypeVar("S", bound="A[Any]") - -TA1: TypeAlias = Callable[Concatenate[S, P], R] - - -def deco(func: TA1[S, P, R], /) -> TA1[S, P, R]: ... - - -class A(Generic[T]): - @deco - def select_all(self, *args: object) -> list[Any]: ... diff --git a/packages/vipeye-internal/src/tests/samples/await1.py b/packages/vipeye-internal/src/tests/samples/await1.py deleted file mode 100644 index 86ed3d5c..00000000 --- a/packages/vipeye-internal/src/tests/samples/await1.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample validates that the await keyword participates in -# bidirectional type inference. - -from typing import ( - Any, - AsyncIterator, - Callable, - Iterable, - Literal, - TypeVar, - Generic, - overload, -) - -T = TypeVar("T") -AnyMsg = TypeVar("AnyMsg", bound="Msg") - - -class Msg(Generic[T]): - body: T - - -class Request: - id: int - - -async def func1(check: "Callable[[AnyMsg], bool]") -> AnyMsg: ... - - -async def func2(): - _: Msg[Request] = await func1(check=lambda msg: (msg.body.id == 12345)) - - -async def func3() -> AsyncIterator[int]: - yield 1 - - -async def func4() -> int: - return await anext(func3()) - - -async def func5(__fn: Callable[..., T]) -> T: ... - - -@overload -def sum(__iterable: Iterable[Literal[0]]) -> int: ... - - -@overload -def sum(__iterable: Iterable[T]) -> T: ... - - -def sum(__iterable: Iterable[Any]) -> Any: ... - - -async def func6(f: Callable[[], list[int]]): - sum(await func5(f)) diff --git a/packages/vipeye-internal/src/tests/samples/await2.py b/packages/vipeye-internal/src/tests/samples/await2.py deleted file mode 100644 index 1c08d3d0..00000000 --- a/packages/vipeye-internal/src/tests/samples/await2.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests that types defined by type variables can be -# awaited. - -from typing import Generator, Any, NoReturn - - -class MyAwaitable: - def __await__(self) -> Generator[Any, None, int]: - async def foo() -> int: - return 1 - - return foo().__await__() - - async def foo(self) -> int: - return await self - - -async def func1() -> None: - p = MyAwaitable() - print(await p.foo()) - print(await p) - - -async def func2() -> NoReturn: - raise Exception() - - -async def func3(x: int | None): - if x is None: - await func2() - print(x.bit_count()) diff --git a/packages/vipeye-internal/src/tests/samples/await3.py b/packages/vipeye-internal/src/tests/samples/await3.py deleted file mode 100644 index 1caee13d..00000000 --- a/packages/vipeye-internal/src/tests/samples/await3.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests various places where await is invalid. - -from typing import Any - - -def func1() -> Any: ... - - -def func2(): - # These are OK because generators can be called - # outside of the context of the current function. - (v async for v in func1()) - (await v for v in func1()) - - # This should generate an error because async - # cannot be used outside of an async function. - [x async for x in func1()] - - # This should generate an error because async - # cannot be used outside of an async function. - {x async for x in func1()} - - # This should generate an error because async - # cannot be used outside of an async function. - {k: v async for k, v in func1()} - - # This should generate an error because await - # cannot be used outside of an async function. - (x for x in await func1()) - - # This should generate an error because await - # cannot be used outside of an async function. - [await x for x in func1()] - - # This should generate an error because await - # cannot be used outside of an async function. - {await k: v for k, v in func1()} diff --git a/packages/vipeye-internal/src/tests/samples/builtins1.py b/packages/vipeye-internal/src/tests/samples/builtins1.py deleted file mode 100644 index 5c8be3fa..00000000 --- a/packages/vipeye-internal/src/tests/samples/builtins1.py +++ /dev/null @@ -1,2 +0,0 @@ -# This file is intentionally blank. It's used to test -# the implicitly-imported builtins module and its symbols. diff --git a/packages/vipeye-internal/src/tests/samples/builtins2.py b/packages/vipeye-internal/src/tests/samples/builtins2.py deleted file mode 100644 index b1d5d71d..00000000 --- a/packages/vipeye-internal/src/tests/samples/builtins2.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests that builtins can be overridden at the module level -# without generating a "possibly unbound" error. - -if input(): - print = lambda *x: None - -print("") diff --git a/packages/vipeye-internal/src/tests/samples/call1.py b/packages/vipeye-internal/src/tests/samples/call1.py deleted file mode 100644 index b5b6ff5a..00000000 --- a/packages/vipeye-internal/src/tests/samples/call1.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests various function type checking -# behavior including arg/param matching. - -from typing import Callable - -# ------------------------------------------------------ -# Test function type matching - - -class FooBase: - pass - - -class Foo(FooBase): - pass - - -class Bar(Foo): - pass - - -def needs_function1(callback: Callable[[Foo], Foo]): - pass - - -def callback1(): - pass - - -def callback2(a: Foo) -> Foo: - return Foo() - - -def callback3(a: Foo) -> str: - return "1" - - -def callback4(a: Foo, b: Foo) -> Foo: - return Foo() - - -def callback5(a: Foo, b: int = 3) -> Foo: - return Foo() - - -def callback6(*a) -> Foo: - return Foo() - - -def callback7(a: str) -> Foo: - return Foo() - - -def callback8(a: Bar) -> Foo: - return Foo() - - -def callback9(a: FooBase) -> Foo: - return Foo() - - -# This should generate an error because callback1 -# takes no parameters. -needs_function1(callback1) - -needs_function1(callback2) - -# This should generate an error because the return -# type of callback3 doesn't match. -needs_function1(callback3) - -# This should generate an error because callback4 -# takes too many parameters. -needs_function1(callback4) - -needs_function1(callback5) -needs_function1(callback6) - -# This should fail because the parameter is the -# wrong type. -needs_function1(callback7) - -# This should fail because the parameter is the -# wrong type. -needs_function1(callback8) - -needs_function1(callback9) - - -import typing - -# This should generate an error because modules are not callable. -typing() diff --git a/packages/vipeye-internal/src/tests/samples/call10.py b/packages/vipeye-internal/src/tests/samples/call10.py deleted file mode 100644 index 41605545..00000000 --- a/packages/vipeye-internal/src/tests/samples/call10.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests that the type checker properly handles -# types of args and kwargs correctly. - -from typing import Any, Hashable, Mapping, Protocol - - -def requires_hashable_tuple(p1: tuple[Hashable, ...]): ... - - -def requires_hashable_dict(p1: dict[str, Hashable]): ... - - -def test_args(*args: Hashable): - if args: - aaa = list(args) - bbb = tuple(aaa) - args = bbb - requires_hashable_tuple(args) - - -def test_kwargs(**kwargs: Hashable): - requires_hashable_dict(kwargs) - - -class StrSubclass(str): ... - - -def test_kwargs2( - a: Mapping[str, Any], - b: Mapping[Any, Hashable], - c: dict[StrSubclass, Hashable], - d: int, - e: Mapping[int, Hashable], - f: tuple[str, ...], -): - test_kwargs(**a) - test_kwargs(**b) - test_kwargs(**c) - - # This should generate an error - test_kwargs(**d) - - # This should generate an error - test_kwargs(**e) - - # This should generate an error - test_kwargs(**f) - - -class Callback1(Protocol): - def __call__(self) -> None: ... - - -def func1( - value: str = ..., - *args: object, -) -> None: ... - - -def func2( - value: str = ..., - **kwargs: object, -) -> None: ... - - -def func3( - value: str = ..., - *args: object, - **kwargs: object, -) -> None: ... - - -v1: Callback1 = func1 -v2: Callback1 = func2 -v3: Callback1 = func3 diff --git a/packages/vipeye-internal/src/tests/samples/call11.py b/packages/vipeye-internal/src/tests/samples/call11.py deleted file mode 100644 index 9c700ba3..00000000 --- a/packages/vipeye-internal/src/tests/samples/call11.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests the case where a call expression involves a union -# on the LHS where the subtypes of the union have different signatures. - -# viper: strict - -from __future__ import annotations -from typing import Any, Callable, Generic, Self, TypeAlias, TypeVar - -T = TypeVar("T") -E = TypeVar("E") -U = TypeVar("U") -F = TypeVar("F") - -Either: TypeAlias = "Left[T]" | "Right[E]" - - -class Left(Generic[T]): - def __init__(self, value: T) -> None: - self.value = value - - def map_left(self, fn: Callable[[T], U]) -> Left[U]: - return Left(fn(self.value)) - - def map_right(self, fn: Callable[[Any], Any]) -> Self: - return self - - -class Right(Generic[E]): - def __init__(self, value: E) -> None: - self.value = value - - def map_left(self, fn: Callable[[Any], Any]) -> Self: - return self - - def map_right(self, fn: Callable[[E], F]) -> Right[F]: - return Right(fn(self.value)) - - -def func() -> Either[int, str]: - raise NotImplementedError - - -result = func().map_left(lambda lv: lv + 1).map_right(lambda rv: rv + "a") -reveal_type(result, expected_text="Right[str] | Left[int]") diff --git a/packages/vipeye-internal/src/tests/samples/call12.py b/packages/vipeye-internal/src/tests/samples/call12.py deleted file mode 100644 index b499fef8..00000000 --- a/packages/vipeye-internal/src/tests/samples/call12.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests that positional arg expressions are evaluated prior -# to keyword arg expressions even if they don't appear in that order -# within the arg list. - - -from typing import TypedDict - - -def func1(a: int | None = None, b: int | None = None, c: int | None = None) -> None: - pass - - -func1((v1 := 1), b=v1 + 1) - -# This should generate an error. -func1(b=(v2 := 1), *[v2 + 1]) - -func1(b=v3 + 1, *[(v3 := 1)]) - - -class A(TypedDict): - a: int - - -class B(TypedDict): - b: int - - -class C(TypedDict): - c: int - - -func1(a=(v4 := 1), **B(b=(v4 + 1))) - -# This should generate an error. -func1(**A(a=(v5 + 1)), b=(v5 := 1)) - -func1(**A(a=(v5 := 1)), b=(v5 + 1)) - -func1(b=(v6 + 1), *[(v6 := 1)], **C(c=(v6 + 2))) - - -def func2(a: int, b: int): - pass - - -func2(b=1, *(2,)) diff --git a/packages/vipeye-internal/src/tests/samples/call13.py b/packages/vipeye-internal/src/tests/samples/call13.py deleted file mode 100644 index 9f75878e..00000000 --- a/packages/vipeye-internal/src/tests/samples/call13.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a call invokes a generic function that -# uses a default argument assigned to a parameter whose type is generic. - -from typing import TypeVar, Iterable, Callable - -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -def func1(values: Iterable[T1], func: Callable[[T1], T2] = lambda x: x) -> list[T2]: - return [func(value) for value in values] - - -v1 = func1([1, 2, 3]) -reveal_type(v1, expected_text="list[int]") diff --git a/packages/vipeye-internal/src/tests/samples/call14.py b/packages/vipeye-internal/src/tests/samples/call14.py deleted file mode 100644 index 34443a7e..00000000 --- a/packages/vipeye-internal/src/tests/samples/call14.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the pre-3.8 position-only parameter convention. - - -from typing import Any - - -def func1(__a: int, __b: int, c: int) -> None: ... - - -func1(1, 2, c=3) - -# This should generate an error because __b is position-only. -func1(1, __b=2, c=3) - - -# This should generate an error because a position-only parameter cannot -# follow a non-position-only parameter. -def func2(a: int, __b: int) -> None: ... - - -def func3(a: int, *args: Any, __b: int) -> None: ... - - -func3(a=1, __b=2) - - -def func4(a: int, /, __b: int) -> None: ... - - -func4(1, __b=2) - - -class A: - def m1(self, __a: int, b: int) -> None: - pass - - # This should generate an error. - def m2(self, a: int, __b: int) -> None: - pass - - @classmethod - def c1(cls, __a, int, b: int) -> None: - pass - - @classmethod - # This should generate an error. - def c2(cls, a, int, __b: int) -> None: - pass - - @staticmethod - def s1(__a: int, b: int) -> None: - pass - - @staticmethod - # This should generate an error. - def s2(a: int, __b: int) -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/call15.py b/packages/vipeye-internal/src/tests/samples/call15.py deleted file mode 100644 index 150bd40d..00000000 --- a/packages/vipeye-internal/src/tests/samples/call15.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample tests the case where a generic function has a default argument -# value for a parameter with a generic type. - -from collections.abc import Callable -from typing import Iterable, TypeVar - -T = TypeVar("T") - -default_value: dict[str, int] = {} - - -def func1(x: T, y: dict[str, T] = default_value, /) -> T: ... - - -def func2(x: T, y: dict[str, T] = default_value) -> T: ... - - -def func3(x: T, *, y: dict[str, T] = default_value) -> T: ... - - -def test1(func: Callable[[T], T], value: T) -> T: - return func(value) - - -# This should generate an error. -test1(func1, "") - -# This should generate an error. -test1(func2, "") - -# This should generate an error. -test1(func3, "") - -reveal_type(test1(func1, 1), expected_text="int") -reveal_type(test1(func2, 1), expected_text="int") -reveal_type(test1(func3, 1), expected_text="int") - - -def func4(x: T, y: Iterable[T] = default_value, z: T = "", /) -> T: ... - - -def func5(x: T, y: Iterable[T] = default_value, z: T = "") -> T: ... - - -def func6(x: T, *, y: Iterable[T] = default_value, z: T = "") -> T: ... - - -reveal_type(test1(func4, 1), expected_text="str | int") -reveal_type(test1(func5, 1), expected_text="str | int") -reveal_type(test1(func6, 1), expected_text="str | int") - - -class A[T]: - def __init__(self, value: T) -> None: - self._value: T = value - - def update(self, value: T = 0, /) -> "A[T]": - return A(value) - - -a = A("") - -a.update("") - -# This should generate an error. -a.update() diff --git a/packages/vipeye-internal/src/tests/samples/call16.py b/packages/vipeye-internal/src/tests/samples/call16.py deleted file mode 100644 index c937e7f0..00000000 --- a/packages/vipeye-internal/src/tests/samples/call16.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests bidirectional type inference for calls where the expected -# type is a union. - -from typing import Any, AnyStr, Iterable, Literal, TypeVar, overload - -T = TypeVar("T") - - -class ItemBase: ... - - -class Item(ItemBase): ... - - -def gen_items() -> Iterable[Item]: - return [] - - -def make_list(val: Iterable[T]) -> list[T]: - return list(val) - - -x: ItemBase | list[ItemBase | None] = make_list(gen_items()) - - -@overload -def urlunsplit(components: Iterable[None]) -> Literal[b""]: ... - - -@overload -def urlunsplit(components: Iterable[AnyStr | None]) -> AnyStr: ... - - -def urlunsplit(components: Iterable[Any]) -> Any: ... - - -def func(url: str, candidates: list[Any]) -> str | None: - return urlunsplit(candidates[0]) diff --git a/packages/vipeye-internal/src/tests/samples/call17.py b/packages/vipeye-internal/src/tests/samples/call17.py deleted file mode 100644 index 36a35742..00000000 --- a/packages/vipeye-internal/src/tests/samples/call17.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests a case of bidirectional type inference for calls -# that involves a union in the expected type. - -# viper: strict - -from __future__ import annotations - -from collections.abc import Callable -from typing import Generic, TypeVar - -T_co = TypeVar("T_co", covariant=True) -E_co = TypeVar("E_co", covariant=True) -F = TypeVar("F") - - -class Ok(Generic[T_co]): - def or_else(self, op: object) -> Ok[T_co]: ... - - -class Err(Generic[E_co]): - def or_else(self, op: Callable[[E_co], Result[T_co, F]]) -> Result[T_co, F]: ... - - -Result = Ok[T_co] | Err[E_co] - - -def inner(func: Callable[[E_co], Err[F]], r: Result[T_co, E_co]) -> Result[T_co, F]: - match r: - case Ok(): - return r.or_else(func) - case Err(): - return r.or_else(func) diff --git a/packages/vipeye-internal/src/tests/samples/call2.py b/packages/vipeye-internal/src/tests/samples/call2.py deleted file mode 100644 index c90d70ab..00000000 --- a/packages/vipeye-internal/src/tests/samples/call2.py +++ /dev/null @@ -1,183 +0,0 @@ -# This sample tests function parameter matching logic. - - -from typing import Any, Callable, Literal - - -def func1(a: int, *b: int): - pass - - -func1(3) -func1(3, 4) -func1(3, *[1, 2, 3]) - -# This should generate an error -func1(3, "hello") - -# This should generate an error -func1(3, 5, 2, "str") - -# This should generate an error -func1("hello", 3) - -str_list = ["he", "2", "3"] - -# This should generate an error -func1(3, *str_list) - - -def func2(a: str, **b: int): - pass - - -func2("hi") -func2("hi", b=3, c=4, d=5) - -str_dict = {"a": "3", "b": "2"} - -# This should generate a type error -func2("hi", **str_dict) - - -# This should generate a type error -func2("hi", 3) - -# This should generate a type error -func2("hi", b="hi") - - -def func4(*args: int): - pass - - -def func5(a: int, *args): - pass - - -tuple1 = (2, 3) -func4(*tuple1) -func5(*tuple1) - -# This should generate an error because a is assigned twice. -func2(a="", a="") - -# This should generate an error because c is assigned twice. -func2("", c=4, d=5, c=5) - - -def func6(param1: int, param2: str): - pass - - -def func7(*args: Any, param0: int, param1: int, param2: str): - func6(*args, param1=param1, param2=param2) - - func6(param0, param2=param2) - - # This should generate two errors because param0 has no match - # and param2 is missing. - func6(param0, param1=param1) - - -def func8( - y: str, - z: bool = ..., -) -> None: ... - - -kwargs1: dict[str, int] = {} -# This should generate an error because int is not compatible with str. -func8(z=False, **kwargs1) - - -class MyStr(str): ... - - -kwargs2: dict[MyStr, MyStr] = {} -func8(z=False, **kwargs2) - - -def func9( - x: int, - y: str, - *, - a: str = ..., - b: str, - c: str, -) -> None: ... - - -kwargs3: dict[str, str] = {} -func9(0, "", **kwargs3) - -args4: list[str] = ["hi"] -func9(0, *args4, **kwargs3) - -# This should generate an error. -func9(*args4, **kwargs3) - - -def func10(x: int): ... - - -func10(1, *()) - -# This should generate an error. -func10(1, *(1,)) - -func10(*(1,)) - -# This should generate an error. -func10(*(1, 1)) - -# This should generate an error. -func10(*("",)) - - -def func11(y: tuple[int, ...]): - func10(1, *y) - - -def func12(x: int, /, y: str): - pass - - -# This should generate an error. -func12(1, **{"z": None}) - - -def func13(*, a: str, b: str, c: int | None = None): - ... - - -func_args1: dict[Literal["a", "b", "d"], str] = { - "a": "a", - "b": "b", - "d": "d", -} - -func13(**func_args1) - -func_args2: dict[Literal["a", "b", "c"], str] = { - "a": "a", - "b": "b", - "c": "c", -} - - -# This should generate an error. -func13(**func_args2) - - -def func14(cb1: Callable[..., Any], cb2: Any, x: None): - cb1(**x) # This should generate an error - cb2(**x) # This should generate an error - - -def func15(cb1: Callable[..., Any], cb2: Any, a: int, b: None | str): - print(*a) # This should generate an error - print(*b) # This should generate an error - cb1(*a) # This should generate an error - cb2(*b) # This should generate an error - diff --git a/packages/vipeye-internal/src/tests/samples/call3.py b/packages/vipeye-internal/src/tests/samples/call3.py deleted file mode 100644 index 8616aa28..00000000 --- a/packages/vipeye-internal/src/tests/samples/call3.py +++ /dev/null @@ -1,180 +0,0 @@ -# This sample tests the Python 3.8 "positional-only parameter" feature. - -from typing import Any, Dict, Protocol, Tuple - - -def f0(a: int, b: int): - return 3 - - -def f1(a: int, b: int, /): - return 3 - -# This should generate an error because only one -# '/' parameter is allowed. -def f2(a: int, /, b: int, /): - return 3 - -def f3(a: int, /, b: int): - return 3 - -def f4(a: int, /, b: int, *, c: int): - return 3 - -# This should generate an error because a '/' -# parameter shouldn't appear after '*'. -def f5(a: int, *, b: int, /, c: int): - return 3 - -# This should generate an error because a '/' -# parameter cannot be the first in a param list. -def f6(/, a: int, *, b: int): - return 3 - - -f0(2, 3) - -f1(2, 3) - -# This should generate an error because b -# is a position-only parameter. -f1(2, b=3) - -# This should generate an error because a and b -# are position-only parameters. -f1(a=2, b=3) - -f2(2, 3) - -# This should generate an error. -f2(a=2, b=3) - -f3(2, 3) -f3(2, b=3) - -# This should generate 1 error because a is a -# position-only parameter. -f3(a=2, b=3) - -f4(1, 2, c=3) -f4(1, b=2, c=3) - -# This should generate an error because c is a -# keyword-only parameter. -f4(1, 2, 3) - -# This should generate an error because a is a -# positional-only parameter. -f4(a=1, b=2, c=3) - -# This will an error because of the bad -# declaration. Test to make sure we don't crash. -f5(1, b=2, c=3) - -f6(1, b=2) -f6(a=1, b=2) - -class A: - def f(self, g: bool = False, /, **kwargs) -> None: - ... - -a = A() - -a.f(hello="world") - - -def f7(name: str, /, **kwargs: Any): - return 3 - -f7("hi", name=3) - -# This should generate an error -f7("hi", name=3, name=4) - - -class P1(Protocol): - def f(self, x: Any, /): - ... - - -class C1: - def f( - self, - y: Any, - ): - ... - - -c1: P1 = C1() - - -class P2(Protocol): - def f(self, x: Any): - ... - - -class C2: - def f(self, y: Any, /): - ... - - -# This should generate an error -c2: P2 = C2() - - -def f8(a: int, b: int = 3, /): - ... - - -kwargs: Dict[str, Any] = {} - -# This should generate an error -f8() - -# This should generate an error -f8(**kwargs) - - -f8(0, **kwargs) - -def f9(*, c: int): - pass - -# This should generate an error because it is missing a keyword -# argument for keyword parameter "c". -f9(*[1, 2, 3]) - - -# This should generate an error because "/" cannot be used after "*args" -def f10(x, *args, /, y): - pass - -# This should generate an error because "*" cannot be used after "*args" -def f11(x, *args, *, y): - pass - -def f15(x, /, *args): - pass - -# This should generate an error because x -# is a position-only parameter. -f15(x=1) - -def f16(x, /, *args, **kw): - pass - -# This should generate an error because x -# is a position-only parameter. -f16(x=1) - -def f12(a: int, b: str, /): - ... - - -def f13(v: Tuple[int, str]): - f12(*v) - -def f14(v: Tuple[int]): - # This should generate an error because parameter "b" has - # no corresponding argument. - f12(*v) diff --git a/packages/vipeye-internal/src/tests/samples/call4.py b/packages/vipeye-internal/src/tests/samples/call4.py deleted file mode 100644 index 2b81adcb..00000000 --- a/packages/vipeye-internal/src/tests/samples/call4.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests that the TypeVar matching logic for -# functions is working correctly. - -a: list[str] = ["a", "bc"] - -# This should work because the "sorted" is defined -# with the first parameter of Iterable[_T] and the -# 'key' parameter Callable[[_T], Any]. Since "len" -# is a function that takes a "Sized" and "str" is -# a "Sized", the result of this should be List[str]. -b: list[str] = sorted(a, key=len) diff --git a/packages/vipeye-internal/src/tests/samples/call5.py b/packages/vipeye-internal/src/tests/samples/call5.py deleted file mode 100644 index eba6913f..00000000 --- a/packages/vipeye-internal/src/tests/samples/call5.py +++ /dev/null @@ -1,94 +0,0 @@ -# This sample tests handling of unpack operators used -# for arguments that are of a specified length (specifically, -# tuples with a specified list of elements types). - -from typing import NamedTuple, List, Tuple - -X = NamedTuple("X", [("a", int), ("b", str), ("c", str)]) - -q0: List[Tuple[int, str, str]] = [(1, "", ""), (2, "", "")] - -[X(*item) for item in q0] - - -q1: List[Tuple[int, str, float]] = [(1, "a", 3), (2, "b", 4), (3, "c", 5)] - -# This should generate an error because the items in q1 are not the -# right type for the X constructor. -[X(*item) for item in q1] - - -q2: List[Tuple[int, str]] = [(1, "1"), (2, "2"), (3, "3")] - -# This should generate an error because the items in q2 contain only -# two elements, and we need three to populate all three parameters -# in the X constructor. -[X(*item) for item in q2] - - -q3: List[Tuple[int, str, str, float]] = [ - (1, "a", "3", 4), - (2, "b", "4", 5), - (3, "c", "5", 6), -] - -# This should generate an error because the items in q3 contain -# four elements, and we need three to populate all parameters -# in the X constructor. -[X(*item) for item in q3] - - -q4: List[Tuple[int, ...]] = [ - (1, 3), - (2, 5), - (3, 6), -] - -# This should generate two errors because it isn't assignable to parameter -# b or c. -[X(*item) for item in q4] - - -Y = NamedTuple("Y", [("a", str), ("b", str), ("c", str)]) - -q5: List[Tuple[str, ...]] = [ - ("a", "b"), - ("a", "b"), -] - -[Y(*item) for item in q5] - - -class Z(NamedTuple): - a: list[str] - b: list[int] - - -q6 = Z(["1"], [3]) - -for a, b in zip(*q6): - reveal_type(a, expected_text="str") - reveal_type(b, expected_text="int") - - -def func1(a: list[str], c: list[int]): ... - - -func1(*q6) - - -class ABC(NamedTuple): - a: float - b: float - c: float - - def to_rgba(self) -> "ABC": - return ABC(*self) - - -class AB(NamedTuple): - a: float - b: float - - def to_abc(self) -> ABC: - return ABC(*self, 1) diff --git a/packages/vipeye-internal/src/tests/samples/call6.py b/packages/vipeye-internal/src/tests/samples/call6.py deleted file mode 100644 index 958e9ade..00000000 --- a/packages/vipeye-internal/src/tests/samples/call6.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the handling of unpack operators -# used in argument expressions when used in conjunction with -# tuples and *args parameters. - - -def func1(a: int, b: int): - pass - - -def func2(*args: int): - pass - - -fixed_tuple_0 = () -func1(*fixed_tuple_0, 2, 3) -func2(*fixed_tuple_0, 2) - -fixed_tuple_1 = (1,) - -# This should generate an error because there -# are too many parameters. -func1(*fixed_tuple_1, 2, 3) - -func2(*fixed_tuple_1, 2, *fixed_tuple_0) - -fixed_tuple_3 = (1, 3, 5) - -# This should generate an error because there -# are too many parameters. -func1(*fixed_tuple_3, 2) - -func2(*fixed_tuple_3, 2, *fixed_tuple_0) - -unbounded_tuple: tuple[int, ...] = (1, 5, 3) - -func2(*unbounded_tuple) -func2(*unbounded_tuple, 2) - - -def func3(*args: str): ... - - -def func4(v1: list[str] | None, v2: None, v3: list[str]): - # This should generate an error. - func3(*v1) - - # This should generate an error. - func3(*v2) - - func3(*v3) diff --git a/packages/vipeye-internal/src/tests/samples/call7.py b/packages/vipeye-internal/src/tests/samples/call7.py deleted file mode 100644 index 4f99d29e..00000000 --- a/packages/vipeye-internal/src/tests/samples/call7.py +++ /dev/null @@ -1,85 +0,0 @@ -# This sample tests the handling of an unpacked TypedDict passed as -# an argument to a function. - -from typing import TypedDict, Unpack - - -class TD1(TypedDict): - arg1: int - arg2: str - - -class TD2(TD1): - arg3: float - - -def func1(arg1: int, arg2: str): - pass - - -def func2(arg1: int, arg2: str, arg3: float): - pass - - -def func3(arg1: int, arg2: str, **kwargs: float): - pass - - -def func4(arg1: int, arg2: str, **kwargs: int): - pass - - -def func5(arg1: int, arg2: str, **kwargs: object): - pass - - -td1: TD1 = {"arg1": 10, "arg2": "something"} -td2: TD2 = {"arg1": 10, "arg2": "something", "arg3": 3.4} - -func1(**td1) - -# This should generate an error because "arg1" is already assigned -func1(arg1=3, **td1) - -# This should generate an error because "arg3" isn't provided -func1(**td2) - -# This should generate an error because "arg3" isn't matched -func2(**td1) - -func2(**td2) - - -# This should generate an error because the extra entries -# in the TD are of type object. -func3(**td1) - -# This should generate an error because the extra entries -# in the TD are of type object. -func3(**td2) - -# This should generate an error because the extra entries -# in the TD are of type object. -func4(**td1) - -func5(**td1) -func5(**td2) - -# This should generate two errors because "arg3" cannot be matched -# due to the type of the **kwargs parameter. Also, the extra entries -# in the TD are of type object. -func4(**td2) - - -class Options(TypedDict, total=False): - opt1: bool - opt2: str - - -def func6(code: str | None = None, **options: Unpack[Options]): - pass - - -func6(**{}) -func6(**{"opt1": True}) -func6(**{"opt2": "hi"}) diff --git a/packages/vipeye-internal/src/tests/samples/call8.py b/packages/vipeye-internal/src/tests/samples/call8.py deleted file mode 100644 index 057e0254..00000000 --- a/packages/vipeye-internal/src/tests/samples/call8.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests a case where multiple overloaded calls are nested -# within each other. - -from typing import Any, Iterable, TypeVar, Protocol, overload -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - LiteralString, -) - -_T = TypeVar("_T") -_T_co = TypeVar("_T_co", covariant=True) - - -class SupportsLenAndGetItem(Protocol[_T_co]): - def __getitem__(self, __k: int) -> _T_co: ... - - -def choices(population: SupportsLenAndGetItem[_T]) -> list[_T]: ... - - -@overload -def join(__iterable: Iterable[LiteralString]) -> LiteralString: # type:ignore - ... - - -@overload -def join(__iterable: Iterable[str]) -> str: ... - - -@overload -def array(object: int) -> list[Any]: ... - - -@overload -def array(object: object) -> list[Any]: ... - - -def array(object: object) -> list[Any]: ... - - -array([join(choices("")) for i in range(1)]) diff --git a/packages/vipeye-internal/src/tests/samples/call9.py b/packages/vipeye-internal/src/tests/samples/call9.py deleted file mode 100644 index 662449e2..00000000 --- a/packages/vipeye-internal/src/tests/samples/call9.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the case where a dictionary expansion operator -# is used in a call. The type checker should verify that the -# type supports a SupportsKeyAndGetItem protocol. - -from typing import Any, Generic, Iterator, TypeVar, Mapping, KeysView - - -class MyMapping(Mapping[str, Any]): - def __getitem__(self, __key: str) -> Any: ... - - def __iter__(self) -> Iterator[str]: ... - - def __len__(self) -> int: ... - - -class StrRecord: - def __getitem__(self, __key: str) -> str: ... - - def keys(self) -> KeysView[str]: ... - - -T = TypeVar("T") - - -class GenericRecord(Generic[T]): - def __getitem__(self, __key: str) -> T: ... - - def keys(self) -> KeysView[T]: ... - - -def func1(**kwargs: Any) -> None: ... - - -m = MyMapping() -r = StrRecord() - - -def func2( - m: MyMapping, - r: StrRecord, - g: GenericRecord[str], - mrg: MyMapping | StrRecord | GenericRecord[str], - bad: GenericRecord[bytes], -): - func1(**m) - func1(**r) - func1(**g) - func1(**mrg) - - # This should generate an error. - func1(**bad) diff --git a/packages/vipeye-internal/src/tests/samples/callSite1.py b/packages/vipeye-internal/src/tests/samples/callSite1.py deleted file mode 100644 index 9285cdc8..00000000 --- a/packages/vipeye-internal/src/tests/samples/callSite1.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests pyright's ability to perform return type -# analysis of functions based on call-site arguments. - - -# This function has no type annotations -from typing import TypeVar - -T = TypeVar("T") - - -def add(a, b): - return a + b - - -async def async_call(x): - return x - - -def deco1(f: T) -> T: - return f - - -@deco1 -def add2(a, b): - return a + b - - -def identity(a): - return a - - -def func1(x: T) -> T: - a = identity(x) - reveal_type(a, expected_text="T@func1") - return a diff --git a/packages/vipeye-internal/src/tests/samples/callSite2.py b/packages/vipeye-internal/src/tests/samples/callSite2.py deleted file mode 100644 index a730492f..00000000 --- a/packages/vipeye-internal/src/tests/samples/callSite2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests pyright's ability to perform return type -# analysis of functions based on call-site arguments. - -from .callSite1 import add, add2, async_call - -v1 = add(1, 2) -reveal_type(v1, expected_text="Literal[3]") - -v2 = add("hi", "there") -reveal_type(v2, expected_text="Literal['hithere']") - -v3 = add2(1, 2) -reveal_type(v3, expected_text="Unknown") - -v4 = async_call(1) -reveal_type(v4, expected_text="CoroutineType[Any, Any, Unknown]") diff --git a/packages/vipeye-internal/src/tests/samples/callSite3.py b/packages/vipeye-internal/src/tests/samples/callSite3.py deleted file mode 100644 index 65a89a82..00000000 --- a/packages/vipeye-internal/src/tests/samples/callSite3.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the case where a call-site return type evaluation -# is invoked multiple times within a loop using different literal values -# each time. - - -def func1(h, ids): - for _ in ids: - h = func2(h, 1) - h = func2(h, 2) - h = func2(h, 3) - h = func2(h, 4) - h = func2(h, 5) - h = func2(h, 6) - h = func2(h, 7) - h = func2(h, 8) - h = func2(h, 9) - h = func2(h, 10) - h = func2(h, 11) - h = func2(h, 12) - h = func2(h, 13) - h = func2(h, 14) - h = func2(h, 15) - h = func2(h, 16) - h = func2(h, 17) - h = func2(h, 18) - h = func2(h, 19) - h = func2(h, 20) - h = func2(h, 21) - h = func2(h, 22) - h = func2(h, 23) - h = func2(h, 24) - h = func2(h, 25) - h = func2(h, 26) - h = func2(h, 27) - h = func2(h, 28) - h = func2(h, 29) - h = func2(h, 30) - h = func2(h, 31) - h = func2(h, 32) - h = func2(h, 33) - h = func2(h, 34) - h = func2(h, 35) - h = func2(h, 36) - h = func2(h, 37) - h = func2(h, 38) - h = func2(h, 39) - - -def func2(a, unused): - return a diff --git a/packages/vipeye-internal/src/tests/samples/callable1.py b/packages/vipeye-internal/src/tests/samples/callable1.py deleted file mode 100644 index 7689e906..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable1.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the type checker's handling of the -# builtin "Callable" class. - -from typing import Callable - -Callable1 = Callable[["A"], None] - - -class A: - pass - - -Callable2 = Callable[[A], None] - - -def func1(a: Callable1): - a(A()) - - -def func2(a: Callable2): - a(A()) - - -Callable3 = Callable[..., int] - - -def func3(a: Callable3) -> int: - return a(1, 2, 3) + a() + a("hello") + a([]) - - -# This should generate an error (... not allowed in param list). -Callable4 = Callable[[...], int] - -# This should generate an error (too many arguments). -Callable5 = Callable[..., int, int] - - -# Test Callable with no parameters -Callable6 = Callable[[], str] - - -def func6(a: Callable6): - a() - # This should generate an error. - a(1) - - -def func7(a: Callable): - reveal_type(a, expected_text="(...) -> Unknown") - b = a(3, 4, 5) - reveal_type(b, expected_text="Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/callable2.py b/packages/vipeye-internal/src/tests/samples/callable2.py deleted file mode 100644 index b4edd3b5..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable2.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests the assignment of generic callables -# to concrete callable types. - -from asyncio.futures import Future -from asyncio.tasks import ensure_future -from typing import Any, Awaitable, Callable, Iterable, Sequence, TypeVar - - -_T1 = TypeVar("_T1") - - -def func1(__iterable: Iterable[_T1]) -> _T1: ... - - -a: Callable[[Sequence[float]], float] = func1 -b: Callable[[Sequence[Any]], Any] = func1 - - -def func2(__iterable: Sequence[_T1]) -> _T1: ... - - -# This should generate an error because an Iterable parameter -# is not assignable to a Sequence parameter. -c: Callable[[Iterable[float]], float] = func2 - - -_T2 = TypeVar("_T2", bound=float) - - -def func3(__iterable: Iterable[_T2]) -> _T2: ... - - -d: Callable[[Sequence[int]], int] = func3 - -# This should generate an error because Sequence[str] -# is not compatible with the bound TypeVar _T2. -e: Callable[[Sequence[str]], Any] = func3 - - -_T3 = TypeVar("_T3") - -TA1 = Callable[[_T3], None] -TA2 = Callable[[TA1[_T3]], None] - - -def func4(cb: TA2[_T3]) -> Awaitable[_T3]: - future: Future[_T3] = Future() - return ensure_future(future) - - -def func5(done: TA1[int]) -> None: - pass - - -reveal_type(func4(func5), expected_text="Awaitable[int]") diff --git a/packages/vipeye-internal/src/tests/samples/callable3.py b/packages/vipeye-internal/src/tests/samples/callable3.py deleted file mode 100644 index a04d3ee6..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable3.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the case where a callable type contains a -# callable type as an input parameter, and the latter callable -# contains generic types. - -from typing import Callable, Generic, TypeVar - -T = TypeVar("T") -R = TypeVar("R") - - -class ClassA(Generic[R]): ... - - -class ClassB(Generic[T]): - def method1(self, val: Callable[[ClassA[R]], T]) -> R | None: - return None - - -b1: ClassB[tuple[int, ClassA[str]]] = ClassB() -v1: Callable[[ClassA[str]], tuple[int, ClassA[str]]] = lambda r: (42, r) - -ret = b1.method1(v1) -reveal_type(ret, expected_text="str | None") diff --git a/packages/vipeye-internal/src/tests/samples/callable4.py b/packages/vipeye-internal/src/tests/samples/callable4.py deleted file mode 100644 index 56851cb8..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable4.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the case where a callable type within a function -# signature contains a generic return type within a union. - -from typing import TypeVar -from collections.abc import Callable - - -T = TypeVar("T") -U = TypeVar("U") - - -def func1(f: Callable[[T], U | None], x: T) -> U: - y = f(x) - - reveal_type(y, expected_text="U@func1 | None") - - if y is not None: - reveal_type(y, expected_text="U@func1") - return y - - raise ValueError() - - -def func2(x: T, f: Callable[[T], U | None]) -> U: - def g() -> U: - y = f(x) - if y is not None: - return y - - raise ValueError() - - return g() diff --git a/packages/vipeye-internal/src/tests/samples/callable5.py b/packages/vipeye-internal/src/tests/samples/callable5.py deleted file mode 100644 index 3c2893c4..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable5.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample covers the case where a function accepts a generic callable -# as a parameter along with another parameter that uses the same type variable -# and a caller provides an overloaded function as an argument. - -from typing import Any, Callable, TypeVar, overload - -T = TypeVar("T") - - -@overload -def func1(real: float): ... - - -@overload -def func1(real: str): ... - - -def func1(real: float | str) -> None: ... - - -def func2(f: Callable[[T], Any], p: T): - return f(p) - - -func2(func1, 4) -func2(func1, "4") - -# This should generate an error because a "bytes" argument -# doesn't match any of the overloads. -func2(func1, b"") - - -map(complex, ["3j", "4"]) - -# This should generate two errors because a "bytes" argument -# doesn't match any of the overloads in the "complex" constructor. -map(complex, [b"3j"]) diff --git a/packages/vipeye-internal/src/tests/samples/callable6.py b/packages/vipeye-internal/src/tests/samples/callable6.py deleted file mode 100644 index 99b227e8..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable6.py +++ /dev/null @@ -1,91 +0,0 @@ -# This sample tests the use of unpacked tuples in a Callable, as described -# in PEP 646. - -from typing import Callable, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -_T = TypeVar("_T", bound=int) - -TA1 = Callable[[_T, Unpack[tuple[int, ...]], tuple[int, int, str], str], _T] - -# This should generate an error. -TA2 = Callable[ - [int, Unpack[tuple[int, ...]], Unpack[tuple[int, int, str, ...]], str], int -] - -TA3 = Callable[[int, Unpack[tuple[int, int]], str], int] - -TA4 = Callable[[Unpack[tuple[int, ...]]], _T] - - -def func1(x: TA1[int]): - r1 = x(3, 4, 5, (1, 2, "hi"), "hi") - reveal_type(r1, expected_text="int") - - x(3, (1, 2, "hi"), "hi") - - # This should generate an error because the first argument is not an int. - x(None, (1, 2, "hi"), "hi") - - y = [1, 2, 3] - x(1, *y, (1, 2, "hi"), "hi") - - -def func2(x: TA3): - x(3, 4, 5, "hi") - - # This should generate an error. - x(3, 4, "hi") - - # This should generate an error. - x(3, 4, "hi", "hi") - - -def func6(x: TA4): - x() - - -Ts = TypeVarTuple("Ts") - - -def func3( - path: str, *args: Unpack[tuple[Unpack[Ts], str]] -) -> tuple[Unpack[Ts], int]: ... - - -v3 = func3("", 1, "2", 3.3, None, "") -reveal_type(v3, expected_text="tuple[int, str, float, None, int]") - -func3("", "") - -# This should generate an error because the type of the first arg is wrong. -func3(1, "") - -# This should generate an error because the type of the last arg is wrong. -func3("", 1) - -# This should generate an error because the type of the last arg is wrong. -func3("", 1, 2, 3, "hi", 1) - - -def func4( - path: str, *args: Unpack[tuple[Unpack[Ts], str]] -) -> tuple[Unpack[Ts], complex]: ... - - -v4 = func4("", 1, "2", 3.3, None, "") -reveal_type(v4, expected_text="tuple[int, str, float, None, complex]") - - -def func5(path: str, *args: Unpack[tuple[str, ...]]) -> None: ... - - -# This should generate an errors. -func5("", 1, "2", "") -func5("", "1", "2", "3.3", "None", "") - -# This should generate one error. -func5("", "1", "2", "3.3", "None", 3) diff --git a/packages/vipeye-internal/src/tests/samples/callable7.py b/packages/vipeye-internal/src/tests/samples/callable7.py deleted file mode 100644 index 42841d99..00000000 --- a/packages/vipeye-internal/src/tests/samples/callable7.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the handling of the `__call__` attribute. - - -from typing import Iterable, Iterator - - -class A: - def __init__(self): - self.__call__ = self.method1 - - def method1(self, a: int): - return a - - -# This should generate an error because `__call__` is -# callable only if it's a class variable. -A()(0) - - -class B: - def method1(self, a: int): - return a - - __call__ = method1 - - -B()(0) - - -class C[K](Iterable[K]): - def keys(self) -> Iterator[K]: ... - - __iter__ = keys diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol1.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol1.py deleted file mode 100644 index 3ca87886..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol1.py +++ /dev/null @@ -1,159 +0,0 @@ -# This sample tests support for callback protocols (defined in PEP 544). - -from typing import Callable, Protocol - - -class TestClass1(Protocol): - def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: - return [] - - -def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]: - return [] - - -def bad_cb1(*vals: bytes, maxlen: int | None, maxitems: int | None) -> list[bytes]: - return [] - - -def bad_cb2(*vals: bytes) -> list[bytes]: - return [] - - -def bad_cb3(*vals: bytes, maxlen: str | None) -> list[bytes]: - return [] - - -var1: TestClass1 = good_cb - -# This should generate an error because maxitems is unmatched. -var1 = bad_cb1 - -# This should generate an error because maxlen is unmatched. -var1 = bad_cb2 - -# This should generate an error because maxlen is the wrong type. -var1 = bad_cb3 - - -class TestClass2(Protocol): - def __call__(self, *vals: bytes, **kwargs: str) -> None: - pass - - -def func1(*a: bytes, **b: str): - pass - - -def func2(*a: bytes): - pass - - -def func3(*a: str, **b: str): - pass - - -def func4(*a: bytes, **b: bytes): - pass - - -def func5(**b: str): - pass - - -var2: TestClass2 = func1 - -# This should generate an error. -var2 = func2 - -# This should generate an error. -var2 = func3 - -# This should generate an error. -var2 = func4 - -# This should generate an error. -var2 = func5 - - -class NotProto: - def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: - return [] - - -# This should generate an error because NotProto is not a protocol class. -not_proto: NotProto = good_cb - - -class TestClass3(Protocol): - def __call__(self) -> None: - pass - - -var3: TestClass3 = func1 - -var3 = func2 -var3 = func3 -var3 = func4 -var3 = func5 - - -class TestClass4(Protocol): - foo: int - - def __call__(self, x: int) -> None: - pass - - -def test_func4(x: int) -> None: - pass - - -# This should generate an error. -var4: TestClass4 = test_func4 - - -class TestClass5(Protocol): - def __call__(self, *, a: int, b: str) -> int: ... - - -def test_func5(a: int, b: str) -> int: - return 123 - - -f5: TestClass5 = test_func5 - - -class TestClass6(Protocol): - def __call__(self, a: int, /, *, b: str) -> int: ... - - -def test_func6(a: int, b: str) -> int: - return 123 - - -f6: TestClass6 = test_func6 - - -class TestClass7: - def __call__(self) -> None: - pass - - -def test_func7(*args: *tuple[int, *tuple[int, ...]]) -> int: - return 123 - - -# This should generate an error. -f7: TestClass7 = test_func7 - - -class TestClass8: - def __call__(self: Callable[[int], int], v: int) -> int: - return v - - -def func8(f: Callable[[int], int]): ... - - -func8(TestClass8()) diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol10.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol10.py deleted file mode 100644 index 0d813d34..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol10.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests the case where a callback protocol uses -# a (*args: Any, **kwargs: Any) signature. - - -from typing import Any, Callable, Concatenate, ParamSpec, Protocol, TypeVar - -P = ParamSpec("P") -T_contra = TypeVar("T_contra", contravariant=True) - - -class Proto1(Protocol): - def __call__(self, *args, **kwargs) -> None: ... - - -class Proto2(Protocol): - def __call__(self, a: int, /, *args, **kwargs) -> None: ... - - -class Proto3(Protocol): - def __call__(self, a: int, *args: Any, **kwargs: Any) -> None: ... - - -class Proto4(Protocol[P]): - def __call__(self, a: int, *args: P.args, **kwargs: P.kwargs) -> None: ... - - -class Proto5(Protocol[T_contra]): - def __call__(self, *args: T_contra, **kwargs: T_contra) -> None: ... - - -class Proto6(Protocol): - def __call__(self, a: int, /, *args: Any, k: str, **kwargs: Any) -> None: - pass - - -class Proto7(Protocol): - def __call__(self, a: float, /, b: int, *, k: str, m: str) -> None: - pass - - -def func( - p1: Proto1, - p2: Proto2, - p3: Proto3, - p4: Proto4[...], - p5: Proto5[Any], - p7: Proto7, - c1: Callable[..., None], - c2: Callable[Concatenate[int, ...], None], -): - x1: Callable[..., None] = p1 - x2: Proto1 = c1 - x3: Callable[..., None] = p5 - x4: Proto5[Any] = c1 - x5: Callable[Concatenate[int, ...], None] = p2 - x6: Proto2 = c2 - x7: Callable[..., None] = p3 - x8: Proto3 = c1 - x9: Proto4[...] = p3 - x10: Proto3 = p4 - x11: Proto6 = p7 diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol11.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol11.py deleted file mode 100644 index 86f500ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol11.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a callback protocol uses a function- -# scoped type variable. - -from typing import Generic, Protocol, TypeVar - -T = TypeVar("T") -T_co = TypeVar("T_co", covariant=True) -U_co = TypeVar("U_co", covariant=True) - - -class A(Generic[T_co, U_co]): ... - - -class BProto(Protocol): - def __call__(self, x: T) -> A[list[T], T]: ... - - -def func1() -> BProto: - def make_a(x: T) -> A[list[T], T]: ... - - return make_a diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol2.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol2.py deleted file mode 100644 index 8a794105..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol2.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where an object is assigned to a -# callback protocol and the object's "__call__" has unannotated -# or "Any" parameter types. - -from typing import Any, Protocol, TypeVar - -InputT = TypeVar("InputT", contravariant=True) -OutputT = TypeVar("OutputT", covariant=True) - - -class MyCallable(Protocol[InputT, OutputT]): - def __call__(self, inputs: InputT) -> OutputT: ... - - -class Class1: - def __call__(self, inputs) -> int: - return 5 - - -g1: MyCallable[int, int] = Class1() - - -class Class2: - def __call__(self, inputs: Any) -> int: - return 5 - - -g2: MyCallable[int, int] = Class2() diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol3.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol3.py deleted file mode 100644 index f3e316c9..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol3.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a callback protocol uses a -# class-level type variable and a combination of Type[T] and T. - -from typing import Protocol, TypeVar, Type - -TE = TypeVar("TE", bound=Exception) - - -class CallbackProtocol1(Protocol[TE]): - def __call__(self, s_exc: Exception, t_exc_class: Type[TE]) -> TE: ... - - -def func1(s_exc: Exception, t_exc_class: Type[TE]) -> TE: ... - - -def func2( - s_exc_class: Exception, - t_exc_class: Type[TE], - mapper: CallbackProtocol1[TE] = func1, -): ... diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol4.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol4.py deleted file mode 100644 index ac35da9c..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol4.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests the case where a callback protocol uses -# an overloaded __call__ method. - -from typing import Any, Protocol, overload - - -class P1(Protocol): - @overload - def __call__(self, x: int) -> int: ... - - @overload - def __call__(self, x: str) -> str: ... - - def __call__(self, x: Any) -> Any: ... - - -def func0(x: Any) -> Any: - return x - - -def func1(x: int) -> Any: - return x - - -a0: P1 = func0 - -# This should generate an error -a1: P1 = func1 - - -@overload -def of1(x: int) -> int: ... - - -@overload -def of1(x: str) -> str: ... - - -def of1(x: Any) -> Any: - return x - - -@overload -def of2(x: int) -> complex: ... - - -@overload -def of2(x: str) -> str: ... - - -def of2(x: Any) -> Any: - return x - - -b0: P1 = of1 - -# This should generate an error -b1: P1 = of2 - - -class P2(Protocol): - def __call__(self, *args: int) -> Any: ... - - -a: P2 = lambda *args: map(lambda arg: arg + 0, args) diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol5.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol5.py deleted file mode 100644 index 44b06638..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol5.py +++ /dev/null @@ -1,84 +0,0 @@ -# This sample tests the case where a callback protocol defines additional -# attributes. - -from typing import Any, Callable, Protocol, TypeVar, cast -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - - -P = ParamSpec("P") -R = TypeVar("R", covariant=True) - - -class CallbackProto1(Protocol[P, R]): - __name__: str - - other_attribute: int - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -def decorator1(f: Callable[P, R]) -> CallbackProto1[P, R]: - converted = cast(CallbackProto1, f) - - print(converted.__name__) - - converted.other_attribute = 1 - - # This should generate an error - converted.other_attribute = "str" - - # This should generate an error - converted.xxx = 3 - - return converted - - -@decorator1 -def func1(x: int) -> str: ... - - -reveal_type(func1, expected_text="CallbackProto1[(x: int), str]") - -func1.other_attribute - -# This should generate an error -func1.other_attribute2 - -func1(x=3) - - -class CallbackProto2(Protocol): - __name__: str - __module__: str - __qualname__: str - __annotations__: dict[str, Any] - __slots__ = () - - def __call__(self) -> None: ... - - -def func2() -> None: ... - - -v: CallbackProto2 = func2 - - -class TestClass7(Protocol): - def __call__(self, x: int, /, y: str) -> Any: ... - - -def func8(x: int, y: str, /) -> Any: - pass - - -def func9(__x: int, __y: str) -> Any: - pass - - -# This should generate an error because "y" is position-only -# in the source but not the dest. -var7: TestClass7 = func8 - -# This should generate an error because "y" is position-only -# in the source but not the dest. -var8: TestClass7 = func9 diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol6.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol6.py deleted file mode 100644 index 5b465aee..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol6.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the case where a callback protocol uses a default argument -# but the corresponding callable does not or vice versa. - -from typing import Protocol - - -# Callback with positional parameter with default arg value. -class Callback1(Protocol): - def __call__(self, path: str = ...) -> str: ... - - -# Callback with positional parameter without default arg value. -class Callback2(Protocol): - def __call__(self, path: str) -> str: ... - - -def func1_1(path: str = "") -> str: ... - - -def func1_2(path: str) -> str: ... - - -val1_1: Callback1 = func1_1 - -# This should generate an error. -val1_2: Callback1 = func1_2 - -val2_1: Callback2 = func1_1 - -val2_2: Callback2 = func1_2 - - -# Callback with keyword parameter with default arg value. -class Callback3(Protocol): - def __call__(self, *, path: str = ...) -> str: ... - - -# Callback with keyword parameter without default arg value. -class Callback4(Protocol): - def __call__(self, *, path: str) -> str: ... - - -def func3_1(*, path: str = "") -> str: ... - - -def func3_2(*, path: str) -> str: ... - - -val3_1: Callback3 = func3_1 - -# This should generate an error. -val3_2: Callback3 = func3_2 - -val4_1: Callback4 = func3_1 - -val4_2: Callback4 = func3_2 diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol7.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol7.py deleted file mode 100644 index aa14470f..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol7.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the case where a callback protocol uses position-only -# parameters. - -from typing import Any, Protocol - - -class P0(Protocol): - def __call__(self, x: int, /, y: str) -> Any: ... - - -def test1(x: int, /, y: str, z: None = None) -> Any: ... - - -x: P0 = test1 - - -class P1(Protocol): - def __call__(self, *args: *tuple[int, int]): ... - - -class P2(Protocol): - def __call__(self, x: int, y: int, /): ... - - -class P3(Protocol): - def __call__(self, x: int, /, *args: *tuple[int]): ... - - -class P4(Protocol): - def __call__(self, x: int, y: int = 2, /): ... - - -def test2(p1: P1, p2: P2, p3: P3, p4: P4): - x1: P1 = p2 - x2: P1 = p3 - x3: P1 = p4 diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol8.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol8.py deleted file mode 100644 index 64454042..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol8.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the case where a callback protocol contains an *args -# and some keyword parameters. - -from typing import Any, Protocol - - -class P(Protocol): - def __call__(self, *args: Any, kwarg0: Any, kwarg1: Any) -> None: ... - - -def f(*args: Any, kwarg0: Any, kwarg1: Any) -> None: ... - - -p: P = f diff --git a/packages/vipeye-internal/src/tests/samples/callbackProtocol9.py b/packages/vipeye-internal/src/tests/samples/callbackProtocol9.py deleted file mode 100644 index d0dab9df..00000000 --- a/packages/vipeye-internal/src/tests/samples/callbackProtocol9.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests that a call through a __call__ handles the case -# where the __call__ is a callable object itself. - - -class A: - def __call__(self, v: int): - print("Received", v) - - -class B: - __call__ = A() - - -class C: - __call__ = B() - - -class D: - __call__ = C() - - -d = D() - -d(1) - -# This should generate an error because of the incompatible argument type. -d("1") - -# This should generate an error because of the wrong argument count. -d(1, 1) diff --git a/packages/vipeye-internal/src/tests/samples/capturedVariable1.py b/packages/vipeye-internal/src/tests/samples/capturedVariable1.py deleted file mode 100644 index 176219e4..00000000 --- a/packages/vipeye-internal/src/tests/samples/capturedVariable1.py +++ /dev/null @@ -1,146 +0,0 @@ -# This sample tests the code flow analysis used to determine -# whether it is safe to narrow the type of a captured variable. - -from typing import NoReturn, Optional - - -def get_optional_int() -> Optional[int]: ... - - -v0 = get_optional_int() -if v0 is not None: - # This should generate an error because v0 is - # a global variable and could be reassigned - # outside of this module. - lambda: v0 + 5 - - -def func0(): - v1 = get_optional_int() - if v1 is not None: - lambda: v1 + 5 - - v2 = get_optional_int() - if v2 is not None: - # This should generate an error because v2 - # is reassigned after capture. - lambda: v2 + 5 - v2 = None - - v3 = get_optional_int() - if v3 is not None: - lambda: v3 + 5 - else: - v3 = None - - # This should generate an error because v4 is - # not bound prior to the capture. - lambda: v4 + 5 - v4 = get_optional_int() - - -def func1(v1: Optional[int]): - if v1 is not None: - lambda: v1 + 5 - - -def func2(v1: Optional[int]): - if v1 is not None: - - def func2_inner1(): - x = v1 + 5 - - def func2_inner2(): - lambda: v1 + 5 - - func2_inner2() - - func2_inner1() - - -def func3(): - v1: Optional[int] = 3 - lambda: v1 + 5 - - -def func4(): - v1: Optional[int] = 3 - # This should generate an error because v1 - # is reassigned after capture. - lambda: v1 + 5 - v1 = None - - -def func5(): - v1: Optional[int] = 3 - - while True: - lambda: v1 + 5 - - -def func6(): - v1: Optional[int] = 3 - - while True: - if v1 is not None: - # This should generate an error because - # v1 is reassigned on a code path that is - # reachable from the lambda. - lambda: v1 + 5 - else: - v1 = None - - -def func7(): - while True: - # This should generate an error because v1 is - # potentially unbound prior to capture. - lambda: v1 + 5 - - v1: Optional[int] = 3 - - -def func8() -> NoReturn: ... - - -def func9(x: str | None): - if not x: - func8() - - def foo() -> str: - return x.upper() - - return x.upper() - - -def func10(cond: bool, val: str): - x: str | None = val if cond else None - y: str | None = val if cond else None - - def inner1(): - nonlocal x - x = None - - if x is not None and y is not None: - - def inner2(): - reveal_type(x, expected_text="str | None") - reveal_type(y, expected_text="str") - - -def func11(foo: list[int] | None): - if isinstance(foo, list): - - def inner() -> list[int]: - return [x for x in foo] - - -def func12() -> None: - counter = 0 - - def inner() -> None: - nonlocal counter - reveal_type(counter, expected_text="int") - counter += 1 - - inner() diff --git a/packages/vipeye-internal/src/tests/samples/capturedVariable2.py b/packages/vipeye-internal/src/tests/samples/capturedVariable2.py deleted file mode 100644 index 3c4089bb..00000000 --- a/packages/vipeye-internal/src/tests/samples/capturedVariable2.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a potentially-unbound variable -# in an outer scope is captured in an inner scope. - -from typing import Literal - - -def func1(subj: Literal[0, 1]) -> None: - v: int | None - - match subj: - case 0: - v = 1 - - def inner1() -> int: - # This should generate an error - return v - - def inner2() -> bool: - # This should generate an error - return v is None diff --git a/packages/vipeye-internal/src/tests/samples/circular1.py b/packages/vipeye-internal/src/tests/samples/circular1.py deleted file mode 100644 index d41d0dd9..00000000 --- a/packages/vipeye-internal/src/tests/samples/circular1.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the handling of a circular dependency -# when resolving a type annotation. - - -class Example1: - # This should generate two errors because "str" refers to itself - # and it is a variable, so it's an illegal annotation. - str: str = "" - - int = int - - test: int - - -class Example2: - int: "int" = 4 diff --git a/packages/vipeye-internal/src/tests/samples/circular2.py b/packages/vipeye-internal/src/tests/samples/circular2.py deleted file mode 100644 index 51427b93..00000000 --- a/packages/vipeye-internal/src/tests/samples/circular2.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the handling of circular dependencies between -# class declarations. - -# viper: strict - -from typing import Generic, TypeVar - -x: "F" - - -class A: - a_attr: object - - -_T = TypeVar("_T", bound=A) - - -class B(Generic[_T]): ... - - -class C(A): - template = B["E"]() - - -class D(A): - pass - - -class E(D): - pass - - -class F(D): - pass - - -E.a_attr diff --git a/packages/vipeye-internal/src/tests/samples/circularBaseClass.py b/packages/vipeye-internal/src/tests/samples/circularBaseClass.py deleted file mode 100644 index 562b76b0..00000000 --- a/packages/vipeye-internal/src/tests/samples/circularBaseClass.py +++ /dev/null @@ -1,16 +0,0 @@ -# This test validates that a circular base class reference -# will be reported and won't crash the analyzer. - - -# This should generate an error because 'Bar' is not bound. -class Bar(Bar): - pass - - -# This should generate an error because 'ClassB' is not bound. -class ClassA(ClassB): - pass - - -class ClassB(ClassA): - pass diff --git a/packages/vipeye-internal/src/tests/samples/classGetItem1.py b/packages/vipeye-internal/src/tests/samples/classGetItem1.py deleted file mode 100644 index fa2cca68..00000000 --- a/packages/vipeye-internal/src/tests/samples/classGetItem1.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the handling of a class with a custom -# __class_getitem__ class method. - - -from typing import Generic, TypeVar - - -class ClassA: - # This should generate a warning because __class_getitem__ - # is implicitly a classmethod and should use cls rather than - # self. - def __class_getitem__(self, args: tuple[int, ...]) -> None: ... - - -reveal_type(ClassA[10, 63], expected_text="type[ClassA]") - - -_T = TypeVar("_T") -_S = TypeVar("_S") - - -class ClassB(Generic[_T, _S]): - # Even though this class has a __class_getitem__ method, - # it will be assumed to follow normal generic class semantics. - def __class_getitem__(cls, args: tuple[int, ...]) -> None: ... - - -reveal_type(ClassB[int, str], expected_text="type[ClassB[int, str]]") diff --git a/packages/vipeye-internal/src/tests/samples/classVar1.py b/packages/vipeye-internal/src/tests/samples/classVar1.py deleted file mode 100644 index a59a93c5..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar1.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the type checker's handling of ClassVar -# as described in PEP 526. - -from typing import Any, ClassVar - - -class MyDescriptor: - def __get__(self, *args: Any) -> str: - return "" - - def __set__(self, obj: Any, value: str): - pass - - -class Starship: - captain: str = "Picard" - damage: int - stats: "ClassVar[dict[str, int]]" = {} - desc: ClassVar[MyDescriptor] = MyDescriptor() - - def __init__(self, damage: int, captain: str | None = None): - self.damage = damage - if captain: - self.captain = captain # Else keep the default - - def hit(self): - Starship.stats["hits"] = Starship.stats.get("hits", 0) + 1 - - -enterprise_d = Starship(3000) -Starship.stats = {} - -a = enterprise_d.stats - -# This should be flagged as an error because stats cannot -# be set via a class instance because it's a ClassVar. -enterprise_d.stats = {} - -# This should not generate an error because "desc" is a -# descriptor instance on the class. -enterprise_d.desc = "OK" diff --git a/packages/vipeye-internal/src/tests/samples/classVar2.py b/packages/vipeye-internal/src/tests/samples/classVar2.py deleted file mode 100644 index 9cf89aee..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the type checker's handling of ClassVar -# used within a Protocol, as specified in PEP 544. - -import typing as t -from typing import ClassVar as _ClassVar - - -class Proto(t.Protocol): - var1: t.ClassVar[str] - var2: t.ClassVar[str] - var3: _ClassVar = ["hi"] - - -class ProtoImpl: - var1 = "" - - def __init__(self) -> None: - self.var2 = "" - - -# This should generate an error because var2 -# is not a class variable. -a: Proto = ProtoImpl() - - -def func1(x: Proto): - reveal_type(x.var1, expected_text="str") - reveal_type(x.var2, expected_text="str") - reveal_type(x.var3, expected_text="list[str]") diff --git a/packages/vipeye-internal/src/tests/samples/classVar3.py b/packages/vipeye-internal/src/tests/samples/classVar3.py deleted file mode 100644 index 2a9d21fd..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar3.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the reporting of errors for ClassVar in contexts -# where it is not allowed. - -from typing import Annotated, Any, ClassVar, Final, Generic, TypeAlias, TypeVar -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] - -# This should generate an error. -x: ClassVar[int] = 3 - -T = TypeVar("T") - -# This should generate an error. -TA1: TypeAlias = ClassVar[str] - - -class Foo(Generic[T]): - x: ClassVar[int] = 3 - - # This should generate an error. - y: Final[ClassVar[int]] = 3 - - # This should generate an error. - z: list[ClassVar[int]] = [] - - # This should generate an error because TypeVars cannot - # be used in a ClassVar. - illegal1: ClassVar[list[T]] - - # This should generate an error because TypeVars cannot - # be used in a ClassVar. - illegal2: ClassVar[T] - - # This should generate an error because Final cannot be - # used with a ClassVar. - illegal3: ClassVar[Final] = 0 - - # This should generate an error because Final cannot be - # used with a ClassVar. A second error is generated because - # Final[int] is not interpreted as a valid type. - illegal4: ClassVar[Final[int]] = 0 - - ok1: ClassVar[list] - ok2: ClassVar[list[Any]] - ok3: Annotated[ClassVar[list[Self]], ""] - - # This should generate an error. - def func1(self, a: ClassVar[int]): - # This should generate an error. - x: ClassVar[str] = "" - - # This should generate an error. - self.xx: ClassVar[str] = "" - - # This should generate an error. - def func2(self) -> ClassVar[int]: - return 3 diff --git a/packages/vipeye-internal/src/tests/samples/classVar4.py b/packages/vipeye-internal/src/tests/samples/classVar4.py deleted file mode 100644 index dcb67fe8..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar4.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests that an error when attempting to access -# a non-ClassVar protocol attribute from a protocol class. - -from typing import ClassVar, Protocol - - -class SomeProtocol(Protocol): - x: int = 3 - y: int - z: ClassVar[int] - - @classmethod - def meth1(cls) -> None: - return None - - @staticmethod - def meth2() -> None: - return None - - -class Class(SomeProtocol): - y = 0 - z = 0 - - -def func1() -> None: - # Previously (prior to pyright 1.1.315), this generated an error - # because x was not explicitly declared as a ClassVar. This was changed - # to match mypy, which treats this as a normal class variable -- one that - # can be accessed as both a class an instance variable. - x: int = Class.x - - # Same as above. - y: int = Class.y - - z: int = Class.z - - Class.meth1 - Class.meth2 diff --git a/packages/vipeye-internal/src/tests/samples/classVar5.py b/packages/vipeye-internal/src/tests/samples/classVar5.py deleted file mode 100644 index c255c4d5..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar5.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the access of a ClassVar that uses Self in its -# declaration. - -# It's not clear whether this should be permitted. Arguably, it's not -# type safe, but mypy admits it. This should be clarified in the typing -# spec. - -from typing import ClassVar, Self - - -class Parent: - x: ClassVar[dict[str, Self]] = {} - - @classmethod - def __init_subclass__(cls): - cls.x = {} diff --git a/packages/vipeye-internal/src/tests/samples/classVar6.py b/packages/vipeye-internal/src/tests/samples/classVar6.py deleted file mode 100644 index 8b93db50..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar6.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests that a ClassVar is disallowed when used in a -# NamedTuple or TypedDict class as reflected in the runtime. - -from typing import ClassVar, NamedTuple, TypedDict - - -class NT1(NamedTuple): - # This should generate an error. - x: ClassVar - - # This should generate an error. - y: ClassVar[int] - - -class TD1(TypedDict): - # This should generate an error. - x: ClassVar - - # This should generate an error. - y: ClassVar[int] diff --git a/packages/vipeye-internal/src/tests/samples/classVar7.py b/packages/vipeye-internal/src/tests/samples/classVar7.py deleted file mode 100644 index 09bac19e..00000000 --- a/packages/vipeye-internal/src/tests/samples/classVar7.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the handling of a "bare" ClassVar with no -# subscript. - -from typing import ClassVar - - -class A: - a: ClassVar - b: ClassVar = 2 - c: ClassVar - d: ClassVar - - d = 3 - - @classmethod - def m1(cls) -> None: - cls.c = "" - - -reveal_type(A.a, expected_text="Unknown") -A.a = 3 -A.a = "" - -reveal_type(A.b, expected_text="int") -A.b = 2 - -# This should generate an error -A.b = "" - -reveal_type(A.c, expected_text="Unknown") -A.c = 2 -A.c = "" - -reveal_type(A.d, expected_text="int") -A.d = 2 - -# This should generate an error -A.d = "" diff --git a/packages/vipeye-internal/src/tests/samples/classes1.py b/packages/vipeye-internal/src/tests/samples/classes1.py deleted file mode 100644 index b15fdfd3..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes1.py +++ /dev/null @@ -1,88 +0,0 @@ -# This sample tests the type checker's ability to -# handle various class definition cases. - - -from typing import Any, Self, TypeVar - - -T = TypeVar("T") -T2 = TypeVar("T2", bound=type[Any]) - - -class A: - ... - - -class B: - C: type[A] - - -app = B() - - -class D(app.C): - ... - - -class EMeta(type): - def __new__(mcls, *args: Any, **kwargs: Any): - ... - - -class E(metaclass=EMeta): - pass - - -class F(E): - pass - - -class G[T](E, metaclass=type): - def my_method(self) -> "G": - reveal_type(__class__, expected_text="type[G[Unknown]]") - return __class__() - - -# This should generate an error because only one metaclass is supported. -class H(E, metaclass=type, metaclass=type): - pass - - -class I(E, other_keyword=2): - pass - - -args = [1, 2, 3] -kwargs = {"foo": 5} - - -class J(*args, **kwargs): - pass - - -def func1(x: type) -> object: - class Y(x): - pass - - return Y() - - -# This should generate an error because a TypeVar can't be used as a base class. -class K(T): - pass - - -class L(type[T]): - pass - - -def func2(cls: type[T]): - class M(cls): - pass - - -def func3(cls: T2) -> T2: - class M(cls): - pass - - return M diff --git a/packages/vipeye-internal/src/tests/samples/classes10.py b/packages/vipeye-internal/src/tests/samples/classes10.py deleted file mode 100644 index 7a412549..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes10.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the handling of dynamic base classes. - -from typing import TypeVar - -T_A = TypeVar("T_A", bound="A") - - -class A: - class InnerA: - pass - - -def dynamic_subclass1(cls: type[T_A]): - class SubClass(cls): - class SubInnerClass(cls.InnerA): - pass - - return SubClass - - -def dynamic_subclass2(base: type[A] | None): - class SubClass(base or A): ... - - return SubClass diff --git a/packages/vipeye-internal/src/tests/samples/classes11.py b/packages/vipeye-internal/src/tests/samples/classes11.py deleted file mode 100644 index ec68153a..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes11.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests the detection of mutually-incompatible base classes -# in classes that use multiple inheritance. - -from typing import Collection, Iterator, Mapping, Sequence, TypeVar - - -# This should generate an error. -class A(Mapping[str, int], Collection[int]): - def __len__(self) -> int: ... - - def __iter__(self) -> Iterator[str]: ... - - -# This should generate an error. -class B(Mapping[str, int], Sequence[int]): ... - - -# This should generate an error. -class C(Sequence[int], Mapping[str, int]): ... - - -class D(Sequence[float], Mapping[float, int]): ... - - -class E(Sequence[float], Mapping[int, int]): ... - - -# This should generate an error. -class F(Mapping[int, int], Sequence[float]): ... - - -T = TypeVar("T") -S = TypeVar("S") - - -class G(Mapping[T, S], Collection[T]): - def __len__(self) -> int: ... - - def __iter__(self) -> Iterator[T]: ... - - -# This should generate an error. -class H(Mapping[T, S], Collection[S]): - def __len__(self) -> int: ... - - def __iter__(self) -> Iterator[T]: ... diff --git a/packages/vipeye-internal/src/tests/samples/classes3.py b/packages/vipeye-internal/src/tests/samples/classes3.py deleted file mode 100644 index bc8c5b41..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes3.py +++ /dev/null @@ -1,125 +0,0 @@ -# This sample tests that various class variables (as defined in -# the type metaclass) are accessible without a type error. - - -from typing import TypeVar - - -class TestClass: - # These should be accessible within the class body - print(__doc__) - print(__module__) - print(__name__) - print(__qualname__) - - -base = TestClass.__base__ -basic_size = TestClass.__basicsize__ -dict = TestClass.__dict__ -dict_offset = TestClass.__dictoffset__ -flags = TestClass.__flags__ -item_size = TestClass.__itemsize__ -module = TestClass.__module__ -mro = TestClass.__mro__ -name = TestClass.__name__ -qualname = TestClass.__qualname__ -reveal_type(qualname, expected_text="str") -text_signature = TestClass.__text_signature__ -subclasses = TestClass.__subclasses__ - - -# This should generate an error. -dummy = TestClass.__dummy__ - -instance = TestClass() - -instance.__doc__ -instance.__module__ - -# This should generate an error. -instance.__name__ - -# This should generate an error. Although the binder adds __qualname__ to a -# class's symbol table to make it available within a class body, __qualname__ -# is exposed via the metaclass (type), not on instances, so instance access -# should be flagged. -instance.__qualname__ - - -class Meta(type): - def method1(self) -> str: - return self.__name__ - - -class NonMeta: - def method1(self) -> str: - # This should generate an error. - return self.__name__ - - -_T = TypeVar("_T") - - -def func1(cls: type[_T]) -> _T: - x1 = cls.__dict__ - x2 = cls.__mro__ - - # Access through a class object (here a `type[_T]`) is valid and resolves - # via the metaclass `type`. - x3 = cls.__qualname__ - reveal_type(x3, expected_text="str") - - return cls() - - -class Sub(TestClass): - pass - - -sub_qualname = Sub.__qualname__ -reveal_type(sub_qualname, expected_text="str") - -sub_instance = Sub() - -# This should generate an error. A base class's implicit __qualname__ must not -# be surfaced as an instance member through the MRO of a derived class. -sub_instance.__qualname__ - - -class Outer: - class Inner: - # __qualname__ must remain name-resolvable inside nested class bodies. - print(__qualname__) - - inner_qualname = Inner.__qualname__ - reveal_type(inner_qualname, expected_text="str") - - -inner_instance = Outer.Inner() - -# This should generate an error. -inner_instance.__qualname__ - - -# A function object explicitly declares `__qualname__`, so accessing it must not -# be flagged. The implicit `__qualname__` symbol added to every class scope must -# not hide a legitimate, explicitly-declared member. -func_qualname = func1.__qualname__ -reveal_type(func_qualname, expected_text="str") - - -class WithQualname: - # A class-body `__qualname__` assignment. At runtime `type.__new__` consumes - # this to set the class's qualified name and removes it from the class - # `__dict__`, so `WithQualname().__qualname__` actually raises `AttributeError`. - # Pyright, however, models class-body assignments as instance-accessible class - # variables, so it treats this as a declared member and does not flag the - # instance access below. This test pins that class-variable modeling, not the - # runtime behavior. - __qualname__ = "WithQualname" - - -# Consistent with pyright's class-variable modeling above, this is not flagged -# even though the equivalent runtime access would raise `AttributeError`. -WithQualname().__qualname__ -reveal_type(WithQualname().__qualname__, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/classes4.py b/packages/vipeye-internal/src/tests/samples/classes4.py deleted file mode 100644 index d0bd1abf..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes4.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the type checker's ability to handle -# class variables that redefine a symbol in an outer -# scope but are not defined with an explicit class -# variable statement. - - -class ClassA: - bar: str = "hi" - - def __init__(self, val: str) -> None: - self.str = val - - @classmethod - def method1(cls, val: str) -> None: - cls.str = val diff --git a/packages/vipeye-internal/src/tests/samples/classes5.py b/packages/vipeye-internal/src/tests/samples/classes5.py deleted file mode 100644 index 394d982b..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes5.py +++ /dev/null @@ -1,291 +0,0 @@ -# This sample tests the reportIncompatibleVariableOverride -# configuration option. - -from typing import Any, ClassVar, Final, Protocol - - -class ParentClass1: - cv1: ClassVar[int] = 0 - cv2: ClassVar[int] = 0 - cv3: ClassVar[int] = 0 - cv4: ClassVar[int] = 0 - - var1: int - var2: str - var3: int | str - var4: int - var5: int - var6: int - var7: list[float] - var8: list[int] - var9: int - - _var1: int - __var1: int - - def __init__(self): - self.var10: int = 0 - self.var11: int = 0 - self.var12 = 0 - - -class Subclass1(ParentClass1): - # This should generate an error. - cv1 = "" - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - cv2: int = 3 - - cv3 = 3 - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled because it's overriding a non-final with a final. - cv4: Final = 3 - - # This should generate an error if reportIncompatibleVariableOverride is - # enabled because the type is incompatible. - var1: str - - var2: str - - # This should generate an error if reportIncompatibleVariableOverride is - # enabled because the member is mutable, and is therefore invariant. - var3: int - - # This should generate an error. - var4 = "" - - var5 = 5 - - # This should generate an error if reportIncompatibleVariableOverride is - # enabled because a property cannot override a variable. - @property - def var6(self) -> int: - return 3 - - # This should not generate an error because the inherited (expected) - # type of var7 is List[float], so the expression "[3, 4, 5]" should - # be inferred as List[float] rather than List[int]. - var7 = [3, 4, 5] - - # This should generate an error because floats are not allowed - # in a List[int]. - var8 = [3.3, 45.6, 5.9] - - # This should generate an error if reportIncompatibleVariableOverride is - # enabled. - var9: ClassVar[int] = 3 - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - _var1: str - - # This should not generate an error because it's a private name. - __var1: str - - def __init__(self): - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - self.var10: str = "" - - # This should generate an error. - self.var11 = "" - - self.var12 = "" - - -class ParentClass2: - cv_decl_1: float - cv_decl_2: float - cv_decl_3: float - cv_decl_4: float - cv_decl_5: float - cv_decl_6: float - - cv_infer_1 = 1.0 - cv_infer_2 = 1.0 - cv_infer_3 = 1.0 - cv_infer_4 = 1.0 - cv_infer_5 = 1.0 - cv_infer_6 = 1.0 - - def __init__(self): - self.iv_decl_1: float - self.iv_decl_2: float - self.iv_decl_3: float - - self.iv_infer_1 = 1.0 - self.iv_infer_2 = 1.0 - self.iv_infer_3 = 1.0 - - -class SubclassDeclared2(ParentClass2): - cv_decl_1: float - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - cv_decl_2: str - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - cv_decl_3: float | None - - cv_infer_1: int - cv_infer_2: str - cv_infer_3: float | None - - def __init__(self): - # This should generate an error if reportIncompatibleVariableOverride - # is enabled because the member is mutable and therefore invariant. - self.cv_decl_4: int - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - self.cv_decl_5: str - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - self.cv_decl_6: float | None - - self.cv_infer_4: int - self.cv_infer_5: str - self.cv_infer_6: float | None - - self.iv_decl_1: int - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - self.iv_decl_2: str - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - self.iv_decl_3: float | None - - self.iv_infer_1: int - self.iv_infer_2: str - self.iv_infer_3: float | None - - -class SubclassInferred2(ParentClass2): - cv_decl_1 = 1 - - # This should generate an error. - cv_decl_2 = "" - - # This should generate an error. - cv_decl_3 = None - - cv_infer_1 = 3 - cv_infer_2 = "" - cv_infer_3 = None - - def __init__(self): - self.cv_decl_4 = 1 - - # This should generate an error. - self.cv_decl_5 = "" - - # This should generate an error. - self.cv_decl_6 = None - - self.cv_infer_4 = 1 - self.cv_infer_5 = "" - self.cv_infer_6 = None - - self.iv_decl_1 = 1 - - # This should generate an error. - self.iv_decl_2 = "" - - # This should generate an error. - self.iv_decl_3 = None - - self.iv_infer_1 = 1 - self.iv_infer_2 = "" - self.iv_infer_3 = None - - -class SubclassTuple1(ParentClass2): - cv_decl_1, cv_decl_2, cv_decl_3 = (3, 4.5, 6.0) - - -class SubclassTuple2(ParentClass2): - # This should generate an error. - cv_decl_1, cv_decl_2, cv_decl_3 = (3, 4.5, None) - - -class ConfigBase: ... - - -class ParentClass3(Protocol): - Config1: ClassVar[type[ConfigBase]] - Config2: ClassVar[type[ConfigBase]] - - -class ChildClass3(ParentClass3): - class Config1(ConfigBase): ... - - # This should generate an error if reportIncompatibleVariableOverride - # is enabled. - class Config2: ... - - -class PeerClass1: - test1: str = "a" - test2: str | None = None - - @property - def test3(self) -> int: - return 3 - - test4: int - test5: Any - test6: float - test7: float - - -class PeerClass2: - test1: int = 1 - test2: int | None = None - test3: int - - @property - def test4(self) -> int: - return 3 - - test5: int - test6: Any - test7: int - - -# This should generate 4 errors if reportIncompatibleVariableOverride -# is enabled. -class MultipleInheritance1(PeerClass1, PeerClass2): - pass - - -class ParentClass4(Protocol): - x: ClassVar[int] - y: int - - -class ChildClass4(ParentClass4): - # This should generate 2 errors if reportIncompatibleVariableOverride - # is enabled, one for overriding a classvar with an instance var, the - # other for overriding a non-final with a final. - x: Final = 0 - - # This should generate 1 error if reportIncompatibleVariableOverride - # is enabled because it is overriding a non-final with a final. - y: Final = 0 - - -class ParentClass5: - def __eq__(self, other: object) -> bool: - return True - - -class ParentClass6: - def __hash__(self) -> int: - return 0 diff --git a/packages/vipeye-internal/src/tests/samples/classes6.py b/packages/vipeye-internal/src/tests/samples/classes6.py deleted file mode 100644 index e3701778..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes6.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests proper scopes for nested classes. - - -class A: - a = 5 - - class B: - # This should generate an error - b = a - - class C: - # This should generate an error - c = a - - # This should generate an error - d = b diff --git a/packages/vipeye-internal/src/tests/samples/classes7.py b/packages/vipeye-internal/src/tests/samples/classes7.py deleted file mode 100644 index 50054251..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes7.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests for duplicate base class detection. - -from typing import Generic, TypeVar - - -T = TypeVar("T") - - -class BaseClass(Generic[T]): - pass - - -IntBaseClass = BaseClass[float] - - -# This should generate an error because the same -# base class is used twice. -class SubClass(BaseClass[float], IntBaseClass): - pass diff --git a/packages/vipeye-internal/src/tests/samples/classes8.py b/packages/vipeye-internal/src/tests/samples/classes8.py deleted file mode 100644 index 2d158843..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes8.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the case where a generic class declaration refers -# to itself. This case should arguably be considered an error, but -# it does appear within the stdlib typeshed stubs (see os.scandir). - -from os import DirEntry -from types import TracebackType -from typing import AnyStr, ContextManager, Iterator -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] - - -class _ScandirIterator( - Iterator[DirEntry[AnyStr]], ContextManager["_ScandirIterator[AnyStr]"] -): - def __iter__(self) -> Self: ... - - def __next__(self) -> DirEntry[AnyStr]: ... - - def close(self) -> None: ... - - def __enter__(self) -> Self: ... - - def __exit__( - self, - __exc_type: type[BaseException] | None, - __exc_value: BaseException | None, - __traceback: TracebackType | None, - ) -> bool | None: ... - - -def scandir(path: AnyStr) -> _ScandirIterator[AnyStr]: ... - - -def thing(value: AnyStr): - with scandir(value) as it: - for file in it: - if isinstance(file.name, str): - if file.name.endswith(".xml"): - ... - elif isinstance(file.name, bytes): - if file.name.endswith(b".xml"): - ... diff --git a/packages/vipeye-internal/src/tests/samples/classes9.py b/packages/vipeye-internal/src/tests/samples/classes9.py deleted file mode 100644 index 9b237563..00000000 --- a/packages/vipeye-internal/src/tests/samples/classes9.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the reportIncompatibleVariableOverride -# configuration option in cases involving multiple inheritance -# where the override symbol is type compatible with the overridden. - - -# viper: reportIncompatibleVariableOverride=true - - -from typing import NotRequired, Required, TypedDict - - -class A: - class M: - pass - - -class B0(A): - class M(A.M): - pass - - -class B1(A): - class M(A.M): - pass - - -class C(B0, B1): - class M(B0.M, B1.M): - pass - - -class D0(B0): - pass - - -class D1(B1): - pass - - -class D(D0, D1, C): - pass - - -class E0(B0): - pass - - -class E1(B1): - pass - - -# This should generate an error because B0.M is not -# type compatible with B1.M. -class E(E0, E1): - pass - - -class TD_A1(TypedDict): - x: Required[int] - y: Required[int] - - -class TD_A2(TypedDict): - x: NotRequired[int] - y: Required[int] - - -# This should generate an error for x but not y. -class TD_A(TD_A1, TD_A2): ... diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow1.py b/packages/vipeye-internal/src/tests/samples/codeFlow1.py deleted file mode 100644 index 5b4d79a9..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow1.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests the type analyzer's ability to determine -# execution paths. - - -def func1(length: int) -> int: - n = 0 - while True: - if n >= length: - return n - n += 3 - else: - # This should not be flagged as an error - # because we should never get here. - return "hello" - - # This should not be flagged as an error - # because we should never get here. - return "not_returned" - - -def func2() -> int: - while None: - # This should not be flagged as an error - # because we should never get here. - return "hello" - else: - # This should be an error because the return - # type doesn't match. - return "hello" - - # This should not be an error because we - # should never get here. - return "not_returned" - - -def func3() -> str: - if True: - return "hello" - else: - # This should not be flagged as an error - # because we should never get here. - return 21 - - raise BaseException() - - # This should not be flagged as an error - # because we should never get here. - return 52 - - -def func4(length: int) -> int: - n = 0 - while True: - if n >= length: - return n - n += 3 - break - else: - return "hello" - - # This should be flagged as an error because - # the break in the while True loop means that - # we might get here, and the return type does - # not match. - return "not_returned" diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow10.py b/packages/vipeye-internal/src/tests/samples/codeFlow10.py deleted file mode 100644 index a49a5b13..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow10.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests type inference for variables reassigned inside a while -# loop using a list comprehension. This is a regression test for -# https://github.com/microsoft/pyright/issues/11321. - -# In this case, `lines` should remain `list[str]` throughout the loop, -# because the list comprehension iterates over `lines[1:]` whose element -# type is `str`. - -lines = ["ab", "bc", "ac", "ca"] -reveal_type(lines, expected_text="list[str]") - -while lines: - reveal_type(lines, expected_text="list[str]") - lines = [item for item in lines[1:]] diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow11.py b/packages/vipeye-internal/src/tests/samples/codeFlow11.py deleted file mode 100644 index 03cea4f1..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow11.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests that the position-based heuristic for skipping -# declarations in the same execution scope (typeEvaluator.ts) correctly -# defers to the flow engine for non-loop branching (if/else, try/except). -# Declarations that textually precede usage but are flow-unreachable -# should not contribute a bound type at the usage site. - - -def if_return_branch(flag: bool, s: str): - if flag: - x = s - return - # The assignment to x textually precedes this point, but the only - # path reaching here did not execute it. The flow engine should - # report x as fully Unbound. - reveal_type(x, expected_text="Unbound") # Error: x is unbound - - -def if_no_else(flag: bool, s: str): - if flag: - x = s - # x may or may not be bound depending on which branch was taken. - reveal_type(x, expected_text="str | Unbound") # Error: x is possibly unbound - - -def try_except_branch(flag: bool, s: str): - try: - x = s - if flag: - raise ValueError() - except ValueError: - # x was assigned before the raise, but the flow engine must - # account for the possibility that the assignment itself could - # have raised, leaving x unbound. - reveal_type(x, expected_text="Unbound | str") # Error: x is possibly unbound - - -def if_else_untyped_in_one_branch(flag: bool, s: str): - if flag: - x = s - else: - y = 1 - # x is assigned only in the True-branch; in the False-branch it is - # unbound. The declaration textually precedes usage so the position - # heuristic retains it, but the flow engine must still narrow to - # include Unbound. - reveal_type(x, expected_text="str | Unbound") # Error: x is possibly unbound diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow2.py b/packages/vipeye-internal/src/tests/samples/codeFlow2.py deleted file mode 100644 index e88fa224..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow2.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the case where a symbol that exists in -# an outer scope is redeclared within a class but is referenced -# within the class before it is declared. - -import stat - - -class FakeOsModule(object): - # The symbol "stat" is a module even though - # it is redeclared below in this scope as - # a method. - _stat_mode: int = stat.S_IFDIR - - def stat(self): - return None - - -def outer(): - a = 1 - - def inner(): - # This should generate an error - a += 1 - - inner() - return a diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow3.py b/packages/vipeye-internal/src/tests/samples/codeFlow3.py deleted file mode 100644 index 471ce1a2..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow3.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests the handling of a compound conditional statement -# where the first portion is statically determined to be false. - - -def func1(): - val = "" - if False and val: - pass diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow4.py b/packages/vipeye-internal/src/tests/samples/codeFlow4.py deleted file mode 100644 index aca416ff..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow4.py +++ /dev/null @@ -1,142 +0,0 @@ -# This sample tests the handling of if/elif chains that omit an else -# statement. The "implied else" statement should be assumed never taken if the -# final if/elif test expression evaluates to Never in the negative case. - -from enum import Enum -from typing import Literal - - -def func1(x: int | str): - if isinstance(x, int): - y = 0 - elif isinstance(x, str): - y = 1 - - print(y) - - -def func2(x: Literal[1, 2, 3, 4]): - if x == 1 or x == 2: - y = 0 - elif x == 3 or not x == 3: - y = 1 - - print(y) - - -def func3(x: Literal[1, 2], y: Literal["one", "two"]): - if x == 1 or y != "two": - z = 0 - elif x == 2 or y != "one": - z = 1 - - print(z) - - -class Color(Enum): - RED = 1 - BLUE = 2 - GREEN = 3 - PERIWINKLE = 4 - - -def func4(x: Color): - if x == Color.RED: - return - - if x == Color.GREEN or (x == Color.PERIWINKLE and True): - y = 2 - else: - if x == Color.BLUE: - y = 3 - - print(y) - - -def func5(): - if True: - y = 2 - - print(y) - - -def func6(): - if not None: - y = 2 - - print(y) - - -def func7(color: Color) -> str: - if color == Color.RED or color == Color.BLUE: - return "yes" - elif color == Color.GREEN or color == Color.PERIWINKLE: - return "no" - - -def func8(color: Color) -> bool: - if color == Color.RED or color == Color.BLUE: - return True - elif color == Color.GREEN or color == Color.PERIWINKLE: - return False - - -reveal_type(func8(Color.RED), expected_text="bool") - - -def func9(a: str | int, b: str | int) -> bool: - if isinstance(a, str): - return True - elif isinstance(a, int): - if isinstance(b, str): - return False - elif isinstance(b, int): - return False - - -def func10(foo: list[str]) -> bool: - i = 0 - x: int | None = None - - while i < 5: - foo[i] - - if x is None: - return False - reveal_type(x, expected_text="Never") - i = x - - return True - - -class A: - pass - - -class B(A): - pass - - -def func11(val: A | B): - if not (isinstance(val, A) or isinstance(val, B)): - raise Exception - - -reveal_type(func11(A()), expected_text="None") - - -def func12(val: A | B): - if isinstance(val, A) or isinstance(val, B): - raise Exception - - -reveal_type(func12(A()), expected_text="NoReturn") - - -def func13(val: int | float): - err_msg = "error!" - if isinstance(val, int): - return 1 - elif isinstance(val, float): - return 1.0 - raise ValueError(err_msg) diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow5.py b/packages/vipeye-internal/src/tests/samples/codeFlow5.py deleted file mode 100644 index 53e6be30..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow5.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample verifies that a builtin symbol that is used -# prior to being redefined in the same file isn't flagged -# as an error. - -int_ = int -int = 3 - - -max_ = max -max = lambda a, b: a if a > b else b diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow6.py b/packages/vipeye-internal/src/tests/samples/codeFlow6.py deleted file mode 100644 index 0e229af7..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow6.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests an interaction between a lambda, a function -# that is declared later in the source, and a function return type -# that uses code flow analysis for evaluation. - -from typing import Any, Callable, overload - - -class C: ... - - -@overload -def func1(v: Callable[[], int]) -> int: ... - - -@overload -def func1(v: Callable[[], list[C]]) -> list[C]: ... - - -def func1(v: Any) -> Any: ... - - -def func2(v: list[C]): ... - - -t = func1(lambda: func3()) -t.append(C()) - - -def func3() -> list[C]: ... diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow7.py b/packages/vipeye-internal/src/tests/samples/codeFlow7.py deleted file mode 100644 index 0e229af7..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow7.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests an interaction between a lambda, a function -# that is declared later in the source, and a function return type -# that uses code flow analysis for evaluation. - -from typing import Any, Callable, overload - - -class C: ... - - -@overload -def func1(v: Callable[[], int]) -> int: ... - - -@overload -def func1(v: Callable[[], list[C]]) -> list[C]: ... - - -def func1(v: Any) -> Any: ... - - -def func2(v: list[C]): ... - - -t = func1(lambda: func3()) -t.append(C()) - - -def func3() -> list[C]: ... diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow8.py b/packages/vipeye-internal/src/tests/samples/codeFlow8.py deleted file mode 100644 index 4364fcf7..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow8.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the case where an assignment expression -# is used within a looping construct such that the assigned -# value is initially unknown. - -# viper: strict - -from typing import Iterator - -for _ in ["1"]: - old_lines: Iterator[str] = iter(["2", "3"]) - - try: - while True: - line = next(old_lines) - count = 1 - if count: - while True: - if not (line := next(old_lines)): - pass - elif line.startswith(""): - print(line.removeprefix("")) - else: - old_lines = iter([line] + list(old_lines)) - break - - except StopIteration: - pass diff --git a/packages/vipeye-internal/src/tests/samples/codeFlow9.py b/packages/vipeye-internal/src/tests/samples/codeFlow9.py deleted file mode 100644 index 9ba49fae..00000000 --- a/packages/vipeye-internal/src/tests/samples/codeFlow9.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where a comprehension-scoped variable -# shadows a variable of the same name in an outer scope and is -# narrowed within the comprehension. - -def func1(m: list[str | int]) -> None: - print( - [ - reveal_type(value, expected_text="str") - for value in m - if isinstance(value, str) - ] - ) - - reveal_type(value, expected_text="() -> None") - value() - - -def value() -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/comparison1.py b/packages/vipeye-internal/src/tests/samples/comparison1.py deleted file mode 100644 index 20bc755d..00000000 --- a/packages/vipeye-internal/src/tests/samples/comparison1.py +++ /dev/null @@ -1,77 +0,0 @@ -# This sample tests the check for non-overlapping types compared -# with equals comparison. - -from typing import Literal, TypeVar - - -OS = Literal["Linux", "Darwin", "Windows"] - - -def func1(os: OS, val: Literal[1, "linux"]): - if os == "Linux": - return True - - # This should generate an error because this expression will always - # evaluate to False. - if os == "darwin": - return False - - # This should generate an error because this expression will always - # evaluate to True. - if os != val: - return False - - # This should generate an error because this expression will always - # evaluate to False. - if val == 2: - return False - - if val == 1: - return True - - -class ClassA: ... - - -class ClassB: ... - - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2", bound=ClassB) - - -def func2(a: ClassA, b: ClassB, c: _T1, d: _T2, e: ClassA | ClassB) -> None | _T1 | _T2: - # This should generate an error because there is no overlap in types. - if a == b: - return - - # This should generate an error because there is no overlap in types. - if a != b: - return - - if a != c: - return - - # This should generate an error because there is no overlap in types. - if a != d: - return - - if a == e: - return - - if b == e: - return - - -def func3(base: type) -> None: - if base == ClassA: - ... - - if ClassA == base: - ... - - -def func4(val: str | None): - # This should generate an error because there is no overlap in types. - if val == 42: - ... diff --git a/packages/vipeye-internal/src/tests/samples/comparison2.py b/packages/vipeye-internal/src/tests/samples/comparison2.py deleted file mode 100644 index 638eb91d..00000000 --- a/packages/vipeye-internal/src/tests/samples/comparison2.py +++ /dev/null @@ -1,158 +0,0 @@ -# This sample tests the reportUnnecessaryComparison diagnostic check -# when applied to functions that appear within a conditional expression. - - -from enum import Enum -from typing import Any, Callable, Coroutine, Protocol -from dataclasses import dataclass - - -def cond() -> bool: ... - - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -if cond: - pass - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -if 0 or cond: - pass - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -if 1 and cond: - pass - -if cond(): - pass -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -elif cond: - pass - - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -def func1(): - while cond: - pass - - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -a = [x for x in range(20) if cond] - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -a = 1 if cond else 2 - -b = "1" == "1" == "1" - -c = "" -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -if c is None: - pass - -# This should generate a diagnostic when reportUnnecessaryComparison is enabled. -if c is not None: - pass - - -def func2(d: str | Any): - if d is None: - pass - - -@dataclass -class DC1: - bar: str - - -def func3(x: DC1): - # This should generate an error if reportUnnecessaryComparison is enabled. - if x == 42: - ... - - -async def func4() -> bool: - return True - - -async def func5() -> None: - # This should generate an error if reportUnnecessaryComparison is enabled. - if func4(): - pass - - -def func6() -> Coroutine[Any, Any, int] | None: ... - - -def func7(): - coro = func6() - if coro: - pass - - -class A: ... - - -def func8(x: A): - # This should generate an error if reportUnnecessaryComparison is enabled. - if x is True: - pass - - # This should generate an error if reportUnnecessaryComparison is enabled. - if x is False: - pass - - # This should generate an error if reportUnnecessaryComparison is enabled. - if x is not True: - pass - - # This should generate an error if reportUnnecessaryComparison is enabled. - if x is not False: - pass - - -def func9(x: object, y: type[object]): - if x is y: - pass - - -def func10(x: object, y: type[object]): - if x is not y: - pass - - -class SupportsBool(Protocol): - def __bool__(self) -> Any: ... - - -def func11(a: A, b: SupportsBool, c: object): - # This should generate an error if reportUnnecessaryComparison is enabled. - if a is None: - pass - - # This should generate an error if reportUnnecessaryComparison is enabled. - if a is not None: - pass - - if b is None: - pass - - if c is None: - pass - - -def func12(a: object, b: Callable[..., int]) -> bool: - return a is b - - -class IntVal(int, Enum): - one = 1 - two = 2 - three = 3 - - -def func13(x: IntVal): - if x == 1: - pass - - # This should generate an error if reportUnnecessaryComparison is enabled. - if x == 4: - pass diff --git a/packages/vipeye-internal/src/tests/samples/complex1.py b/packages/vipeye-internal/src/tests/samples/complex1.py deleted file mode 100644 index 91d8762b..00000000 --- a/packages/vipeye-internal/src/tests/samples/complex1.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the type checker's handling of imaginary -# and complex numbers. - -a = 3.2j - -b = a + 4 - -c = 1.2 * a - - -def requires_complex(val: complex): ... - - -requires_complex(a) -requires_complex(b) -requires_complex(c) diff --git a/packages/vipeye-internal/src/tests/samples/comprehension1.py b/packages/vipeye-internal/src/tests/samples/comprehension1.py deleted file mode 100644 index a2b6601c..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension1.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests type checking for list comprehensions. - -from typing import Any, Generator, Iterable, Literal - -a = [1, 2, 3, 4] - - -def func1() -> Generator[int, None, None]: - b = (elem for elem in a) - return b - - -def func2() -> list[int]: - c = [elem for elem in a] - return c - - -def func3() -> list[str]: - c = [elem for elem in a] - - # This should generate an error because - # c is a List[int], which doesn't match - # the declared return type. - return c - -def func4(): - c = [(i for i in [1, 2, 3])] - reveal_type(c, expected_text="list[Generator[int, None, None]]") - - -def generate(): - for i in range(2): - yield i - - -# Verify that generate returns a Generator. -s = generate() -s.close() - -# Verify that literals are handled correctly. -FooOrBar = Literal["foo", "bar"] - - -def to_list(values: Iterable[FooOrBar]) -> list[FooOrBar]: - a = [value for value in values] - reveal_type(a, expected_text="list[str]") - - b: list[FooOrBar] = [value for value in values] - - c = list(value for value in values) - reveal_type(c, expected_text="list[str]") - - d: list[FooOrBar] = list(value for value in values) - - e = (value for value in values) - reveal_type(e, expected_text="Generator[str, None, None]") - - f: Generator[FooOrBar, Any, Any] = (value for value in values) - - return [value for value in values] - -x = 3 -# This should generate a syntax error. -[x for in range(3)] - diff --git a/packages/vipeye-internal/src/tests/samples/comprehension10.py b/packages/vipeye-internal/src/tests/samples/comprehension10.py deleted file mode 100644 index dc0c69ec..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension10.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests type checking for set comprehensions. - -from typing import Generator - -a = [1, 2, 3, 4] - - -def func1() -> Generator[int, None, None]: - b = (elem for elem in a) - return b - - -def func2() -> set[int]: - c = {elem for elem in a} - return c - - -def func3() -> set[str]: - c = {elem for elem in a} - - # This should generate an error because - # c is a Set[int], which doesn't match - # the declared return type. - return c - - -def generate(): - for i in range(2): - yield i - - -# Verify that generate returns a Generator. -s = generate() -s.close() diff --git a/packages/vipeye-internal/src/tests/samples/comprehension11.py b/packages/vipeye-internal/src/tests/samples/comprehension11.py deleted file mode 100644 index 9bc13b6b..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension11.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where bidirectional type inference is used -# in a nested manner with list comprehensions. - -# viper: strict - -from itertools import chain - -times = [ - (hour, minute, meridian) - for hour, minute, meridian in chain.from_iterable( - chain.from_iterable( - ((hour, minute, meridian) for minute in range(0, 60, 15)) - for hour in range(12) - ) - for meridian in ("am", "pm") - ) -] -reveal_type(times, expected_text="list[tuple[int, int, str]]") diff --git a/packages/vipeye-internal/src/tests/samples/comprehension2.py b/packages/vipeye-internal/src/tests/samples/comprehension2.py deleted file mode 100644 index 30c86758..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension2.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests interleaved for and if clauses in a list comprehension. - -# viper: strict, reportUnnecessaryComparison=false - -from typing import Union, List, Tuple - -m1: List[Union[Tuple[int, int], None]] = [] - -a = [ - y + z + x[0] - for x in m1 - if x is not None - for y in x - if y is not None - for z in [1, None, 3] - if z is not None -] diff --git a/packages/vipeye-internal/src/tests/samples/comprehension3.py b/packages/vipeye-internal/src/tests/samples/comprehension3.py deleted file mode 100644 index c265343c..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension3.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests type inference for list comprehensions, -# including list target expressions in for statements. - - -def foo() -> list[str]: - pairs = [s.split(":") if ":" in s else [s, "null"] for s in ["foo:bar", "baz"]] - foo = [p[0] for p in pairs] - if foo: - return foo - - bar = [a for [a, b] in pairs] - return bar diff --git a/packages/vipeye-internal/src/tests/samples/comprehension4.py b/packages/vipeye-internal/src/tests/samples/comprehension4.py deleted file mode 100644 index 013b9bb6..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension4.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests scoping rules for variables that are declared within -# a list comprehension statement. - -a: str = "hello" - -# The statement "len(a)" should not generate an -# error because "a" is not yet bound to the local -# variable at the time it is executed. Instead, it -# has the str type of the "a" in the outer scope. -b = [a for a in [len(a)]] - -# This assignment should succeed because "a" at this -# point should have the type of "a" in the outer scope, -# not the int type from the list comprehension. -c: str = a diff --git a/packages/vipeye-internal/src/tests/samples/comprehension5.py b/packages/vipeye-internal/src/tests/samples/comprehension5.py deleted file mode 100644 index 295002ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension5.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the type inference of list comprehensions -# that result in AsyncGenerator types. - -import asyncio - - -async def do_iter(): - for i in range(10): - yield i - await asyncio.sleep(0.1) - - -async def doit(): - as_list = (i + 1 async for i in do_iter()) - - async for i in as_list: - print(i) - - -asyncio.run(doit()) diff --git a/packages/vipeye-internal/src/tests/samples/comprehension6.py b/packages/vipeye-internal/src/tests/samples/comprehension6.py deleted file mode 100644 index 78fad2b9..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension6.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests parsing of list comprehensions with -# various syntax errors. - -# This should generate an error. -(*i for i in []) - -# This should generate an error. -[*i for i in []] - -# This should generate an error. -{*d for d in []} - -# This should generate an error. -{**d for d in []} diff --git a/packages/vipeye-internal/src/tests/samples/comprehension7.py b/packages/vipeye-internal/src/tests/samples/comprehension7.py deleted file mode 100644 index fe0543ac..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension7.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample validates that list comprehensions within a class -# body do not reference class-scoped variables within the -# comprehension unless they are within the initial iterator expression. - -outer_var = [1, 2] - - -class A: - var1 = [1, 2] - var2 = {x for x in var1} - - # This should generate an error. - var3 = {var1[0] for x in var1} - - var4 = {outer_var[0] for x in outer_var} diff --git a/packages/vipeye-internal/src/tests/samples/comprehension8.py b/packages/vipeye-internal/src/tests/samples/comprehension8.py deleted file mode 100644 index 471f3a06..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension8.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the evaluation of a list comprehension where -# there are interdependencies between some of the variables. - -# viper: strict - - -class ClassA: - input: str - output: str - - -def func1(a: ClassA, x: str): - a.output = x.join( - stripped for line in a.input.splitlines() if (stripped := line.strip()) - ) diff --git a/packages/vipeye-internal/src/tests/samples/comprehension9.py b/packages/vipeye-internal/src/tests/samples/comprehension9.py deleted file mode 100644 index 1a69a8bb..00000000 --- a/packages/vipeye-internal/src/tests/samples/comprehension9.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a comprehension requires bidirectional -# type inference for correct analysis. - -# viper: strict - -from typing import TypedDict - - -class X(TypedDict): - x: str - - -xs: list[X] = [] -xs.extend({"x": c} for c in "abc") - - -def func1(data: dict[str, int]): - sum(data.get(k, 0) for k in "") - - -def func2(data: dict[str, int]): - sum([data.get(k, 0) for k in ""]) diff --git a/packages/vipeye-internal/src/tests/samples/conditional1.py b/packages/vipeye-internal/src/tests/samples/conditional1.py deleted file mode 100644 index 49d17695..00000000 --- a/packages/vipeye-internal/src/tests/samples/conditional1.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests that the check that validates the operand type for -# a conditional statement. The operand must be of type bool or a type -# that has a __bool__ method that returns a bool. - -from typing import NoReturn, TypeVar - - -class ReturnsBool: - def __bool__(self) -> bool: - return True - - -class ReturnsNonBool: - def __bool__(self) -> NoReturn: - raise TypeError("Not a bool") - - -def func1(val: ReturnsNonBool): - # This should generate an error. - if val: - pass - - # This should generate an error. - a = not val - - b = val or 1 - # This should generate an error. - if b: - pass - - c = 1 and val - # This should generate an error. - if c: - pass - - # This should generate an error. - y = 1 if val else 2 - - # This should generate an error. - while val: - break - - # This should generate an error. - z = [1 for i in range(10) if val] - - -TVal = TypeVar("TVal", bound=ReturnsNonBool) - - -def func2(val: TVal | ReturnsBool) -> TVal | ReturnsBool: - # This should generate an error. - if val: - pass - - # This should generate an error. - a = not val - - b = val or 1 - # This should generate an error. - if b: - pass - - c = 1 and val - # This should generate an error. - if c: - pass - - # This should generate an error. - y = 1 if val else 2 - - # This should generate an error. - while val: - break - - # This should generate an error. - z = [1 for i in range(10) if val] - - return val - - -class Meta(type): - def __bool__(self) -> int: - return 1 - - -class MetaDerived(metaclass=Meta): - pass - - -def func3(val: type[MetaDerived]): - # This should generate an error. - if val: - pass diff --git a/packages/vipeye-internal/src/tests/samples/constant1.py b/packages/vipeye-internal/src/tests/samples/constant1.py deleted file mode 100644 index 2b74484f..00000000 --- a/packages/vipeye-internal/src/tests/samples/constant1.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the "reportConstantRedefinition" feature. - -ALL_CAPS_123_ = 234 -# This should generate an error if the feature is enabled. -ALL_CAPS_123_ = 233 - -_ = 234 -# This should not be considered a constant -_ = 234 - - -a = True - - -def foo(): - LOCALVAR = 3 - - if a: - # This should generate an error if the feature is enabled. - LOCALVAR = 23 - - -from typing import TYPE_CHECKING - -# This should generate an error if the feature is enabled. -TYPE_CHECKING = True - - -class Foo(object): - CONST_VAR = 3 - - # This should generate an error if the feature is enabled. - CONST_VAR = 4 - - def __init__(self): - self.HELLO = "3" - - def foo(self): - # This should generate an error if the feature is enabled. - self.HELLO = "324" diff --git a/packages/vipeye-internal/src/tests/samples/constants1.py b/packages/vipeye-internal/src/tests/samples/constants1.py deleted file mode 100644 index 440b1e5e..00000000 --- a/packages/vipeye-internal/src/tests/samples/constants1.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests that the type checker flags certain values -# that cannot be deleted or assigned to. - -# This should generate an error -True = 3 - -# This should generate an error -False = 4 - -# This should generate an error -None = True - -# This should generate an error -__debug__ = 4 - -# This should generate an error -del True - -# This should generate an error -del None - -# This should generate an error --3 = 2 - -# This should generate an error -[4] = [2] - -# This should generate an error -[True] = [3] - -# This should generate an error -(True) = 3 - -# This should generate an error -del -3 - -# This should generate an error -3 + 4 = 2 - -# This should generate an error -del 3 + 4 - -# This should generate an error -del -(4) - -# This should generate an error -del __debug__ - -# This should generate an error -del {} - -# This should generate an error -... = 3 - -# This should generate an error -del ... - -# This should generate an error -(...) = 3 - -# This should generate an error -del ... - - diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar1.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar1.py deleted file mode 100644 index bd21a03b..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar1.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests constraint solving constrained TypeVars. - -from typing import Generic, TypeVar - -S = TypeVar("S", str, bytes) - - -def constrained(first: S, second: S) -> S: - return first - - -# This should generate an error because the two arguments -# cannot satisfy the 'str' or 'bytes' constraint. -result = constrained("a", b"abc") - -U = TypeVar("U", float, str) - - -class ClassA(Generic[U]): - def generic_func1(self, a: U, b: str = "", **kwargs: U) -> U: - return a - - -a1 = ClassA[str]() -r1 = a1.generic_func1("hi") -reveal_type(r1, expected_text="str") -r2 = a1.generic_func1("hi", test="hi") -reveal_type(r2, expected_text="str") - -# This should generate an error. -r3 = a1.generic_func1("hi", test=3) -reveal_type(r3, expected_text="str") - -# This should generate an error. -r4 = a1.generic_func1("hi", 3) -reveal_type(r4, expected_text="str") - -a2: ClassA[int] - -# This should generate an error. -a3: ClassA[Never] - -ClassAAlias = ClassA[U] - -# This should generate an error. -a4: ClassAAlias[Never] diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar10.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar10.py deleted file mode 100644 index 9b069c20..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar10.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the handling of constrained type variables -# that include unions. - -from typing import TypeVar - -T1 = TypeVar("T1", int, str) -T2 = TypeVar("T2", int, str, int | str) -T3 = TypeVar("T3", int, str, int | str | list[int]) - - -def func1(x: T1) -> T1: - return x - - -def func2(x: T2) -> T2: - return x - - -def func3(x: T3) -> T3: - return x - - -def func4(y: int | str): - # This should generate an error because T1 doesn't - # include a union constraint. - func1(y) - - func2(y) - - func3(y) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar11.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar11.py deleted file mode 100644 index b8571757..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar11.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests for proper handling of constrained or bound TypeVars. - -from typing import Generic, TypeVar - - -class IntSubclass1(int): - pass - - -_T1 = TypeVar("_T1", int, IntSubclass1) - - -def add1(value: _T1) -> _T1: - reveal_type(value + 1, expected_text="int*") - - # This should generate an error - return value + 5 - - -class IntSubclass2(int): - def __add__(self, value: object) -> "IntSubclass2": ... - - -_T2 = TypeVar("_T2", int, IntSubclass2) - - -def add2(value: _T2) -> _T2: - reveal_type(value + 1, expected_text="int* | IntSubclass2*") - return value + 5 diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar12.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar12.py deleted file mode 100644 index 63653972..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar12.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a constrained TypeVar is assigned -# to another constrained TypeVar or a union that contains a constrained -# TypeVar. - -from os import PathLike -from typing import AnyStr - - -def func1(path: AnyStr | PathLike[AnyStr]) -> AnyStr: ... - - -def func2(value: AnyStr) -> AnyStr: - return func1(value) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar13.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar13.py deleted file mode 100644 index 32ebe2d0..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar13.py +++ /dev/null @@ -1,126 +0,0 @@ -# This sample tests the "constrained TypeVar narrowing for return types" -# feature. When a declared return type of a function contains a constrained -# TypeVar and the return statement is found on a path that tests a variable -# that is typed as that TypeVar, we know that the code path is taken only -# in the case where constraint is satisfied. - -from typing import AnyStr, Generic, ParamSpec, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -_T1 = TypeVar("_T1", str, int) -_T2 = TypeVar("_T2") - - -class A: ... - - -class B: ... - - -class C: ... - - -_T3 = TypeVar("_T3", A, B, C) - -_P = ParamSpec("_P") -_Ts = TypeVarTuple("_Ts") - - -def func1(val1: _T1) -> _T1: - if isinstance(val1, str): - return "" - return 0 - - -def func2(val1: _T1) -> list[_T1]: - if isinstance(val1, str): - return [""] - return [0] - - -class Class1(Generic[_T1, _T2, _T3, _P, Unpack[_Ts]]): - def meth1( - self, val1: _T1, val2: _T2, val3: _T3, cond: bool - ) -> list[_T1] | list[_T2] | list[_T3]: - if cond: - # This should generate an error. - return [0] - - if cond or 3 > 2: - if isinstance(val1, str): - # This should generate an error. - return [0] - else: - return [0] - - if cond or 3 > 2: - if isinstance(val3, B): - return [B()] - else: - # This should generate an error. - return [C()] - - if cond or 3 > 2: - if not isinstance(val3, B) and not isinstance(val3, C): - return [A()] - - return [val1] - - def meth2(self, val1: _T1) -> _T1: - val2 = val1 - - while True: - if isinstance(val2, str): - return "hi" - - val2 = val2 = val1 - - if isinstance(val2, int): - return 0 - - def meth3(self, val1: _T1, val2: _T3) -> _T1: - if isinstance(val2, A): - # This should generate an error. - return 1 - - if isinstance(val2, B): - if isinstance(val1, str): - return "" - - if isinstance(val1, int): - if isinstance(val2, B): - # This should generate an error. - return "" - - raise BaseException() - - -def func3(s: AnyStr, y: AnyStr | None = None) -> AnyStr: - if isinstance(s, str): - if y is None: - pass - return "" - else: - raise NotImplementedError - - -def func4(t: _T3) -> _T3: - match t: - case A(): - return A() - case B(): - return B() - case C(): - return C() - - -def func5(t: _T3) -> _T3: - if isinstance(t, A): - return A() - elif isinstance(t, B): - return B() - elif isinstance(t, C): - return C() diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar14.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar14.py deleted file mode 100644 index 53c74bc5..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar14.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample verifies that a generic class parameterized with a -# constrained TypeVar properly translates an explicit type argument -# into the correct constrained type. - -from typing import TypeVar, Generic - - -class A: ... - - -class B: ... - - -class A2(A): ... - - -T = TypeVar("T", A, B) - - -class F(Generic[T]): - def __init__(self, thing: T) -> None: - self.thing = thing - - -f2 = F[A2](A2()) - -reveal_type(F[A2], expected_text="type[F[A]]") -reveal_type(f2, expected_text="F[A]") -reveal_type(f2.thing, expected_text="A") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar15.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar15.py deleted file mode 100644 index be2691a1..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar15.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests the case where a constrained TypeVar is used -# as an argument for a constructor or function call. - -from typing import AnyStr, Iterable, TypeVar, Generic -from dataclasses import dataclass - - -class ClassA: ... - - -_T = TypeVar("_T", int | float, ClassA) - - -@dataclass -class Data(Generic[_T]): - data: _T - - -def func1(a: Data[_T]) -> _T: - if isinstance(a.data, (int, float)): - value = int(a.data / 3) - reveal_type(value, expected_text="int*") - else: - value = a.data - reveal_type(value, expected_text="ClassA*") - - return value - - -def func2(val: AnyStr, objs: Iterable[AnyStr]) -> AnyStr: - return val.join(objs) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar16.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar16.py deleted file mode 100644 index b4913a07..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar16.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the case where a TypeVar requires multiple passes -# to resolve and the first pass it is assigned to a max widened -# type that is a constrained TypeVar. - -# The code below is a simplified version of this code: -# import os -# result = filter(os.path.exists, ["hello", "world"]) - -from typing import Any, Callable, Iterable, Iterator, TypeVar -from functools import reduce - -_T1 = TypeVar("_T1") -AnyStr = TypeVar("AnyStr", str, bytes) - - -def exists2(path: AnyStr) -> bool: ... - - -def filter2(f: Callable[[_T1], Any], i: Iterable[_T1]) -> Iterator[_T1]: ... - - -result = filter2(exists2, ["hello", "world"]) - - -_T2 = TypeVar("_T2", set, frozenset) - - -def merge_sets(sets: Iterable[_T2]) -> _T2: - return reduce(lambda x, y: x.union(y), sets) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar17.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar17.py deleted file mode 100644 index 002f583b..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar17.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests the case where a constrained TypeVar -# is used in a protocol with a contravariant TypeVar. - -# This example is a stand-alone sample based on the following code. -# with open('read', 'rb') as fr, open('write', 'wb') as fw: -# shutil.copyfileobj(fr, fw) - -from typing import Any, AnyStr, Optional, Protocol, TypeVar, Union - - -class Array: ... - - -class MMap: ... - - -# Note that this union contains types that are not compatible -# with the type "bytes". -ReadableBuffer = Union[bytes, bytearray, memoryview, Array, MMap] - -_T_contra = TypeVar("_T_contra", contravariant=True) -_T_co = TypeVar("_T_co", covariant=True) - - -class BufferedWriter: - def write(self, __buffer: ReadableBuffer) -> int: ... - - -class SupportsWrite(Protocol[_T_contra]): - def write(self, __s: _T_contra) -> Any: ... - - -class SupportsRead(Protocol[_T_co]): - def read(self, __length: int = ...) -> _T_co: ... - - -class BufferedReader: - def read(self, __size: Optional[int] = ...) -> bytes: ... - - -def copyfileobj( - fsrc: SupportsRead[AnyStr], fdst: SupportsWrite[AnyStr], length: int = ... -) -> AnyStr: ... - - -def f(fr: BufferedReader, fw: BufferedWriter): - x = copyfileobj(fr, fw) - reveal_type(x, expected_text="bytes") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar18.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar18.py deleted file mode 100644 index 457df901..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar18.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the case where an inferred method return type is -# a union with subtypes that are conditioned on different constraints of -# a constrained TypeVar. When the method is bound, one or more of these -# subtypes should be eliminated. - -from typing import Generic, TypeVar, Awaitable - -T1 = TypeVar("T1") - - -class Async: - def fn(self, returnable: T1) -> Awaitable[T1]: ... - - -class Sync: - def fn(self, returnable: T1) -> T1: ... - - -T2 = TypeVar("T2", Async, Sync) - - -class A(Generic[T2]): - def __init__(self, client: T2): - self._client = client - - def method1(self): - return self._client.fn(7) - - -a1 = A(Async()) -r1 = a1.method1() -reveal_type(r1, expected_text="Awaitable[int]*") - -a2 = A(Sync()) -r2 = a2.method1() -reveal_type(r2, expected_text="int*") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar19.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar19.py deleted file mode 100644 index fa9bc4aa..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar19.py +++ /dev/null @@ -1,18 +0,0 @@ -# This tests the handling of a constrained TypeVar with literal types -# in the constraints. - -from typing import TypeVar, Literal, Generic - -T = TypeVar("T", Literal[True], Literal[False]) - - -class A(Generic[T]): - def __init__(self, null: T = False) -> None: - pass - - -A(null=bool()) # Type error - -reveal_type(A(null=False), expected_text="A[Literal[False]]") -reveal_type(A(), expected_text="A[Literal[False]]") -reveal_type(A(null=True), expected_text="A[Literal[True]]") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar2.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar2.py deleted file mode 100644 index 40c35e03..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar2.py +++ /dev/null @@ -1,103 +0,0 @@ -# This sample tests constraint solving for constrained type vars. - -import pathlib -import shutil -from typing import AnyStr, Type, TypeVar, Union - - -class Foo: - pass - - -class Bar(Foo): - pass - - -T1 = TypeVar("T1", Foo, str) -T2 = TypeVar("T2", bound=Foo) - - -def test1(x: T1) -> T1: - return x - - -def test2(x: T2) -> T2: - return x - - -# This should generate an error because test1(Bar()) -# should evaluate to type Foo, not Bar. -aa1: Bar = test1(Bar()) - -aa2: Foo = test1(Bar()) - -bb1: Bar = test2(Bar()) - -bb2: Foo = test2(Bar()) - - -# The call to rmtree should not generate any errors. -data_dir = pathlib.Path("/tmp") -archive_path = data_dir / "hello" -shutil.rmtree(archive_path) - - -def func1(a: AnyStr, b: AnyStr) -> None: ... - - -def func2(a: Union[str, bytes], b: Union[str, bytes]): - # This should generate two errors - func1(a, b) - - -class A: ... - - -class B: ... - - -class C: ... - - -class D: ... - - -T3 = TypeVar("T3", A, B, Union[C, D]) - - -def do_something(value: T3) -> T3: ... - - -def func10(value: Union[C, D]): - value1 = do_something(value) - - -def func11(value: D): - value1 = do_something(value) - - -def func12(value: Union[A, B]): - # This should generate an error because A and B - # map to different constraints. - value1 = do_something(value) - - -def func13(value: Union[A, D]): - # This should generate an error because A and D - # map to different constraints. - value1 = do_something(value) - - -T4 = TypeVar("T4", A, B, Union[C, D]) - - -def func14(cls: Type[T4]) -> T4: - instance1 = cls() - reveal_type(instance1, expected_text="T4@func14") # Unknown - return instance1 - - -def func15(cls: Union[Type[Union[A, B]], Type[Union[C, D]]]) -> Union[A, B, C, D]: - instance2 = cls() - reveal_type(instance2, expected_text="A | B | C | D") - return instance2 diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar20.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar20.py deleted file mode 100644 index c7e09635..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar20.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case involving nested calls that each use -# constrained TypeVars but one is a subset of the other. - -from os import PathLike -from typing import Any, AnyStr, Literal, LiteralString, TypeVar, overload - -AnyOrLiteralStr = TypeVar("AnyOrLiteralStr", str, bytes, LiteralString) - - -def abspath(path: PathLike[AnyStr] | AnyStr) -> AnyStr: ... - - -@overload -def dirname(p: PathLike[AnyStr]) -> AnyStr: ... - - -@overload -def dirname(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... - - -def dirname(p: Any) -> Any: ... - - -def func1(refpath: Literal["-"]): - reveal_type(dirname(abspath(refpath)), expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar3.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar3.py deleted file mode 100644 index 1f05f125..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar3.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the type checker's expansion of constrained -# TypeVars within a union type. - -from typing import Union, AnyStr, Sequence - - -def do_the_thing(param: Union[Sequence[AnyStr], AnyStr]) -> None: - if isinstance(param, str): - print(f"str: {param}") - return - - if isinstance(param, bytes): - print(f"bytes: {param!r}") - return - - print(f"list:") - for itm in param: - print(f" -> {itm}") - - -do_the_thing("a") -do_the_thing(b"b") -do_the_thing(["a", "b"]) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar4.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar4.py deleted file mode 100644 index 05f2ecd2..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar4.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests type narrowing of generic constrained types. - -from typing import AnyStr, Generic, Sequence, TypeVar - - -Command = AnyStr | Sequence[AnyStr] - - -def func1(cmd: Command) -> list[str]: - if isinstance(cmd, bytes): - return [str(cmd, "utf-8")] - if isinstance(cmd, str): - return [cmd] - - ret: list[str] = [] - for itm in cmd: - if isinstance(itm, str): - ret.append(itm) - else: - ret.append(str(itm, "utf-8")) - return ret - - -T = TypeVar("T", str, int, float, bool) - - -class Item(Generic[T]): - value: T | None - - def __init__(self, source: T | None) -> None: - self.value = source - - def read(self) -> T | None: - if self.value is None: - raise RuntimeError(f"Item is required!") - - return self.value diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar5.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar5.py deleted file mode 100644 index ef1a3cc2..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar5.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the handling of generic type aliases -# with constrained types. - -from typing import Callable, Generic, TypeVar - -T = TypeVar("T", str, bool, None) - - -class MyData(Generic[T]): - def __init__(self, val: T): - self.val = val - - -Op = Callable[[MyData[T]], T] - - -def f_generic1(val: T, op: Op[T]) -> T: - obj = MyData[T](val) - return op(obj) - - -def f_generic2(val: T, op: Op[T]) -> T: - obj = MyData(val) - return op(obj) - - -def f_bool(val: bool) -> bool: - op: Op[bool] = lambda od: od.val - r = f_generic1(val, op) - return r - - -def f_generic3(val: T) -> T: - return val - - -def f_union(val: bool | str) -> None: - # This should generate an error because a - # union cannot be assigned to a constrained - # type variable. - f_generic3(val) - - if isinstance(val, bool): - f_generic3(val) - else: - f_generic3(val) - - -def func1(v: T, t: type[T]): - print(t) - - -def func2(v: T, t: type[T]): - func1(v, t) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar6.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar6.py deleted file mode 100644 index 1a0421ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar6.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the handling of constrained types -# when one of the constraints is a narrower version -# of another. The order of the constraints as they appear -# within the TypeVar definition shouldn't matter. - -from typing import TypeVar - -_T1 = TypeVar("_T1", float, str) - - -def add1(a: _T1, b: _T1) -> _T1: - return a + b - - -a1 = add1(3, 5.5) -reveal_type(a1, expected_text="float") -b1 = add1(3.3, 5) -reveal_type(b1, expected_text="float") -c1 = add1("3", "5") -reveal_type(c1, expected_text="str") - - -_T2 = TypeVar("_T2", float, int) - - -def add2(a: _T2, b: _T2) -> _T2: - return a + b - - -a2 = add2(3, 5.5) -reveal_type(a2, expected_text="float") -b2 = add2(3.3, 5) -reveal_type(b2, expected_text="float") -c2 = add2(3, 5) -reveal_type(c2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar7.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar7.py deleted file mode 100644 index 3537785c..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar7.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests the assignment of constrained TypeVars to a union -# that allows for all of the types in the constraint. - -from typing import Iterator, Optional, Sequence, TypeVar, Union - - -def func0(a: Union[int, float]): ... - - -_T1 = TypeVar("_T1", int, float) - - -def func1(a: _T1, b: _T1): - return func0(a) - - -_T2 = TypeVar("_T2", int, float, complex) - - -def func2(a: _T2, b: _T2): - # This should generate an error. - return func0(a) - - -_T3 = TypeVar("_T3", int, float) - - -def func3(xs: Sequence[Optional[_T3]]) -> Iterator[_T3]: - return (x for x in xs if x is not None) - - -def func4(xs: Sequence[Optional[_T3]]) -> Iterator[_T3]: - return func3(xs) - - -def func5(xs: Sequence[Optional[_T2]]) -> Iterator[_T2]: - # This should generate an error. - return func3(xs) - - -class A: ... - - -class B(A): ... - - -_T4 = TypeVar("_T4", A, B) -_T5 = TypeVar("_T5", B, A) - - -def func6(t: type[_T4]) -> type[_T4]: - return t - - -def func7(t: type[_T5]) -> type[_T5]: - return t - - -val6 = func6(B) -val7 = func7(B) - -reveal_type(val6, expected_text="type[B]") -reveal_type(val7, expected_text="type[B]") diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar8.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar8.py deleted file mode 100644 index 0eb0d43e..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar8.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the handling of a constrained TypeVar used with -# a Type[T] annotation. - -from typing import TypeVar, Any - - -class A: - def __init__(self, x: Any) -> None: - pass - - def f(self) -> None: - pass - - -T = TypeVar("T", str, int, A) - - -def factory(desired_type: type[T]) -> T: - return desired_type(1) - - -factory(str) -reveal_type(factory(str), expected_text="str") - -factory(int) -reveal_type(factory(int), expected_text="int") - -factory(A).f() -reveal_type(factory(A), expected_text="A") - -# This should generate an error -factory(float) diff --git a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar9.py b/packages/vipeye-internal/src/tests/samples/constrainedTypeVar9.py deleted file mode 100644 index 3f92ae7f..00000000 --- a/packages/vipeye-internal/src/tests/samples/constrainedTypeVar9.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a constrained type variable -# includes a Literal[False] and Literal[True]. - -from typing import TypeVar, Generic, Literal - -XOrY = TypeVar("XOrY", Literal[True], Literal[False]) - - -class A(Generic[XOrY]): - pass - - -class B(Generic[XOrY]): - def __init__(self, a: A[XOrY]): - self.a = a diff --git a/packages/vipeye-internal/src/tests/samples/constructor1.py b/packages/vipeye-internal/src/tests/samples/constructor1.py deleted file mode 100644 index 0fda3e90..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor1.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the handling of a constructor for a generic -# class where the type arguments need to be inferred using -# bidirectional type inference and the expected type is a -# union of other types. - -from typing import Generic, TypeVar, Final - -T = TypeVar("T") -S = TypeVar("S") - - -class A(Generic[T]): - def __init__(self, value: T) -> None: - self._value: Final = value - - -class B(Generic[S]): - def __init__(self, value: S) -> None: - self._value: Final = value - - -Result = A[T] | B[S] - - -def return_ok_none() -> Result[int | None, Exception]: - return A(None) - - -def return_ok_one() -> Result[int | None, Exception]: - return A(1) - - -class C(Generic[T]): - pass - - -c1: C[bool] | None = C() -reveal_type(c1, expected_type="C[bool]") - -c2: A[int] | C[int] = C() -reveal_type(c2, expected_type="C[int]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor10.py b/packages/vipeye-internal/src/tests/samples/constructor10.py deleted file mode 100644 index e3df1abc..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor10.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the handling of a __new__ method that -# is part of a generic class but uses its own type parameters. - - -from typing import Generic, Iterable, Iterator, TypeVar - - -_T_co = TypeVar("_T_co", covariant=True) -_T = TypeVar("_T") - - -class A(Iterator[_T_co]): - def __new__(cls, __iterable: Iterable[_T]) -> "A[tuple[_T, _T]]": ... - - def __next__(self) -> _T_co: ... - - -def func1(iterable: Iterable[_T]) -> Iterator[tuple[_T, _T, _T]]: - for (a, _), (b, c) in A(A(iterable)): - yield a, b, c - - -class B(Generic[_T_co]): - def __new__(cls, __iter1: Iterable[_T]) -> "B[_T]": ... - - -def func2(p1: list[dict]): - v1 = B(p1) - reveal_type(v1, expected_text="B[dict[Unknown, Unknown]]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor11.py b/packages/vipeye-internal/src/tests/samples/constructor11.py deleted file mode 100644 index eb9a4060..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor11.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the case where a subclass of Dict uses -# a dictionary literal as an argument to the constructor call. - -from collections import Counter, defaultdict -from typing import Callable, Generic, Mapping, Optional, TypeVar - -c1 = Counter({0, 1}) -reveal_type(c1, expected_text="Counter[int]") - -for i in range(256): - c1 = Counter({0: c1[1]}) - reveal_type(c1, expected_text="Counter[int]") - -reveal_type(c1, expected_text="Counter[int]") - - -K = TypeVar("K") -V = TypeVar("V") - -MyFuncType = Callable[[Callable[[K], V]], V] - - -class MyFunc(Generic[K, V]): - def __init__(self, g: MyFuncType[K, V]) -> None: - self.g = g - - -MyFuncMapping = Mapping[K, Optional[MyFunc[K, V]]] - -my_func_defaultdict: MyFuncMapping[str, int] = defaultdict( - lambda: None, {"x": MyFunc(lambda f: f("a"))} -) diff --git a/packages/vipeye-internal/src/tests/samples/constructor12.py b/packages/vipeye-internal/src/tests/samples/constructor12.py deleted file mode 100644 index cab755cc..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor12.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a specialized class is constructed -# from within the class implementation and uses a class TypeVar in -# the specialization. - -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class ClassA(Generic[T]): - def return_from_variable(self) -> "ClassA[T]": - value = ClassA[T]() - reveal_type(value, expected_text="ClassA[T@ClassA]") - return value - - -x = ClassA[int]() -v1 = x.return_from_variable() - -reveal_type(v1, expected_text="ClassA[int]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor13.py b/packages/vipeye-internal/src/tests/samples/constructor13.py deleted file mode 100644 index 85fbd8c1..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor13.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a generic type Type[T] is -# instantiated. - -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class Foo(Generic[T]): - def __init__(self) -> None: - val = self.method1() - reveal_type(val(), expected_text="T@Foo") - - # This should generate an error. - val(1) - - def method1(self) -> type[T]: ... diff --git a/packages/vipeye-internal/src/tests/samples/constructor14.py b/packages/vipeye-internal/src/tests/samples/constructor14.py deleted file mode 100644 index bea76b5d..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor14.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case where a constructor call is evaluated -# using bidirectional type inference in the case where the expected -# type is `Self`. - -# viper: strict - -from __future__ import annotations - -from typing import Any, Generic, Protocol, TypeVar -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] - -T_contra = TypeVar("T_contra", contravariant=True) -ThingT = TypeVar("ThingT", bound="Thing[Any]") - - -class Callback(Protocol[T_contra]): - def __call__(self, message: T_contra, /) -> Any: ... - - -class Thing(Generic[T_contra]): - def __init__(self, callback: Callback[T_contra]) -> None: - self._callback: Callback[T_contra] = callback - - def copy(self) -> Self: - return type(self)(self._callback) diff --git a/packages/vipeye-internal/src/tests/samples/constructor15.py b/packages/vipeye-internal/src/tests/samples/constructor15.py deleted file mode 100644 index 08ac7ed2..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor15.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the case where a constructor for a generic -# class is called with an inference context (i.e. using bidirectional -# type inference) and literals are used as type arguments. - -from typing import Any, Generic, Literal, Self, TypeVar - -_N = TypeVar("_N") -_M = TypeVar("_M") - - -class A(Generic[_M, _N]): - def __new__(cls, m: _M, n: _N) -> "A[_M, _N]": ... - - -a: A[Literal[3], Literal[4]] = A(3, 4) - - -class B(Generic[_M, _N]): - def __new__(cls, m: _M, n: _N) -> "B[_M, _N]": ... - - def __init__(self, *args: Any, **kwargs: Any) -> None: ... - - -b: B[Literal[3], Literal[4]] = B(3, 4) - - -class C(Generic[_M, _N]): - def __new__(cls, m: _M, n: _N) -> "C[_M, _N]": ... - - def __init__(self, m: _M, n: _N) -> None: ... - - -c: C[Literal[3], Literal[4]] = C(3, 4) - - -class D(Generic[_M, _N]): - def __new__(cls, m: _M, n: _N) -> Self: ... - - -d: D[Literal[3], Literal[4]] = D(3, 4) diff --git a/packages/vipeye-internal/src/tests/samples/constructor16.py b/packages/vipeye-internal/src/tests/samples/constructor16.py deleted file mode 100644 index 32e24df3..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor16.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests the case where a class defines a __new__ method -# that returns a class other than the owning class. - - -class A: - def __init__(self) -> None: - pass - - -class B(A): - def __new__(cls) -> A: - return A() - - def __init__(self, a: int) -> None: - pass - - -class C(B): - def __init__(self, a: int) -> None: - pass - - -B() - -# This should generate an error because B.__init__ is never called. -B(1) - -C() - -# This should generate an error because C.__init__ is never called. -C(1) diff --git a/packages/vipeye-internal/src/tests/samples/constructor17.py b/packages/vipeye-internal/src/tests/samples/constructor17.py deleted file mode 100644 index 4970521c..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor17.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the case where a generic class constructor doesn't -# allow for the solving of a class-scoped type variable. In this case, -# the type argument should be Unknown. - -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class A(Generic[T]): - def __new__(cls, *args, **kwargs): - return super().__new__(cls, *args, **kwargs) - - -class B(Generic[T]): - def __init__(self): ... - - -class C(Generic[T]): - def __new__(cls, *args, **kwargs): - return super().__new__(cls, *args, **kwargs) - - def __init__(self): ... - - -class D(Generic[T]): - def __new__(cls, *args, **kwargs): - return super().__new__(cls, *args, **kwargs) - - def __init__(self, a: T): ... - - -class E(Generic[T]): - pass - - -a = A(1) -reveal_type(a, expected_text="A[Unknown]") - -b = B() -reveal_type(b, expected_text="B[Unknown]") - -c = C() -reveal_type(c, expected_text="C[Unknown]") - -d = D(1) -reveal_type(d, expected_text="D[int]") - -e = E() -reveal_type(e, expected_text="E[Unknown]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor18.py b/packages/vipeye-internal/src/tests/samples/constructor18.py deleted file mode 100644 index d45c95f4..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor18.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests the case where a generic class contains a -# __new__ method that returns a Self type and an __init__ method -# that provides specialization for the Self type. When evaluating -# the __new__ method, we don't want to specialize the Self type -# too early. - -from dataclasses import dataclass -from typing import Generic, Self, TypeVar, overload - - -_ = isinstance(dict(a=0), dict) - - -class ClassA: ... - - -_T1 = TypeVar("_T1", bound=ClassA | str, covariant=True) -_T2 = TypeVar("_T2") - - -class ClassB(Generic[_T1]): - def __new__(cls, *args, **kwargs) -> Self: - return super().__new__(cls, *args, **kwargs) - - @overload - def __init__(self, arg: _T1) -> None: ... - - @overload - def __init__(self: "ClassB[str]", arg: int) -> None: ... - - def __init__(self, arg: int | ClassA | str) -> None: - pass - - -b1: ClassB[ClassA | str] = ClassB[str](32) - - -@dataclass -class ClassC(Generic[_T2]): - value: _T2 - - -c1: ClassC[int] | ClassC[str] = ClassC("hi") -c2: ClassC[int] | ClassC[str] = ClassC(1) diff --git a/packages/vipeye-internal/src/tests/samples/constructor19.py b/packages/vipeye-internal/src/tests/samples/constructor19.py deleted file mode 100644 index 7a93b989..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor19.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample handles the case where a class doesn't define its own -# constructor and relies on the `object` class constructor, which accepts -# no parameters. - - -class A: - pass - - -a1 = A() - -# This should generate an error -a2 = A(1) - -a3 = A(*[], **{}) diff --git a/packages/vipeye-internal/src/tests/samples/constructor2.py b/packages/vipeye-internal/src/tests/samples/constructor2.py deleted file mode 100644 index b4a8bb09..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor2.py +++ /dev/null @@ -1,184 +0,0 @@ -# This sample tests bidirectional type inference when the RHS -# is a call to a constructor. - -from typing import ( - Any, - Generic, - Iterable, - Literal, - Mapping, - Protocol, - Self, - TypeVar, -) - - -_T1 = TypeVar("_T1") -_T1_contra = TypeVar("_T1_contra", contravariant=True) -_T2 = TypeVar("_T2") -_T3 = TypeVar("_T3") - - -class Animal(Generic[_T1, _T2]): - pass - - -class Bear(Animal[_T3, int]): - def __init__(self, p1: _T3 | None = None): - pass - - -class Donkey(Animal[int, int], Generic[_T3]): - pass - - -class Flyer(Protocol[_T1_contra]): - def get_wingspan(self, p1: _T1_contra) -> float: - raise NotImplemented - - -class CaveDweller(Generic[_T1]): - pass - - -class Bat(Animal[int, int], CaveDweller[int]): - def get_wingspan(self, p1: int) -> float: - raise NotImplemented - - -def s1(): - b: Bear[str] = Bear() - a: Animal[str, int] = b - reveal_type(a, expected_text="Bear[str]") - - -def s2(): - a: Animal[str, int] = Bear() - reveal_type(a, expected_text="Bear[str]") - - -def s3(): - a: Animal[str, int] = Bear() - reveal_type(a, expected_text="Bear[str]") - - -def s4(): - a: Bear[Any] = Bear[int]() - reveal_type(a, expected_text="Bear[Any]") - - -def s5(): - a: Animal[Any, Any] = Bear[int]() - reveal_type(a, expected_text="Bear[int]") - - -def s6(): - a: Bat | Bear[str] = Bear() - reveal_type(a, expected_text="Bear[str]") - - -def s7(p: Bat | Bear[int]): - a: Animal[int, int] = p - reveal_type(a, expected_text="Bat | Bear[int]") - - -def s8(): - a: Animal[int, int] = Bear[int]() - reveal_type(a, expected_text="Bear[int]") - - -def s9(p: dict[str, str]): - a: dict[str, Any] = p - reveal_type(a, expected_text="dict[str, Any]") - - -def s10(p: list[str]): - a: Iterable[Any] = p - reveal_type(a, expected_text="list[str]") - b: Iterable[str] = [] - reveal_type(b, expected_text="list[str]") - c: Iterable[str] = list() - reveal_type(c, expected_text="list[str]") - - -def s11(): - a: Animal[Any, Any] = Donkey[int]() - reveal_type(a, expected_text="Donkey[int]") - - -def s12(p: Bear[_T1], b: _T1): - a: Animal[Any, int] = p - reveal_type(a, expected_text="Bear[_T1@s12]") - - -def s13(p: Bat): - a: Flyer[int] = p - reveal_type(a, expected_text="Bat") - - -def s14(p: Bat): - a: CaveDweller[int] = p - reveal_type(a, expected_text="Bat") - - -def s15(): - a = Bear(1) - reveal_type(a, expected_text="Bear[int]") - b = Bear[int](1) - reveal_type(b, expected_text="Bear[int]") - c = Bear[float](1) - reveal_type(c, expected_text="Bear[float]") - d = Bear[str | int](1) - reveal_type(d, expected_text="Bear[str | int]") - - -def s16(): - a: Any = Bear(1) - reveal_type(a, expected_text="Any") - - -def s17(): - a1: Iterable[object] = [2, 3, 4] - reveal_type(a1, expected_text="list[int]") - - a2: list[object] = [2, 3, 4] - reveal_type(a2, expected_text="list[object]") - - b1: Iterable[float] = [2, 3, 4] - reveal_type(b1, expected_text="list[int]") - - b2: list[float] = [2, 3, 4] - reveal_type(b2, expected_text="list[float]") - - c1: Iterable[Literal["A", "B", "C"]] = ["A", "B"] - reveal_type(c1, expected_text="list[Literal['A', 'B']]") - - c2: list[Literal["A", "B", "C"]] = ["A", "B"] - reveal_type(c2, expected_text="list[Literal['A', 'B', 'C']]") - - -def s18(): - a1: Mapping[object, object] = {"a": 3, "b": 5.6} - reveal_type(a1, expected_text="dict[object, int | float]") - - a2: dict[object, object] = {"a": 3, "b": 5.6} - reveal_type(a2, expected_text="dict[object, object]") - - b1: Mapping[str, float] = {"a": 3, "b": 5} - reveal_type(b1, expected_text="dict[str, int]") - - b2: dict[str, float] = {"a": 3, "b": 5} - reveal_type(b2, expected_text="dict[str, float]") - - c1: Mapping[Literal["A", "B"], Literal[3, 4]] = {"A": 3} - reveal_type(c1, expected_text="dict[Literal['A', 'B'], Literal[3]]") - - c2: dict[Literal["A", "B"], Literal[3, 4]] = {"A": 3} - reveal_type(c2, expected_text="dict[Literal['A', 'B'], Literal[3, 4]]") - - -class Plant(Generic[_T1]): - def __new__(cls, o: _T1) -> Self: ... - - -plant: Plant[float] = Plant(0) diff --git a/packages/vipeye-internal/src/tests/samples/constructor20.py b/packages/vipeye-internal/src/tests/samples/constructor20.py deleted file mode 100644 index c1d5f65c..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor20.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the specialization of constructors based on -# the expected type specified through either an assignment to -# an annotated variable or by a call where the parameter is -# annotated. - -from typing import Generic, TypeVar - -T = TypeVar("T", int, str) - - -class Adder(Generic[T]): - def add(self, a: T, b: T) -> T: - return a + b - - -int_adder: Adder[int] = Adder() -int_adder.add(1, 2) - -# This should be an error because "adder" -# should be of type Adder[int]. -int_adder.add("1", 2) - - -def requires_str_adder(str_adder: Adder[str]): - return str_adder - - -a = requires_str_adder(Adder()) -print(a.add("1", "2")) - -# This should be an error because the result -# of the call should be an Adder[str] -print(a.add(1, "2")) - - -generic_adder = Adder() -generic_adder.add(1, 2) -generic_adder.add("a", "b") - -# Since the type has an Unknown type argument, -# the following should not generate an error. -generic_adder.add(1, "b") diff --git a/packages/vipeye-internal/src/tests/samples/constructor21.py b/packages/vipeye-internal/src/tests/samples/constructor21.py deleted file mode 100644 index ebe6449d..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor21.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the instantiation of classes via a constructor -# when the type of the class is a TypeVar. - -from typing import TypeVar - - -class ClassA: - def __init__(self, a: int, b: str): - pass - - -T_A = TypeVar("T_A", bound=ClassA) - - -def func1(cls: type[T_A]) -> T_A: - # This should generate an error. - y = cls() - - x = cls(1, "") - reveal_type(x, expected_text="T_A@func1") - return x - - -_T = TypeVar("_T") - - -def func2(cls: type[_T]) -> _T: - # This should generate an error. - y = cls(1, "") - - x = cls() - reveal_type(x, expected_text="_T@func2") - return x diff --git a/packages/vipeye-internal/src/tests/samples/constructor22.py b/packages/vipeye-internal/src/tests/samples/constructor22.py deleted file mode 100644 index ea4b433a..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor22.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the case where a method within a generic class -# constructs an instance of the same type using a type variable -# within that class. - -from typing import Generic, Protocol, Tuple, TypeVar - - -T = TypeVar("T", covariant=True) - - -class A(Protocol[T]): - def a(self) -> "A[Tuple[T]]": ... - - def b(self) -> "A[Tuple[T]]": ... - - def c(self) -> "T": ... - - -class B(Generic[T]): - def __init__(self, t: T): - self._t = t - - def a(self) -> A[Tuple[T]]: - t = (self._t,) - y = B(t) - v = f(y.b()) - reveal_type(v, expected_text="tuple[T@B]") - return y - - def b(self) -> A[Tuple[T]]: - x = (self._t,) - reveal_type(x, expected_text="tuple[T@B]") - y = B(x) - reveal_type(y, expected_text="B[tuple[T@B]]") - return y - - def c(self) -> T: - return self._t - - -def f(a: A[Tuple[T]]) -> T: - return a.c()[0] diff --git a/packages/vipeye-internal/src/tests/samples/constructor23.py b/packages/vipeye-internal/src/tests/samples/constructor23.py deleted file mode 100644 index 768d7577..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor23.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests the case where a generic class has a constructor that -# supplies the type arguments via a callable which is itself generic. - - -from typing import Callable, Generic, Sequence, TypeVar - -T = TypeVar("T") -V = TypeVar("V", bound=object) -V_co = TypeVar("V_co", covariant=True) -U = TypeVar("U", bound=object) - - -class Result(Generic[V]): - pass - - -ParseFn = Callable[[Sequence[T], int, int], Result[V]] - - -class Parser(Generic[T, V_co]): - def fmap1(self, fn: Callable[[V_co], U]) -> "Parser[T, U]": - def fmap2(stream: Sequence[T], pos: int, bt: int) -> Result[U]: - raise NotImplementedError() - - reveal_type(FnParser(fmap2), expected_text="FnParser[T@Parser, U@fmap1]") - return FnParser(fmap2) - - -class FnParser(Parser[T, V_co]): - def __init__(self, fn: ParseFn[T, V_co]): - self._fn = fn diff --git a/packages/vipeye-internal/src/tests/samples/constructor24.py b/packages/vipeye-internal/src/tests/samples/constructor24.py deleted file mode 100644 index e544189c..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor24.py +++ /dev/null @@ -1,88 +0,0 @@ -# This sample tests the case where a generic class uses a default argument -# for a generic type parameter in its constructor. - -from typing import Callable, Generic, List, TypeVar - - -T = TypeVar("T") -U = TypeVar("U") - - -class Box(Generic[T]): - def __init__(self, value: T = 123): - self.value = value - - -x1 = Box[str | int]() -x2 = Box[float]() -x3 = Box[str]("hi") - -# This should generate an error because "hi" isn't compatible -# with float. -x4 = Box[float]("hi") - - -# This should generate an error because the default value of 123 -# isn't compatible with str. -y = Box[str]() - - -class Container(Generic[T]): - def __init__(self, value: T = None): - self.value = value - - @classmethod - def create(cls) -> "Container[T]": - # This should generate an error if strictParameterNoneValue - # is true because Container[T] being constructed is different - # from the current Container[T]. - return Container[T]() - - def on_next(self, value: T): - pass - - -class IntContainer(Container[int]): - def increment(self): - # This should generate an error if strictParameterNoneValue is false. - self.value += 1 - - -class ContainerList(Generic[U]): - def __init__(self) -> None: - self.containers: List[Container[U]] = [] - - def method1(self, a: U): - Container[U](a) - Container() - Container(123) - - # This should generate an error if strictParameterNoneValue is true. - Container[U]() - - # This should generate an error if strictParameterNoneValue is true. - Container[U](None) - - def method2(self): - Container[U].create() - - -def func1(obv: Container[T], default_value: T = None) -> None: - # This should generate an error if strictParameterNoneValue is false. - obv.on_next(default_value) - - -class A: ... - - -T_A = TypeVar("T_A", bound=A) - - -class B(Generic[T]): - def __init__(self, c: Callable[[], T]): ... - - -def func2(cls: type[T_A] = A) -> Callable[[], T_A]: ... - - -B(func2()) diff --git a/packages/vipeye-internal/src/tests/samples/constructor25.py b/packages/vipeye-internal/src/tests/samples/constructor25.py deleted file mode 100644 index be9c2ecd..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor25.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the handling of a generic class whose implementation -# allocates an instance of itself by invoking a constructor and passing -# an argument that is a generic type. - -# viper: strict - -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class A(Generic[T]): - def __init__(self, x: T): - self.x = x - - def method1(self) -> "A[T]": - x = self.x - reveal_type(x, expected_text="T@A") - t = (x,) - reveal_type(t, expected_text="tuple[T@A]") - a = A(t[0]) - reveal_type(a, expected_text="A[T@A]") - return a - - -class B(Generic[T]): - def __init__(self, thing: T): - pass - - @staticmethod - def method1(val: T) -> "B[T]": - # This should generate an error. - return B(0) - - -class C(Generic[T]): - def method1(self) -> "C[T]": - return C[T]() - - -c1 = C[int]() -reveal_type(c1, expected_text="C[int]") - -c2 = c1.method1() -reveal_type(c2, expected_text="C[int]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor26.py b/packages/vipeye-internal/src/tests/samples/constructor26.py deleted file mode 100644 index fd32878f..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor26.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests the case where a generic class with multiple -# type parameters invokes its own constructor and uses its own -# type parameters to specialize the constructed type. - -from typing import Generic, TypeVar - -T = TypeVar("T") -U = TypeVar("U") - - -class Test1(Generic[T, U]): - def __init__(self, t: T, u: U): - pass - - def test1(self, ts: list[T], us: list[U]) -> None: - # This should generate an error. - x1: Test1[U, T] = Test1(us, ts) - - x2: Test1[list[U], list[T]] = Test1(us, ts) - - -class Test2(Generic[T, U]): - def __init__(self): - pass - - def test2(self) -> None: - x1: Test2[U, T] - x2: Test2[T, T] - x3: Test2[T, U] - - x1 = Test2[U, T]() - # This should generate an error. - x2 = Test2[U, T]() - # This should generate an error. - x3 = Test2[U, T]() - - # This should generate an error. - x1 = Test2[T, T]() - x2 = Test2[T, T]() - # This should generate an error. - x3 = Test2[T, T]() - - # This should generate an error. - x1 = Test2[T, U]() - # This should generate an error. - x2 = Test2[T, U]() - x3 = Test2[T, U]() - - -class Test3(Generic[T, U]): - def __init__(self, ts: list[T], us: list[U]): - pass - - def test3(self, ts: list[T], us: list[U]) -> None: - x1: Test3[U, T] = Test3(us, ts) - - # This should generate two errors. - x2: Test3[list[U], list[T]] = Test3(us, ts) diff --git a/packages/vipeye-internal/src/tests/samples/constructor27.py b/packages/vipeye-internal/src/tests/samples/constructor27.py deleted file mode 100644 index b34f9d27..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor27.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests a case where a __new__ method in a generic class -# returns an instance of the class but with different type arguments -# than expected. This is arguably an error case, but pyright needs -# to handle it gracefully. - -from __future__ import annotations -from typing import Generic, TypeVar - - -T = TypeVar("T", contravariant=True) -S = TypeVar("S", contravariant=True) - - -class ClassA(Generic[T]): ... - - -class ClassB(Generic[S, T], ClassA[T]): ... - - -class ClassC(ClassB[S, T]): - def __new__(cls, subcon: ClassA[S]) -> ClassC[S, list[S]]: ... - - -class ClassD(ClassB[S, T]): - def __new__(cls, subcon: ClassA[S]) -> ClassD[S, list[S]]: ... - - -c = ClassA[int]() - -intermediate = ClassC(c) -v1 = ClassD(intermediate) -reveal_type(v1, expected_text="ClassD[list[int], list[list[int]]]") - -v2 = ClassD(ClassC(c)) -reveal_type(v2, expected_text="ClassD[list[int], list[list[int]]]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor28.py b/packages/vipeye-internal/src/tests/samples/constructor28.py deleted file mode 100644 index 8cd8dde0..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor28.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the case where a constructor for a class is invoked -# multiple times as separate arguments for a call. - -# viper: strict - -from __future__ import annotations -from typing import Any, Callable, Generic, Iterable, TypeVar, overload - -T = TypeVar("T") -S = TypeVar("S", covariant=True) - - -class ParentA: ... - - -class ChildA(ParentA, Generic[T]): - def __init__(self, a: T) -> None: ... - - -def func1(arg1: ParentA, arg2: ParentA): ... - - -func1(ChildA(1), ChildA(2)) - - -class ParentB(Generic[T]): ... - - -class ChildB(ParentB[T]): - def __init__(self, a: T) -> None: ... - - -def func2(arg1: ParentB[T], arg2: ParentB[T]) -> T: ... - - -# This should generate an error. -func2(ChildB(""), ChildB(1.2)) - - -class ClassC(Generic[S]): - def __new__(cls, item: S) -> "ClassC[S]": ... - - def __call__(self, obj: Any) -> S: ... - - -def func3(func1: Callable[..., T], func2: Callable[..., T]) -> T: ... - - -x2 = func3(ClassC(""), ClassC(1)) -reveal_type(x2, expected_text="str | int") - - -class ClassD(Generic[S]): - @overload - def __new__(cls, item: S, /) -> ClassD[S]: ... - - @overload - def __new__(cls, item: S, __item2: S, /) -> ClassD[tuple[S, S]]: ... - - def __new__(cls, *items: Any) -> Any: ... - - def __call__(self, obj: Any) -> Any: ... - - -func3(ClassD(""), ClassD("")) - - -def func4(a: Iterable[tuple[str, ...]]): - zip(a, zip(*a)) diff --git a/packages/vipeye-internal/src/tests/samples/constructor29.py b/packages/vipeye-internal/src/tests/samples/constructor29.py deleted file mode 100644 index 758518c3..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor29.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where a constructor for a generic class is -# called with a bidirectional type inference context that includes a union -# of multiple types that could apply. - -from typing import Mapping - - -d1: dict[str, str] | dict[int, int] = dict() -reveal_type(d1, expected_text="dict[int, int]") - -d2: dict[int, int] | dict[str, str] = dict() -reveal_type(d2, expected_text="dict[int, int]") - -d3: Mapping[int, int] | Mapping[str, str] | int | float = dict() -reveal_type(d3, expected_text="dict[int, int]") - -d4: dict[str, str] | dict[int, int] = dict(a="hi") -reveal_type(d4, expected_text="dict[str, str]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor3.py b/packages/vipeye-internal/src/tests/samples/constructor3.py deleted file mode 100644 index 685396a0..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor3.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests inference of constructed types (in this case, -# for "chain") when the expected type is provided by another -# constructor (in this case "list"). - -# viper: strict - -from concurrent.futures import Future, wait -from itertools import chain -from typing import Any, Dict - -my_list = list(chain([0])) -reveal_type(my_list, expected_text="list[int]") - - -pending: Dict[Future[Any], Any] = {} -done_tasks = wait(list(pending.keys())).done - -reveal_type(done_tasks, expected_text="set[Future[Any]]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor30.py b/packages/vipeye-internal/src/tests/samples/constructor30.py deleted file mode 100644 index e2bae00b..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor30.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests the case where a class is parameterized by a ParamSpec -# which is inferred by a call to the constructor, and the passed value -# is a generic function whose types are informed by additional parameters -# also passed to the constructor. - -from typing import Callable, Generic, ParamSpec, TypeVar - -P = ParamSpec("P") -T = TypeVar("T") - - -class ABase: ... - - -class A(ABase): ... - - -TA = TypeVar("TA", bound=ABase) - - -class B(Generic[P, T]): - def __init__( - self, _type: Callable[P, T], *args: P.args, **kwargs: P.kwargs - ) -> None: ... - - -def func1(t: type[TA]) -> TA: ... - - -b = B(func1, A) -reveal_type(b, expected_text="B[(t: type[A]), A]") - - -class C(Generic[TA]): - def __init__(self, _type: type[TA]) -> None: ... - - -c = B(C, A) -reveal_type(c, expected_text="B[(_type: type[A]), C[A]]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor31.py b/packages/vipeye-internal/src/tests/samples/constructor31.py deleted file mode 100644 index 1f852ecd..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor31.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where bidirectional type inference fails -# because a particular set of nested constructor calls and variance -# combinations makes it impossible to infer the correct type arguments -# using bidirectional type inference. We need to fall back to using -# regular evaluation rules in this case. - -from typing import Iterable, Sequence - -list1 = [1] - - -class NT(tuple[list]): ... - - -x1: Iterable[NT | Sequence] = list(zip(list1)) diff --git a/packages/vipeye-internal/src/tests/samples/constructor32.py b/packages/vipeye-internal/src/tests/samples/constructor32.py deleted file mode 100644 index c607bcbd..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor32.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the case where a metaclass __call__ method is present -# and supplies a different bidirectional type inference context than -# the __new__ or __init__ methods. - -from typing import TypedDict, TypeVar - -T = TypeVar("T") - - -class TD1(TypedDict): - x: int - - -class AMeta(type): - def __call__(cls, *args, **kwargs): - super().__call__(*args, **kwargs) - - -class A(metaclass=AMeta): - def __init__(self, params: TD1): - pass - - -A({"x": 42}) - - -class BMeta(type): - def __call__(cls: type[T], x: int, y: str) -> T: ... - - -class B(metaclass=BMeta): ... - - -def func1(cls: type[B]): - # This should generate an error. - cls() diff --git a/packages/vipeye-internal/src/tests/samples/constructor33.py b/packages/vipeye-internal/src/tests/samples/constructor33.py deleted file mode 100644 index c5712cfa..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor33.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the case where an argument to a constructor -# uses an assignment expression (walrus operator) and the constructor -# has both a __new__ and __init__ method whose parameters have -# different bidirectional type inference contexts. - -from dataclasses import dataclass -from typing import Any, Self, TypedDict - - -class A: - def __new__(cls, *args: Any, **kwargs: Any) -> Self: ... - def __init__(self, base: list[str], joined: str) -> None: ... - - -A(temp := ["x"], " ".join(temp)) - - -class TD1(TypedDict): - a: str - - -class TD2(TD1): - b: str - - -@dataclass -class DC1[T: TD1]: - x: T - - -@dataclass -class DC2[T: TD1]: - y: list[DC1[T]] - - -@dataclass -class DC3[T: TD1]: - embedded: DC2[T] - - -v1 = DC3[TD2](DC2(y=[DC1(x={"a": "", "b": ""})])) diff --git a/packages/vipeye-internal/src/tests/samples/constructor4.py b/packages/vipeye-internal/src/tests/samples/constructor4.py deleted file mode 100644 index 71b5c8c3..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor4.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests that unspecified type parameters -# for a class instance are "unknown". - -from collections import defaultdict -from queue import Queue -from typing import DefaultDict, List, Type, TypeVar - -val1 = Queue() -reveal_type(val1, expected_text="Queue[Unknown]") - -val2 = list() -reveal_type(val2, expected_text="list[Unknown]") - -_T = TypeVar("_T") - - -def foo(value: Type[_T], b: _T) -> None: - val1: "DefaultDict[str, list[_T]]" = defaultdict(list) - reveal_type(val1, expected_text="DefaultDict[str, list[_T@foo]]") - - val2: "DefaultDict[str, list[_T]]" = defaultdict(List[_T]) - reveal_type(val2, expected_text="DefaultDict[str, list[_T@foo]]") - - # This should generate an error because the type is incompatible. - val3: "DefaultDict[str, list[_T]]" = defaultdict(list[int]) diff --git a/packages/vipeye-internal/src/tests/samples/constructor5.py b/packages/vipeye-internal/src/tests/samples/constructor5.py deleted file mode 100644 index 1f76cc6c..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor5.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case where a constructor -# (in this case, OrderedDict) accepts a dict expression -# that is matched against a protocol in the OrderedDict -# constructor. - -from typing import OrderedDict - - -val1 = { - "a": 1, - "b": 0, -} -reveal_type(val1, expected_text="dict[str, int]") - -val2 = OrderedDict(val1) -reveal_type(val2, expected_text="OrderedDict[str, int]") - - -val3 = OrderedDict( - { - "a": 1, - "b": 0, - } -) -reveal_type(val3, expected_text="OrderedDict[str, int]") diff --git a/packages/vipeye-internal/src/tests/samples/constructor6.py b/packages/vipeye-internal/src/tests/samples/constructor6.py deleted file mode 100644 index 04f20db5..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor6.py +++ /dev/null @@ -1,87 +0,0 @@ -# This sample tests the special-case handling of an overloaded __init__ -# method where the "self" parameter is specialized to influence the -# type of the constructed object. - -from typing import Any, Generic, Literal, Optional, Type, TypeVar, overload - -_T = TypeVar("_T", bound=Optional[str]) - - -class TextField(Generic[_T]): - @overload - def __init__(self: "TextField[str]", *, null: Literal[False] = ...) -> None: ... - - @overload - def __init__( - self: "TextField[Optional[str]]", - *, - null: Literal[True] = ..., - ) -> None: ... - - @overload - def __init__(self, *, null: bool = ...) -> None: ... - - def __init__(self, *, null: bool = ...) -> None: ... - - def __get__(self: "TextField[_T]", instance: Any, owner: Any) -> _T: ... - - -def foo(a: bool): - reveal_type(TextField(), expected_text="TextField[str]") - reveal_type(TextField(null=True), expected_text="TextField[str | None]") - reveal_type(TextField(null=a), expected_text="TextField[Unknown]") - - -class Model: ... - - -_T1 = TypeVar("_T1", bound="Optional[Model]") -_T2 = TypeVar("_T2", bound="Optional[Model]") - - -class ForeignKey(Generic[_T1]): - @overload - def __init__( - self: "ForeignKey[_T2]", to: Type[_T2], *, null: Literal[False] = ... - ) -> None: ... - - @overload - def __init__( - self: "ForeignKey[Optional[_T2]]", to: Type[_T2], *, null: Literal[True] - ) -> None: ... - - def __init__(self, to: Type[_T2], *, null: bool = False) -> None: ... - - -class Author(Model): - pass - - -reveal_type(ForeignKey(Author, null=False), expected_text="ForeignKey[Author]") -reveal_type(ForeignKey(Author, null=True), expected_text="ForeignKey[Author | None]") - - -_T3 = TypeVar("_T3") -_T4 = TypeVar("_T4") -_S1 = TypeVar("_S1") -_S2 = TypeVar("_S2") - - -class Class1(Generic[_T3, _T4]): - def __init__(self: "Class1[_S1, _S2]", value1: _S1, value2: _S2) -> None: ... - - -reveal_type(Class1(0, ""), expected_text="Class1[int, str]") - - -class Class2(Generic[_T3, _T4]): - def __init__(self: "Class2[_S2, _S1]", value1: _S1, value2: _S2) -> None: ... - - -reveal_type(Class2(0, ""), expected_text="Class2[str, int]") - - -class Class3(Generic[_T3, _T4]): - # This should generate an error because class-scoped TypeVars are not - # allowed in the "self" type annotation for an __init__ method. - def __init__(self: "Class3[_T3, _T4]", value1: _T3, value2: _T4) -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/constructor7.py b/packages/vipeye-internal/src/tests/samples/constructor7.py deleted file mode 100644 index d2163283..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor7.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the case where a __new__ method provides -# a type that differs from the class that contains it. - - -from typing import Any, Callable, ParamSpec, Self, TypeVar - - -class ClassA: - def __new__(cls) -> str: - return "Hello World" - - -v1 = ClassA() -reveal_type(v1, expected_text="str") - - -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -def func1(a: int) -> int: - return a + 1 - - -class ClassB: - def __new__(cls, func: Callable[_P, _R]) -> Callable[_P, _R]: - return func - - -v2 = ClassB(func1) -reveal_type(v2, expected_text="(a: int) -> int") - - -class ClassC: - def __new__(cls) -> Any: - return 1 - - def __init__(self, a: int) -> None: ... - - -ClassC() - - -class ClassD: - def __new__(cls) -> Self | Any: - return 1 - - def __init__(self, a: int) -> None: ... - - -ClassD() diff --git a/packages/vipeye-internal/src/tests/samples/constructor9.py b/packages/vipeye-internal/src/tests/samples/constructor9.py deleted file mode 100644 index 6ca11eab..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructor9.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample validates that type(self) can be instantiated without -# error even if the class is abstract. - -from abc import ABC, abstractmethod -from typing import TypeVar - -T_A = TypeVar("T_A", bound="A") - - -class A(ABC): - @abstractmethod - def some_method(self) -> str: ... - - def some_factory_method_1(self): - return type(self)() - - def some_factory_method_2(self: T_A) -> T_A: - return type(self)() diff --git a/packages/vipeye-internal/src/tests/samples/constructorCallable1.py b/packages/vipeye-internal/src/tests/samples/constructorCallable1.py deleted file mode 100644 index c04aa9ed..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructorCallable1.py +++ /dev/null @@ -1,174 +0,0 @@ -# This sample verifies that a class can be assigned to a Callable -# type if its constructor conforms to that type. - -from dataclasses import dataclass -from typing import ( - Any, - Callable, - Generic, - Literal, - ParamSpec, - Sized, - TypeVar, - Union, - overload, -) - -T1 = TypeVar("T1") -T2 = TypeVar("T2") -P = ParamSpec("P") -R = TypeVar("R") - - -def func1(callback: Callable[[T1], T2], val: T1) -> T2: ... - - -class A(Generic[T1]): - def __new__(cls, x: T1) -> "A[T1]": ... - - -a1 = func1(A[float], 3.4) -reveal_type(a1, expected_text="A[float]") - -# This should generate an error. -a2 = func1(A[int], 3.4) - -a3 = func1(A[int], 3) -reveal_type(a3, expected_text="A[int]") - - -class B(Generic[T1]): - @overload - def __new__(cls, x: int, y: Literal[True]) -> "B[None]": ... - - @overload - def __new__(cls, x: T1, y: bool = ...) -> "B[T1]": ... - - def __new__(cls, x: Union[T1, int], y: bool = False) -> "B[Any]": ... - - -b1 = func1(B[int], 3) -reveal_type(b1, expected_text="B[int]") - -# This should generate an error. -b2 = func1(B[None], 3.5) - -b3 = func1(B[float], 3.5) -reveal_type(b3, expected_text="B[float]") - -b4 = func1(B[Union[int, str]], 3) -reveal_type(b4, expected_text="B[int | str]") - -b5 = func1(B[Union[int, str]], "3") -reveal_type(b5, expected_text="B[int | str]") - - -class C(Generic[T1]): - def __init__(self, x: T1) -> None: ... - - -c1 = func1(C[float], 3.4) -reveal_type(c1, expected_text="C[float]") - -# This should generate an error. -c2 = func1(C[int], 3.4) - -c3 = func1(C[int], 3) -reveal_type(c3, expected_text="C[int]") - - -class D(Generic[T1]): - @overload - def __init__(self: "D[None]", x: int, y: Literal[True]) -> None: ... - - @overload - def __init__(self, x: T1, y: bool = ...) -> None: ... - - def __init__(self, x: Any, y: bool = False) -> None: ... - - -d1 = func1(D[int], 3) -reveal_type(d1, expected_text="D[int]") - -# This should generate an error. -d2 = func1(D[None], 3.5) - -d3 = func1(D[float], 3.5) -reveal_type(d3, expected_text="D[float]") - -d4 = func1(D[Union[int, str]], 3) -reveal_type(d4, expected_text="D[int | str]") - -d5 = func1(D[Union[int, str]], "3") -reveal_type(d5, expected_text="D[int | str]") - - -@dataclass(frozen=True, slots=True) -class E(Generic[T1]): - x: T1 - - -e1: Callable[[int], E[int]] = E - - -def func2(x: T1) -> E[T1]: ... - - -e2: Callable[[int], E[int]] = func2 - - -def cast_to_callable(cls: Callable[P, T1]) -> Callable[P, T1]: - return cls - - -class F: - pass - - -reveal_type(cast_to_callable(F), expected_text="() -> F") -reveal_type( - cast_to_callable(Sized), expected_text="(*args: Any, **kwargs: Any) -> Sized" -) - - -def func3(t: type[object]): - reveal_type( - cast_to_callable(t), expected_text="(*args: Any, **kwargs: Any) -> object" - ) - - -@dataclass -class G: - value: int - - -def func4(c: Callable[[T1], T2]) -> Callable[[T1], T2]: - return c - - -reveal_type(func4(G), expected_text="(int) -> G") - - -# Test the conversion of a complex constructor that involves -# a bunch of type variables, a default __new__ (that comes -# from object), and an __init__ that involves custom self -# types. This is meant to test a class like defaultdict. -KT = TypeVar("KT") -VT = TypeVar("VT") - - -class DDict(dict[KT, VT]): - @overload - def __init__(self) -> None: ... - @overload - def __init__(self: "DDict[str, T1]", **kwargs: T1) -> None: ... - @overload - def __init__(self, default_factory: Callable[[], VT] | None, /) -> None: ... - def __init__(self, *args: Any, **kwargs: Any) -> None: ... - - -dd1 = cast_to_callable(DDict) -reveal_type( - dd1, - expected_text="Overload[() -> DDict[Unknown, Unknown], (**kwargs: T1@__init__) -> DDict[str, T1@__init__], (default_factory: (() -> VT@DDict) | None, /) -> DDict[Unknown, VT@DDict]]", -) diff --git a/packages/vipeye-internal/src/tests/samples/constructorCallable2.py b/packages/vipeye-internal/src/tests/samples/constructorCallable2.py deleted file mode 100644 index bf0872af..00000000 --- a/packages/vipeye-internal/src/tests/samples/constructorCallable2.py +++ /dev/null @@ -1,163 +0,0 @@ -# This sample tests the case where a constructor is converted to -# a callable. - - -from typing import ( - Any, - Callable, - Generic, - NoReturn, - ParamSpec, - Self, - TypeVar, - overload, - reveal_type, -) - -P = ParamSpec("P") -R = TypeVar("R") -T = TypeVar("T") - - -def accepts_callable(cb: Callable[P, R]) -> Callable[P, R]: - return cb - - -class Class1: - def __init__(self, x: int) -> None: - pass - - -r1 = accepts_callable(Class1) -reveal_type(r1, expected_text="(x: int) -> Class1") -reveal_type(r1(1), expected_text="Class1") - - -class Class2: - pass - - -r2 = accepts_callable(Class2) -reveal_type(r2, expected_text="() -> Class2") -reveal_type(r2(), expected_text="Class2") - - -class Class3: - def __new__(cls, *args, **kwargs) -> Self: ... - - def __init__(self, x: int) -> None: ... - - -r3 = accepts_callable(Class3) -reveal_type(r3, expected_text="(x: int) -> Class3") -reveal_type(r3(3), expected_text="Class3") - - -class Class4: - def __new__(cls, x: int) -> int: ... - - -r4 = accepts_callable(Class4) -reveal_type(r4, expected_text="(x: int) -> int") -reveal_type(r4(1), expected_text="int") - - -class Meta1(type): - def __call__(cls, *args: Any, **kwargs: Any) -> NoReturn: - raise NotImplementedError("Class not constructable") - - -class Class5(metaclass=Meta1): - def __new__(cls, *args: Any, **kwargs: Any) -> Self: - return super().__new__(cls) - - -r5 = accepts_callable(Class5) -reveal_type(r5, expected_text="(...) -> NoReturn") - - -class Class6Proxy: ... - - -class Class6: - def __new__(cls) -> Class6Proxy: - # This should generate an error because "cls" isn't compatible. - return Class6Proxy.__new__(cls) - - def __init__(self, x: int) -> None: - pass - - -r6 = accepts_callable(Class6) -reveal_type(r6, expected_text="() -> Class6Proxy") -reveal_type(r6(), expected_text="Class6Proxy") - - -class Class6_2: - def __new__(cls) -> Any: - return super().__new__(cls) - - def __init__(self, x: int) -> None: - pass - - -r6_2 = accepts_callable(Class6_2) -reveal_type(r6_2, expected_text="() -> Any") -reveal_type(r6_2(), expected_text="Any") - - -class Class7(Generic[T]): - @overload - def __init__(self: "Class7[int]", x: int) -> None: ... - - @overload - def __init__(self: "Class7[str]", x: str) -> None: ... - - def __init__(self, x: int | str) -> None: - pass - - -r7 = accepts_callable(Class7) -reveal_type( - r7, expected_text="Overload[(x: int) -> Class7[int], (x: str) -> Class7[str]]" -) - -reveal_type(r7(0), expected_text="Class7[int]") -reveal_type(r7(""), expected_text="Class7[str]") - - -class Class8(Generic[T]): - def __new__(cls, x: T, y: list[T]) -> Self: - return super().__new__(cls) - - -r8 = accepts_callable(Class8) -reveal_type(r8, expected_text="(x: T@Class8, y: list[T@Class8]) -> Class8[T@Class8]") -reveal_type(r8("", [""]), expected_text="Class8[str]") - - -class Class9: - def __init__(self, x: list[T], y: list[T]) -> None: - pass - - -r9 = accepts_callable(Class9) -reveal_type(r9, expected_text="(x: list[T@__init__], y: list[T@__init__]) -> Class9") -reveal_type(r9([""], [""]), expected_text="Class9") - - -M = TypeVar("M") - - -class Meta2(type): - def __call__(cls: type[M], *args: Any, **kwargs: Any) -> M: ... - - -class Class10(metaclass=Meta2): - def __new__(cls, x: int, y: str) -> Self: - return super().__new__(cls) - - -r10 = accepts_callable(Class10) -reveal_type(r10, expected_text="(x: int, y: str) -> Class10") -reveal_type(r10(1, ""), expected_text="Class10") diff --git a/packages/vipeye-internal/src/tests/samples/coroutines1.py b/packages/vipeye-internal/src/tests/samples/coroutines1.py deleted file mode 100644 index 4a6739df..00000000 --- a/packages/vipeye-internal/src/tests/samples/coroutines1.py +++ /dev/null @@ -1,69 +0,0 @@ -# This same tests the type checker's ability to validate -# types related to coroutines (and async/await) statements. - -from typing import Generator, Any, Optional -from asyncio import coroutine - - -async def coroutine1(): - return 1 - - -a = coroutine1() - -# This should generate an error because 'await' -# can't be used outside of an async function. -await a - - -async def func1() -> int: ... - - -async def func2() -> None: - # This should generate an error because await cannot be - # used in a lambda. - x = lambda: await func2() - - -def needs_int(val: int): - pass - - -async def consumer1(): - # This should generate an error because - # a is not an int - needs_int(a) - - needs_int(await a) - - needs_int(await coroutine1()) - - -class ScopedClass1: - def __aenter__(self): - return self - - @coroutine - def __await__(self) -> Generator[Any, None, int]: - yield 3 - return 3 - - async def __aexit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -async def consumer2(): - a = ScopedClass1() - - # This should generate two errors because - # there is no __enter__ or __exit__ method on ScopedClass1. - with a as b: - needs_int(b) - - async with a as b: - needs_int(b) diff --git a/packages/vipeye-internal/src/tests/samples/coroutines2.py b/packages/vipeye-internal/src/tests/samples/coroutines2.py deleted file mode 100644 index 51016315..00000000 --- a/packages/vipeye-internal/src/tests/samples/coroutines2.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample verifies that the inferred return type -# of an async function is wrapped in a Coroutine. - -import asyncio -from typing import Any, Coroutine - - -async def inspector(cr: Coroutine[Any, Any, Any]): - return await cr - - -async def inner(sleep: int, message: str) -> str: - await asyncio.sleep(sleep) - print(message) - return message - - -async def outer(): - await inspector(inner(1, "test")) - - -async def recursive1(): - await recursive1() diff --git a/packages/vipeye-internal/src/tests/samples/coroutines3.py b/packages/vipeye-internal/src/tests/samples/coroutines3.py deleted file mode 100644 index 2352cc48..00000000 --- a/packages/vipeye-internal/src/tests/samples/coroutines3.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests old-style (pre-await) awaitable generators. - -import asyncio -from typing import Any -from _typeshed._type_checker_internals import AwaitableGenerator - - -@asyncio.coroutine -def old_style_coroutine1(): - yield from asyncio.sleep(1) - - -async def func1() -> None: - x = await old_style_coroutine1() - reveal_type(x, expected_text="None") - return x - - -reveal_type( - old_style_coroutine1, - expected_text="() -> AwaitableGenerator[Any, Unknown, None, Any]", -) - - -@asyncio.coroutine -def old_style_coroutine2() -> AwaitableGenerator[None, None, None, Any]: - yield from asyncio.sleep(1) - - -async def func2() -> None: - x = await old_style_coroutine2() - reveal_type(x, expected_text="None") - return x - - -reveal_type( - old_style_coroutine2, - expected_text="() -> AwaitableGenerator[None, None, None, Any]", -) diff --git a/packages/vipeye-internal/src/tests/samples/coroutines4.py b/packages/vipeye-internal/src/tests/samples/coroutines4.py deleted file mode 100644 index 32967916..00000000 --- a/packages/vipeye-internal/src/tests/samples/coroutines4.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where an inner coroutine with an inferred -# return type is referenced in a manner that results in recursion. - -import asyncio - - -def func1(replace_inner: bool) -> None: - inner = lambda: None - - async def wrapper(): - inner() - - wrapped_fn = wrapper() - asyncio.create_task(wrapped_fn) - - if replace_inner: - inner = lambda: None diff --git a/packages/vipeye-internal/src/tests/samples/dataclass1.py b/packages/vipeye-internal/src/tests/samples/dataclass1.py deleted file mode 100644 index 45e59cb9..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass1.py +++ /dev/null @@ -1,128 +0,0 @@ -# This sample tests the handling of the @dataclass decorator. - -from dataclasses import dataclass, InitVar, field -from typing import Callable, Generic, Literal, Sequence, TypeVar - - -@dataclass -class DC1: - bbb: int - ccc: str - aaa: str = "string" - __hash__: None # viper: ignore[reportIncompatibleMethodOverride] - - -bar1 = DC1(bbb=5, ccc="hello") -bar2 = DC1(5, "hello") -bar3 = DC1(5, "hello", "hello2") -print(bar3.bbb) -print(bar3.ccc) -print(bar3.aaa) - -# This should generate an error because ddd -# isn't a declared value. -bar = DC1(bbb=5, ddd=5, ccc="hello") - -# This should generate an error because the -# parameter types don't match. -bar = DC1("hello", "goodbye") - -# This should generate an error because a parameter -# is missing. -bar = [DC1(2)] - -# This should generate an error because there are -# too many parameters. -bar = DC1(2, "hello", "hello", 4) - - -@dataclass -class DC2: - bbb: int - aaa: str = "string" - - # This should generate an error because variables - # with no default cannot come after those with - # defaults. - ccc: str - - def __init__(self) -> None: - pass - - -@dataclass -class DC3: - aaa: str - ddd: InitVar[int] = 3 - - -@dataclass(init=False) -class DC4: - bbb: int - aaa: str = "string" - # This should not generate an error because - # the ordering requirement is not enforced when - # init=False. - ccc: str - - -@dataclass -class DC5: - # Private names are not allowed, so this should - # generate an error. - __private: int - - -@dataclass -class DC6: - x: type - - -DC6(int) - -# This should generate an error. -DC6(1) - - -T1 = TypeVar("T1", int, str) - - -@dataclass -class DC7(Generic[T1]): - # This should generate an error. - x: T1 = 1 - - -v7_1 = DC7() -reveal_type(v7_1, expected_text="DC7[int]") - -# This should generate an error. -v7_2: DC7[str] = DC7() - - -@dataclass -class DC8(Generic[T1]): - # This should generate an error. - x: T1 = field(default=1) - - -# This should generate an error. -v8_1 = DC8() -reveal_type(v8_1, expected_text="DC8[int]") - -# This should generate an error. -v8_2 = DC8[str]() - - -@dataclass -class DC9(Generic[T1]): - x: Sequence[Literal["a", "b"]] = ["a"] - - -@dataclass -class DC10[T]: - a: type[T] - b: Callable[[T], bool] = lambda _: True - - -DC10(a=int) diff --git a/packages/vipeye-internal/src/tests/samples/dataclass10.py b/packages/vipeye-internal/src/tests/samples/dataclass10.py deleted file mode 100644 index d6633be4..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass10.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample verifies that a generic dataclass works. - -from dataclasses import dataclass -from typing import Generic, TypeVar, Union - -T = TypeVar("T") - - -@dataclass -class ABase(Generic[T]): - value: Union[str, T] - - -reveal_type(ABase(""), expected_text="ABase[Unknown]") - - -class AChild(ABase[int]): - pass - - -reveal_type(AChild(123), expected_text="AChild") - - -class B(Generic[T]): - pass - - -@dataclass -class CBase(Generic[T]): - x: B[T] = B[T]() - - -@dataclass -class CChild(CBase[T]): - pass - - -c1 = CBase[int]() -reveal_type(c1, expected_text="CBase[int]") -reveal_type(c1.x, expected_text="B[int]") - -c2 = CChild[int]() -reveal_type(c2, expected_text="CChild[int]") -reveal_type(c2.x, expected_text="B[int]") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass11.py b/packages/vipeye-internal/src/tests/samples/dataclass11.py deleted file mode 100644 index 2ef75ba2..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass11.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the case where an inheritance chain of -# dataclasses use generic types. - -from dataclasses import dataclass -from typing import Generic, TypeVar - -Key0 = TypeVar("Key0") -Key1 = TypeVar("Key1") -Key2 = TypeVar("Key2") -Value = TypeVar("Value") - - -@dataclass -class MapTreeLeaf(Generic[Key0, Value]): - key: Key0 - value: Value - - -@dataclass -class MapTreeNode(MapTreeLeaf[Key1, Value]): - pass - - -class Foo(Generic[Key2, Value]): - def add(self, key: Key2, value: Value): - return MapTreeNode(key=key, value=value) - - def test1(self, a: Key2, b: Value): - v1 = self.add(a, b) - reveal_type(v1, expected_text="MapTreeNode[Key2@Foo, Value@Foo]") - reveal_type(v1.key, expected_text="Key2@Foo") - reveal_type(v1.value, expected_text="Value@Foo") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass12.py b/packages/vipeye-internal/src/tests/samples/dataclass12.py deleted file mode 100644 index 34e82b91..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass12.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the case where a dataclass declares an instance -# variable and a subclass redeclares it as a class variable. - -# viper: reportIncompatibleVariableOverride=false - -from dataclasses import dataclass -from typing import ClassVar - - -@dataclass -class Base: - x: int - y: int - - -@dataclass -class Special(Base): - x: ClassVar[int] = 1 - z: int - - -@dataclass -class VerySpecial(Special): - y: ClassVar[int] = 2 - - -Base(x=1, y=2) -Special(y=2, z=3) -Special(2, 3) - -# This should generate an error -Special(x=1, y=2, z=3) - -# This should generate an error -Special(1, 2, 3) - -VerySpecial(z=3) - -# This should generate an error -VerySpecial(x=1, z=3) diff --git a/packages/vipeye-internal/src/tests/samples/dataclass13.py b/packages/vipeye-internal/src/tests/samples/dataclass13.py deleted file mode 100644 index acf7ca4f..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass13.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that a dataclass member without a type annotation -# but with a field descriptor assignment results in an error. - -from dataclasses import dataclass, field - - -@dataclass -class MyClass: - id: int - x: int = field() - - # This should generate an error because it will result in a runtime exception - y = field() diff --git a/packages/vipeye-internal/src/tests/samples/dataclass14.py b/packages/vipeye-internal/src/tests/samples/dataclass14.py deleted file mode 100644 index 8bc9661c..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass14.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where a dataclass field has a corresponding -# redundant declaration within a method. - -from dataclasses import dataclass - - -@dataclass -class ClassA: - a: int - b: str - - def foo(self): - self.b: str = "" - - -ClassA(1, "hi") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass15.py b/packages/vipeye-internal/src/tests/samples/dataclass15.py deleted file mode 100644 index 64d05302..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass15.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a dataclass type refers to -# type that circularly refers back to the dataclass itself -# through a type alias. - -from dataclasses import dataclass -from typing import List - - -class ClassA: - test: "C" - - -@dataclass -class ClassB: - children: "C" - - def test(self): - for child in self.children: - reveal_type(child, expected_text="ClassB") - - -C = List[ClassB] diff --git a/packages/vipeye-internal/src/tests/samples/dataclass16.py b/packages/vipeye-internal/src/tests/samples/dataclass16.py deleted file mode 100644 index 805d6ac1..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass16.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the generation of __init__ when some ancestor -# classes are unknown. - -from dataclasses import dataclass -import abc -from random import random - -C = abc.ABC if random() else object - - -class B(C): - def __init__(self, x: int): - pass - - -@dataclass -class A(B): - color: str - - -reveal_type(A.__init__, expected_text="(self: A, *args: Any, **kwargs: Any) -> None") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass17.py b/packages/vipeye-internal/src/tests/samples/dataclass17.py deleted file mode 100644 index 1d770129..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass17.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the case where a dataclass uses a ClassVar that -# is also Final. - -from dataclasses import dataclass -from typing import ClassVar, Final - - -@dataclass -class A: - a: Final[int] - b: Final[str] = "" - c: ClassVar[Final[int]] = 0 - d: ClassVar[Final] = 0 - e: Final[ClassVar[int]] = 0 - - -a = A(1) - -# This should generate an error. -a.a = 0 - -# This should generate an error. -a.b = "" - -# This should generate an error. -a.c = 0 - -# This should generate an error. -A.c = 0 - -# This should generate an error. -A.d = 0 - -# This should generate an error. -A.e = 0 - - -@dataclass -class B: - a: ClassVar[Final[int]] = 0 - b: int = 1 diff --git a/packages/vipeye-internal/src/tests/samples/dataclass18.py b/packages/vipeye-internal/src/tests/samples/dataclass18.py deleted file mode 100644 index 20771e58..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass18.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a "bare" Final is used in a dataclass -# with a default value. - -from typing import Final -from dataclasses import dataclass - - -@dataclass -class DC1: - a: Final = 1 - - -v1 = DC1(1) -reveal_type(v1.a, expected_text="Literal[1]") - -v2 = DC1() -reveal_type(v2.a, expected_text="Literal[1]") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass2.py b/packages/vipeye-internal/src/tests/samples/dataclass2.py deleted file mode 100644 index a332a96a..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass2.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the handling of Callable fields within a -# dataclass definition. - -# viper: strict - -from dataclasses import dataclass -from typing import Any, Callable, TypeVar - -CallableT = TypeVar("CallableT", bound=Callable[..., Any]) - - -def decorate(arg: CallableT) -> CallableT: - return arg - - -def f(s: str) -> int: - return int(s) - - -@dataclass -class C: - str_to_int: Callable[[str], int] = f - - -c = C() - - -reveal_type(c.str_to_int, expected_text="(str) -> int") - -c.str_to_int = decorate(f) diff --git a/packages/vipeye-internal/src/tests/samples/dataclass3.py b/packages/vipeye-internal/src/tests/samples/dataclass3.py deleted file mode 100644 index 1e8d4013..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass3.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the type checker's handling of -# synthesized __init__ and __new__ methods for -# dataclass classes and their subclasses. - -from dataclasses import dataclass - - -@dataclass -class A: - x: int - - -@dataclass(init=False) -class B(A): - y: int - - def __init__(self, a: A, y: int): - self.__dict__ = a.__dict__ - - -a = A(3) -b = B(a, 5) - - -# This should generate an error because there is an extra parameter -a = A(3, 4) - -# This should generate an error because there is one too few parameters -b = B(a) - - -A.__new__(A) -B.__new__(B) diff --git a/packages/vipeye-internal/src/tests/samples/dataclass4.py b/packages/vipeye-internal/src/tests/samples/dataclass4.py deleted file mode 100644 index 8402f62c..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass4.py +++ /dev/null @@ -1,110 +0,0 @@ -# This sample tests the analyzer's ability to handle inherited -# data classes. - -# viper: reportIncompatibleVariableOverride=false - -from dataclasses import dataclass, field - - -class C1: ... - - -class C2: ... - - -class C3: ... - - -@dataclass -class DC1: - aa: C1 - bb: C2 - cc: C3 - - -class NonDC2: - ff: int - - -@dataclass -class DC2(NonDC2, DC1): - ee: C2 - aa: C2 - dd: C2 - - -dc2_1 = DC2(C2(), C2(), C3(), C2(), C2()) - -# This should generate an error because the type -# of parameter aa has been replaced with type C1. -dc2_2 = DC2(C1(), C2(), C3(), C2(), C2()) - -dc2_3 = DC2(ee=C2(), dd=C2(), aa=C2(), bb=C2(), cc=C3()) - - -@dataclass -class DC3: - aa: C1 - bb: C2 = C2() - cc: C3 = C3() - - -@dataclass -class DC4(DC3): - # This should generate an error because - # previous parameters have default values. - dd: C1 - - -@dataclass -class DC5(DC3): - # This should not generate an error because - # aa replaces aa in DC3, and it's ordered - # before the params with default values. - aa: C2 - - -@dataclass -class DC6: - a: int = 0 - - -@dataclass -class DC7(DC6): - # This should generate an error because it is overriding - # a field with a default value, but it doesn't have a - # default value. - a: int - - # This should generate an error because the default - # value for "a" is inherited from the base class. - b: str - - -@dataclass -class DC8: - a: int = field(default=0) - - -@dataclass -class DC9(DC8): - # This should generate an error because it is overriding - # a field with a default value, but it doesn't have a - # default value. - a: int - - # This should generate an error because the default - # value for "a" is inherited from the base class. - b: str - - -@dataclass -class DC10: - a: str = field(init=False, default="s") - b: bool = field() - - -@dataclass -class DC11(DC10): - a: str = field() - b: bool = field() diff --git a/packages/vipeye-internal/src/tests/samples/dataclass5.py b/packages/vipeye-internal/src/tests/samples/dataclass5.py deleted file mode 100644 index fcd55d9c..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass5.py +++ /dev/null @@ -1,83 +0,0 @@ -# This sample tests the handling of the @dataclass decorator -# with a custom __init__. - -# viper: reportIncompatibleMethodOverride=false - -from dataclasses import dataclass - - -@dataclass(init=False) -class A: - x: int - x_squared: int - - def __init__(self, x: int): - self.x = x - self.x_squared = x**2 - - -a = A(3) - - -@dataclass(init=True) -class B: - x: int - x_squared: int - - def __init__(self, x: int): - self.x = x - self.x_squared = x**2 - - -b = B(3) - - -@dataclass() -class C: - x: int - x_squared: int - - def __init__(self, x: int): - self.x = x - self.x_squared = x**2 - - -c = C(3) - - -@dataclass(init=False) -class D: - x: int - x_squared: int - - -# This should generate an error because there is no -# override __init__ method and no synthesized __init__. -d = D(3) - - -@dataclass(eq=False) -class E: - x: int - - def __eq__(self, x: "E") -> float: - return 1.23 - - def __lt__(self, x: "E") -> str: - return "" - - -foo1 = E(3) == E(3) -reveal_type(foo1, expected_text="float") - -foo2 = E(3) < E(3) -reveal_type(foo2, expected_text="str") - - -@dataclass(order=True) -class F: - x: int - - -foo3 = F(3) < F(3) -reveal_type(foo3, expected_text="bool") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass6.py b/packages/vipeye-internal/src/tests/samples/dataclass6.py deleted file mode 100644 index c2a96330..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass6.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the case where a dataclass entry is -# initialized with a "field" that uses "init=False". This -# case needs to be handled specially because it means -# that the synthesized __init__ method shouldn't include -# this field in its parameter list. - -from dataclasses import dataclass, field - - -@dataclass -class ParentA: - prop_1: str = field(init=False) - prop_2: str = field(default="hello") - prop_3: str = field(default_factory=lambda: "hello") - - # This should generate an error because it appears after - # a property with a default value. - prop_4: str = field() - - def __post_init__(self): - self.prop_1 = "test" - - -@dataclass -class ChildA(ParentA): - prop_2: str = "bye" - - -test = ChildA(prop_2="test", prop_4="hi") - -assert test.prop_1 == "test" -assert test.prop_2 == "test" - - -@dataclass -class ClassB: - prop_1: str - prop_2: str - prop_3: str = field(default="") - prop_4: str = field(init=False) - prop_5: str = field(init=False) - - def __post_init__(self): - cprop_1 = "calculated value" - cprop_2 = "calculated value" diff --git a/packages/vipeye-internal/src/tests/samples/dataclass7.py b/packages/vipeye-internal/src/tests/samples/dataclass7.py deleted file mode 100644 index e098ae5a..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass7.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests the synthesized comparison operators for dataclasses. - -from dataclasses import dataclass - - -@dataclass(order=True) -class DC1: - a: str - b: int - - -@dataclass(order=True) -class DC2: - a: str - b: int - - -dc1_1 = DC1("hi", 2) -dc1_2 = DC1("hi", 2) - -if dc1_1 < dc1_2: - print("") - -if dc1_1 <= dc1_2: - print("") - -if dc1_1 > dc1_2: - print("") - -if dc1_1 >= dc1_2: - print("") - -if dc1_1 == dc1_2: - print("") - -if dc1_1 != dc1_2: - print("") - -if dc1_1 == None: - print("") - -if dc1_1 != None: - print("") - -dc2_1 = DC2("hi", 2) - -# This should generate an error because the types are -# incompatible. -if dc1_1 < dc2_1: - print("") - -if dc1_1 != dc2_1: - print("") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass8.py b/packages/vipeye-internal/src/tests/samples/dataclass8.py deleted file mode 100644 index 632ec8a9..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass8.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the type checker's ability to handle -# circular type references within dataclass definitions. - -from dataclasses import dataclass -from pathlib import Path - - -@dataclass -class ParentA: - b: "ClassB" - - -@dataclass -class ChildA(ParentA): - pass - - -@dataclass -class ClassB: - sub_class: ChildA - - def method1(self): - ChildA(b=self) - - -@dataclass() -class ClassC: - name: str = "sample" - dir_a: Path = Path.home().joinpath(f"source/{name}") - dir_b: Path = dir_a.joinpath("path/to/b") diff --git a/packages/vipeye-internal/src/tests/samples/dataclass9.py b/packages/vipeye-internal/src/tests/samples/dataclass9.py deleted file mode 100644 index d6fa5f48..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclass9.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample verifies that the type analyzer adds -# the __dataclass_fields__ class variable to -# synthesized data classes. - -from dataclasses import dataclass -from typing import Any, ClassVar, Protocol - - -class IsDataclass(Protocol): - # Checking for this attribute seems to currently be - # the most reliable way to ascertain that something is a dataclass - __dataclass_fields__: ClassVar[dict[str, Any]] - - -def dataclass_only( - x: IsDataclass, -): ... # do something that only makes sense with a dataclass - - -@dataclass -class A: - pass - - -dataclass_only(A()) diff --git a/packages/vipeye-internal/src/tests/samples/dataclassConverter1.py b/packages/vipeye-internal/src/tests/samples/dataclassConverter1.py deleted file mode 100644 index fe0cd363..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassConverter1.py +++ /dev/null @@ -1,159 +0,0 @@ -# This sample tests the use of field's converter parameter -# described in PEP 712. - -from typing import Any, Callable, dataclass_transform, overload - - -def model_field(*, converter: Callable[..., Any]) -> Any: ... - - -@dataclass_transform(field_specifiers=(model_field,)) -class ModelBase: ... - - -def converter_simple(s: str) -> int: - return int(s) - - -def converter_with_param_before_args(s: str, *args: int, **kwargs: int) -> int: - return int(s) - - -def converter_with_args(*args: str) -> int: - return int(args[0]) - - -def converter_with_extra_defaulted_params( - s: str, extra: int = 1, *, extraKwarg: int = 1 -) -> int: - return int(s) - - -def converter_with_default_for_first_param(s: str = "1") -> int: - return int(s) - - -def converter_with_more_specialized_return_type(s: str) -> int: - return int(s) - - -class ConverterClass: - @overload - def __init__(self, val: str) -> None: ... - - @overload - def __init__(self, val: bytes) -> None: ... - - def __init__(self, val: str | bytes) -> None: - pass - - -class DC1(ModelBase): - field0: int = model_field(converter=converter_simple) - field1: int = model_field(converter=converter_with_param_before_args) - field2: int = model_field(converter=converter_with_args) - field3: int = model_field(converter=converter_with_extra_defaulted_params) - field4: int = model_field(converter=converter_with_default_for_first_param) - field5: int | str = model_field( - converter=converter_with_more_specialized_return_type - ) - field6: ConverterClass = model_field(converter=ConverterClass) - - -reveal_type( - DC1.__init__, - expected_text="(self: DC1, field0: str, field1: str, field2: str, field3: str, field4: str, field5: str, field6: str | bytes) -> None", -) - - -# This overload will be ignored because it has too many arguments. -@overload -def overloaded_converter(s: float, secondParam: str, /) -> int: ... - - -# This overload will be ignored because its return type doesn't match the field type. -@overload -def overloaded_converter(s: float) -> str: ... - - -@overload -def overloaded_converter(s: str) -> int: ... - - -@overload -def overloaded_converter(s: list[str]) -> int: ... - - -def overloaded_converter(s: float | str | list[str], *args: str) -> int | float | str: - return 0 - - -class Overloads(ModelBase): - field0: int = model_field(converter=overloaded_converter) - - -reveal_type( - Overloads.__init__, - expected_text="(self: Overloads, field0: str | list[str]) -> None", -) - - -class CallableObject: - @overload - def __call__(self, arg1: int) -> str: ... - - @overload - def __call__(self, arg1: str) -> int: ... - - def __call__(self, arg1: str | int | list[str]) -> int | str: - return 1 - - -callable: Callable[[str], int] = converter_simple -callable_union: Callable[[str], int] | Callable[[int], str] = converter_simple - - -class Callables(ModelBase): - field0: int = model_field(converter=CallableObject()) - field1: int = model_field(converter=callable) - field2: int = model_field(converter=callable_union) - - -reveal_type( - Callables.__init__, - expected_text="(self: Callables, field0: str, field1: str, field2: str) -> None", -) - - -def wrong_return_type(s: str) -> str: - return s - - -def wrong_number_of_params(x: str, x2: str, /) -> int: - return 1 - - -@overload -def wrong_converter_overload(s: float) -> str: ... - - -@overload -def wrong_converter_overload(s: str) -> str: ... - - -def wrong_converter_overload(s: float | str) -> int | str: - return 1 - - -class Errors(ModelBase): - # This should generate an error because the return type doesn't - # match the field type. - field0: int = model_field(converter=wrong_return_type) - - # This should generate an error because the converter has the - # wrong number of parameters. - field1: int = model_field(converter=wrong_number_of_params) - - # This should generate an error because none of the overloads - # match the field type. - field2: int = model_field(converter=wrong_converter_overload) diff --git a/packages/vipeye-internal/src/tests/samples/dataclassConverter2.py b/packages/vipeye-internal/src/tests/samples/dataclassConverter2.py deleted file mode 100644 index 7004138b..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassConverter2.py +++ /dev/null @@ -1,71 +0,0 @@ -# This sample tests assignment of dataclass fields that use -# the converter parameter described in PEP 712. - -from typing import Any, Callable, dataclass_transform - - -def converter_simple(s: str) -> int: ... - - -def converter_passThru(x: str | int) -> str | int: ... - - -def model_field(*, converter: Callable[..., Any]) -> Any: ... - - -@dataclass_transform(field_specifiers=(model_field,)) -class ModelBase: ... - - -class DC1(ModelBase): - asymmetric: int = model_field(converter=converter_simple) - symmetric: str | int = model_field(converter=converter_passThru) - - -dc1 = DC1("1", 1) - -reveal_type(dc1.asymmetric, expected_text="int") -dc1.asymmetric = "2" -reveal_type( - dc1.asymmetric, expected_text="int" -) # Asymmetric -- type narrowing should not occur -# This should generate an error because only strs can be assigned to field0. -dc1.asymmetric = 2 - -reveal_type(dc1.symmetric, expected_text="str | int") -dc1.symmetric = "1" -reveal_type( - dc1.symmetric, expected_text="Literal['1']" -) # Symmetric -- type narrowing should occur - - -reveal_type(DC1.asymmetric, expected_text="int") -DC1.asymmetric = "2" -reveal_type(DC1.asymmetric, expected_text="int") -# This should generate an error because only strs can be assigned to field0. -DC1.asymmetric = 2 - -reveal_type(DC1.symmetric, expected_text="str | int") -DC1.symmetric = "1" -reveal_type(DC1.symmetric, expected_text="Literal['1']") - - -class DC2(ModelBase): - a: dict[str, str] = model_field(converter=dict) - - -DC2({}) -DC2({"": ""}) - -# This should generate an error. -DC2({"": 1}) - - -class DC3(ModelBase): - b: tuple[int, ...] = model_field(converter=tuple) - - -DC3([1, 2, 3]) - -# This should generate an error. -DC3(["", 1]) diff --git a/packages/vipeye-internal/src/tests/samples/dataclassConverter3.py b/packages/vipeye-internal/src/tests/samples/dataclassConverter3.py deleted file mode 100644 index 5b6a59e1..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassConverter3.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a dataclass converter is used with -# a generic type. - -from typing import Any, Callable, dataclass_transform - - -def model_field(*, converter: Callable[..., Any]) -> Any: ... - - -@dataclass_transform(field_specifiers=(model_field,)) -class ModelBase: ... - - -class DC1[T](ModelBase): - data: set[T] = model_field(converter=set) - - -x = DC1([1, 2]) -reveal_type(x, expected_text="DC1[int]") -reveal_type(x.data, expected_text="set[int]") diff --git a/packages/vipeye-internal/src/tests/samples/dataclassDescriptors1.py b/packages/vipeye-internal/src/tests/samples/dataclassDescriptors1.py deleted file mode 100644 index 43a368cf..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassDescriptors1.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the handling of dataclass fields that use -# descriptor objects. - -from dataclasses import dataclass -from typing import Any, cast, overload - - -class MyDescriptor: - @overload - def __get__(self, __obj: None, __owner: Any) -> "MyDescriptor": ... - - @overload - def __get__(self, __obj: object, __owner: Any) -> int: ... - - def __get__(self, __obj: object | None, __owner: Any) -> "int | MyDescriptor": - if __obj is None: - return self - return cast(Any, __obj)._x - - def __set__(self, __obj: object, __value: int) -> None: - if __obj is not None: - cast(Any, __obj)._x = __value - - -@dataclass -class Foo: - y: MyDescriptor = MyDescriptor() - - -f1 = Foo(3) - -reveal_type(f1.y, expected_text="int") -reveal_type(Foo.y, expected_text="MyDescriptor") - - -# This should generate an error. -f2 = Foo("hi") - - -f3 = Foo() -reveal_type(f3.y, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/dataclassDescriptors2.py b/packages/vipeye-internal/src/tests/samples/dataclassDescriptors2.py deleted file mode 100644 index c6850ea0..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassDescriptors2.py +++ /dev/null @@ -1,68 +0,0 @@ -# This sample tests the handling of fields within a dataclass that -# are descriptors. - -from dataclasses import dataclass - -from typing import overload, Any, TypeVar, Generic, Optional, Union, Callable, Type -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - dataclass_transform, -) - - -_T = TypeVar("_T") - - -class A(Generic[_T]): ... - - -class Desc(Generic[_T]): - @overload - def __get__(self, instance: None, owner: Any) -> A[_T]: ... - - @overload - def __get__(self, instance: object, owner: Any) -> _T: ... - - def __get__(self, instance: Optional[object], owner: Any) -> Union[A[_T], _T]: ... - - -@dataclass_transform(field_specifiers=(Desc[Any],)) -def dataclass_like( - *, - init: bool = True, - repr: bool = True, # noqa: A002 - eq: bool = True, - order: bool = False, - unsafe_hash: bool = False, -) -> Callable[[Type[_T]], Type[_T]]: ... - - -@dataclass_like() -class B: - x: Desc[int] - y: Desc[str] - z: Desc[str] = Desc() - - -@dataclass -class C: - x: Desc[int] - y: Desc[str] - z: Desc[str] = Desc() - - -reveal_type(B.x, expected_text="A[int]") -reveal_type(B.y, expected_text="A[str]") -reveal_type(B.z, expected_text="A[str]") -reveal_type(C.x, expected_text="A[int]") -reveal_type(C.y, expected_text="A[str]") -reveal_type(C.z, expected_text="A[str]") - -b = B(Desc(), Desc(), Desc()) -reveal_type(b.x, expected_text="int") -reveal_type(b.y, expected_text="str") -reveal_type(b.z, expected_text="str") - -c = C(Desc(), Desc(), Desc()) -reveal_type(c.x, expected_text="int") -reveal_type(c.y, expected_text="str") -reveal_type(c.z, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/dataclassFrozen1.py b/packages/vipeye-internal/src/tests/samples/dataclassFrozen1.py deleted file mode 100644 index faa6817d..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassFrozen1.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the handling of frozen dataclass types. - -from dataclasses import dataclass -from typing import ClassVar - - -@dataclass(frozen=False) -class DC1: - val1: int = 6 - - -@dataclass(frozen=True) -class DC2: - val2: float = 4 - - -# This should generate an error because a frozen dataclass -# cannot inherit from a non-frozen dataclass. -@dataclass(frozen=True) -class DC3(DC1): - val3: int = 4 - - -@dataclass(frozen=True) -class DC4(DC2): - val4: int = 4 - - val5: ClassVar[int] - - -# This should generate an error because a non-frozen dataclass -# cannot inherit from a frozen dataclass. -@dataclass(frozen=False) -class DC5(DC2): - val4: int = 5 - - -a = DC1(val1=3) -a.val1 = 3 - -b = DC4(val2=3, val4=5) - -DC4.val5 = 3 - -# This should generate an error because the dataclass is frozen. -b.val2 = 3 - -# This should generate an error because the dataclass is frozen. -b.val4 = 3 - - -@dataclass(frozen=True) -class DC6(DC2): - val2: int = 6 diff --git a/packages/vipeye-internal/src/tests/samples/dataclassHash1.py b/packages/vipeye-internal/src/tests/samples/dataclassHash1.py deleted file mode 100644 index 18d741f0..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassHash1.py +++ /dev/null @@ -1,68 +0,0 @@ -# This sample tests the synthesis of the __hash__ method for dataclasses. - -from dataclasses import dataclass -from typing import Hashable - - -@dataclass -class DC1: - a: int - - -# This should generate an error. -v1: Hashable = DC1(0) - - -@dataclass(eq=True, frozen=True) -class DC2: - a: int - - -v2: Hashable = DC2(0) - - -@dataclass(eq=True) -class DC3: - a: int - - -# This should generate an error. -v3: Hashable = DC3(0) - - -@dataclass(frozen=True) -class DC4: - a: int - - -v4: Hashable = DC4(0) - - -@dataclass(eq=True, unsafe_hash=True) -class DC5: - a: int - - -v5: Hashable = DC5(0) - - -@dataclass(eq=True) -class DC6: - a: int - - def __hash__(self) -> int: - return 0 - - -v6: Hashable = DC6(0) - - -@dataclass(frozen=True) -class DC7: - a: int - - def __eq__(self, other) -> bool: - return self.a == other.a - - -v7: Hashable = DC7(0) diff --git a/packages/vipeye-internal/src/tests/samples/dataclassKwOnly1.py b/packages/vipeye-internal/src/tests/samples/dataclassKwOnly1.py deleted file mode 100644 index 27c93832..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassKwOnly1.py +++ /dev/null @@ -1,90 +0,0 @@ -# This sample tests the Python 3.10 additions to dataclass. - -from dataclasses import dataclass, KW_ONLY, field - - -@dataclass -class DC1: - a: str - _: KW_ONLY - b: int = 0 - - -DC1("hi") -DC1(a="hi") -DC1(a="hi", b=1) -DC1("hi", b=1) - -# This should generate an error because "b" is keyword-only. -DC1("hi", 1) - - -@dataclass -class DC2: - b: int = field(kw_only=True, default=3) - a: str - - -DC2("hi") -DC2(a="hi") -DC2(a="hi", b=1) -DC2("hi", b=1) - -# This should generate an error because "b" is keyword-only. -DC2("hi", 1) - - -@dataclass(kw_only=True) -class DC3: - a: str = field(kw_only=False) - b: int = 0 - - -DC3("hi") -DC3(a="hi") -DC3(a="hi", b=1) -DC3("hi", b=1) - -# This should generate an error because "b" is keyword-only. -DC3("hi", 1) - - -@dataclass -class DC4(DC3): - c: float - - -DC4("", 0.2, b=3) -DC4(a="", b=3, c=0.2) - - -# This tests that the KW_ONLY separator is recognized even when it -# is assigned to a name other than "_". -@dataclass -class DC5: - a: str - __: KW_ONLY - b: int = 0 - - -DC5("hi") -DC5(a="hi", b=1) -DC5("hi", b=1) - -# This should generate an error because "b" is keyword-only. -DC5("hi", 1) - - -# This tests that a duplicate KW_ONLY separator is flagged. CPython raises a -# TypeError at runtime if more than one KW_ONLY separator appears. -@dataclass -class DC6: - a: str - _: KW_ONLY - b: int = 0 - # This should generate an error because only one KW_ONLY separator is allowed. - __: KW_ONLY - c: int = 0 - - -DC6("hi", b=1, c=2) diff --git a/packages/vipeye-internal/src/tests/samples/dataclassKwOnly2.py b/packages/vipeye-internal/src/tests/samples/dataclassKwOnly2.py deleted file mode 100644 index 4cd7e7ec..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassKwOnly2.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests that KW_ONLY can be assigned to any variable name, -# not just `_`. Python docs state the name is ignored at runtime. -# See: https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY - -from dataclasses import KW_ONLY, dataclass - - -@dataclass -class DC1: - a: int - __: KW_ONLY - b: str - - -DC1(1, b="hi") -DC1(a=1, b="hi") - -# This should generate an error because "b" is keyword-only. -DC1(1, "hi") - - -@dataclass -class DC2: - a: int = 0 - __: KW_ONLY - b: str = "hi" - - -DC2(a=0, b="hi") -DC2(b="hi") - -# This should generate an error because "b" is keyword-only. -DC2(0, "hi") - - -@dataclass -class DC3: - a: int = 0 - kw_sep: KW_ONLY - b: str = "hi" - - -DC3(a=0, b="hi") -DC3(b="hi") - -# This should generate an error because "b" is keyword-only. -DC3(0, "hi") diff --git a/packages/vipeye-internal/src/tests/samples/dataclassNamedTuple1.py b/packages/vipeye-internal/src/tests/samples/dataclassNamedTuple1.py deleted file mode 100644 index 05683827..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassNamedTuple1.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample validates the Python 3.7 data class feature. - -from typing import ClassVar, Final, Hashable, NamedTuple - - -class Other: - pass - - -def standalone(obj: object) -> None: - print(obj) - - -class DataTuple(NamedTuple): - def _m(self): - pass - - id: int - aid: Other - value: str = "" - - # Unannotated variables should not be included. - not_annotated = 5 - - name: str | None = None - name2: str | None = None - - not_a_method = standalone - - -d1 = DataTuple(id=1, aid=Other(), name2="hi") -d1.not_a_method() - -d2 = DataTuple(id=1, aid=Other(), value="v") -d3 = DataTuple(id=1, aid=Other(), name="hello") -d4 = DataTuple(id=1, aid=Other(), name=None) -id = d1.id - -h4: Hashable = d4 -v = d3 == d4 - -# This should generate an error because the name argument -# is the incorrect type. -d5 = DataTuple(id=1, aid=Other(), name=3) - -# This should generate an error because aid is a required -# parameter and is missing an argument here. -d6 = DataTuple(id=1, name=None) - - -class DataTuple2(NamedTuple): - # This should generate an error because Final cannot - # be used in a NamedTuple. A second downstream error - # is also generated. - x: Final[int] - - # This should generate an error because Final cannot - # be used in a NamedTuple. - y: Final = 1 - - # This should generate an error because ClassVar cannot - # be used in a NamedTuple. - z: ClassVar[int] = 1 diff --git a/packages/vipeye-internal/src/tests/samples/dataclassNamedTuple2.py b/packages/vipeye-internal/src/tests/samples/dataclassNamedTuple2.py deleted file mode 100644 index f8829380..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassNamedTuple2.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample validates the Python 3.7 data class feature, ensuring that -# NamedTuple must be a direct base class. - -from typing import NamedTuple - - -class Parent(NamedTuple): - pass - - -class DataTuple2(Parent): - id: int - - -# This should generate an error because DataTuple2 isn't considered -# a data class and won't have the associated __new__ or __init__ -# method defined. -data = DataTuple2(id=1) diff --git a/packages/vipeye-internal/src/tests/samples/dataclassPostInit1.py b/packages/vipeye-internal/src/tests/samples/dataclassPostInit1.py deleted file mode 100644 index a89160e4..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassPostInit1.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the __post_init__ validation logic. - -# viper: reportIncompatibleMethodOverride=false - -from dataclasses import InitVar, dataclass, field -from typing import Iterable - - -@dataclass -class A: - a: InitVar[int] - b: InitVar[str] - c: InitVar[bool] - - def __post_init__(self, x: float, y: str, z: int, xx: int = 3) -> None: ... - - -@dataclass -class B: - items: list[int] - - # This should generate an error because the number of InitVars is zero. - def __post_init__(self, x: list[int]) -> None: ... - - -@dataclass -class C: - iterable: InitVar[Iterable[int]] - - items: list[int] = field(init=False) - - # This should generate an error because the number of InitVars is 1. - def __post_init__(self) -> None: ... - - -@dataclass -class D: - iterable: InitVar[Iterable[int]] - - # This should generate an error because the type is incompatible. - def __post_init__(self, iterable: Iterable[str]) -> None: ... - - -@dataclass -class E: - _name: InitVar[str] = field() - name: str = field(init=False) - - def __post_init__(self, _name: str): ... - - -@dataclass -class F(E): - _age: InitVar[int] = field() - age: int = field(init=False) - - def __post_init__(self, _name: str, _age: int): ... diff --git a/packages/vipeye-internal/src/tests/samples/dataclassReplace1.py b/packages/vipeye-internal/src/tests/samples/dataclassReplace1.py deleted file mode 100644 index ba93f95e..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassReplace1.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the synthesis of a "__replace__" method for dataclass -# classes in Python 3.13 and newer. - -from dataclasses import dataclass -from typing import NamedTuple - - -@dataclass -class DC1: - a: int - b: str - c: str = "" - - -dc1: DC1 = DC1(1, "") - -dc1_clone = dc1.__replace__(b="", a=1, c="") -reveal_type(dc1_clone, expected_text="DC1") - -dc1.__replace__(c="") -dc1.__replace__(b="2") - -# This should generate an error. -dc1.__replace__(b=2) - -# This should generate an error. -dc1.__replace__(d="") - - -class NT1(NamedTuple): - a: int - b: str - c: str = "" - - -nt1 = NT1(1, "") - -nt1_clone = nt1.__replace__(c="") -reveal_type(nt1_clone, expected_text="NT1") - -# This should generate an error. -nt1.__replace__(b=2) - -# This should generate an error. -nt1.__replace__(d="") diff --git a/packages/vipeye-internal/src/tests/samples/dataclassSlots1.py b/packages/vipeye-internal/src/tests/samples/dataclassSlots1.py deleted file mode 100644 index 520731e5..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassSlots1.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the "slots" parameter for dataclasses introduced -# in Python 3.10. - -from dataclasses import dataclass - - -# This should generate an error because __slots__ is already defined. -@dataclass(slots=True) -class A: - x: int - - __slots__ = () - - -@dataclass(slots=True) -class B: - x: int - - def __init__(self): - self.x = 3 - - # This should generate an error because "y" is not in slots. - self.y = 3 - - -@dataclass(slots=False) -class C: - x: int - - __slots__ = ("x",) - - def __init__(self): - self.x = 3 - - # This should generate an error because "y" is not in slots. - self.y = 3 - - -@dataclass -class D: - __slots__ = ("y", "x") - x: int - y: str - - -D(1, "bar") - - -@dataclass(slots=True) -class E: - a: int - - -E.__slots__ -E(1).__slots__ - -reveal_type(E.__slots__, expected_text="Iterable[str]") - - -@dataclass -class F: - a: int - - -# This should generate an error. -F.__slots__ - -# This should generate an error. -F(1).__slots__ diff --git a/packages/vipeye-internal/src/tests/samples/dataclassTransform1.py b/packages/vipeye-internal/src/tests/samples/dataclassTransform1.py deleted file mode 100644 index b308d377..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassTransform1.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests the handling of the dataclass_transform mechanism -# when applied to a decorator function. - -from typing import Any, Callable, TypeVar, overload -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - dataclass_transform, -) - -_T = TypeVar("_T") - - -@overload -@dataclass_transform(kw_only_default=True, order_default=True) -def create_model(cls: _T) -> _T: ... - - -@overload -@dataclass_transform(kw_only_default=True, order_default=True) -def create_model( - *, - frozen: bool = False, - kw_only: bool = True, - order: bool = True, -) -> Callable[[_T], _T]: ... - - -def create_model(*args: Any, **kwargs: Any) -> Any: ... - - -@create_model(kw_only=False, order=False) -class Customer1: - id: int - name: str - - -@create_model(frozen=True) -class Customer2: - id: int - name: str - - -@create_model(frozen=True) -class Customer2Subclass(Customer2): - salary: float - - -c1_1 = Customer1(id=3, name="Sue") -c1_1.id = 4 - -c1_2 = Customer1(3, "Sue") -c1_2.name = "Susan" - -# This should generate an error because of a type mismatch. -c1_2.name = 3 - -# This should generate an error because comparison methods are -# not synthesized. -v1 = c1_1 < c1_2 - -# This should generate an error because salary is not -# a defined field. -c1_3 = Customer1(id=3, name="Sue", salary=40000) - -c2_1 = Customer2(id=0, name="John") - -# This should generate an error because Customer2 supports -# keyword-only parameters for its constructor. -c2_2 = Customer2(0, "John") - -v2 = c2_1 < c2_2 - - -@dataclass_transform(kw_only_default=True, order_default=True, frozen_default=True) -def create_model_frozen(cls: _T) -> _T: ... - - -@create_model_frozen -class Customer3: - id: int - name: str - - -# This should generate an error because a non-frozen class -# cannot inherit from a frozen class. -@create_model -class Customer3Subclass(Customer3): - age: int - - -c3_1 = Customer3(id=2, name="hi") - -# This should generate an error because Customer3 is frozen. -c3_1.id = 4 diff --git a/packages/vipeye-internal/src/tests/samples/dataclassTransform2.py b/packages/vipeye-internal/src/tests/samples/dataclassTransform2.py deleted file mode 100644 index 75f76483..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassTransform2.py +++ /dev/null @@ -1,98 +0,0 @@ -# This sample tests the handling of the dataclass_transform mechanism -# when applied to a metaclass. - -from typing import Any, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - dataclass_transform, -) - -_T = TypeVar("_T") - - -class ModelField: - def __init__(self, *, init: bool = True, default: Any | None = None) -> None: ... - - -def model_field( - *, init: bool = True, default: Any | None = None, alias: str | None = None -) -> Any: ... - - -@dataclass_transform( - kw_only_default=True, - field_specifiers=(ModelField, model_field), -) -class ModelMeta(type): - not_a_field: str - - -class ModelBase(metaclass=ModelMeta): - def __init_subclass__( - cls, - *, - frozen: bool = False, - kw_only: bool = True, - order: bool = True, - ) -> None: ... - - -class Customer1(ModelBase, frozen=True): - id: int = model_field() - name: str = model_field() - name2: str = model_field(alias="other_name", default="None") - - -# This should generate an error because a non-frozen class cannot -# derive from a frozen one. -class Customer1Subclass(Customer1, frozen=False): - salary: float = model_field() - - -class Customer2(ModelBase, order=True): - id: int - name: str = model_field(default="None") - - -c1_1 = Customer1(id=3, name="Sue", other_name="Susan") - -# This should generate an error because the class is frozen. -c1_1.id = 4 - -# This should generate an error because the class is kw_only. -c1_2 = Customer1(3, "Sue") - -# This should generate an error because other_name is missing. -c1_3 = Customer1(id=3, name="John") - -# This should generate an error because comparison methods are -# not synthesized. -v1 = c1_1 < c1_2 - -c2_1 = Customer2(id=0, name="John") - -c2_2 = Customer2(id=1) - -v2 = c2_1 < c2_2 - -# This should generate an error because Customer2 supports -# keyword-only parameters for its constructor. -c2_3 = Customer2(0, "John") - - -@dataclass_transform(frozen_default=True) -class ModelMetaFrozen(type): - pass - - -class ModelBaseFrozen(metaclass=ModelMetaFrozen): ... - - -class Customer3(ModelBaseFrozen): - id: int - name: str - - -c3_1 = Customer3(id=2, name="hi") - -# This should generate an error because Customer3 is frozen. -c3_1.id = 4 diff --git a/packages/vipeye-internal/src/tests/samples/dataclassTransform3.py b/packages/vipeye-internal/src/tests/samples/dataclassTransform3.py deleted file mode 100644 index 6b72b366..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassTransform3.py +++ /dev/null @@ -1,125 +0,0 @@ -# This sample tests the handling of the dataclass_transform mechanism -# when applied to a class. - -from typing import Any, Callable, Generic, TypeVar - -_T = TypeVar("_T") - - -def __dataclass_transform__( - *, - eq_default: bool = True, - order_default: bool = False, - kw_only_default: bool = False, - frozen_default: bool = False, - field_specifiers: tuple[type | Callable[..., Any], ...] = (()), -) -> Callable[[_T], _T]: - return lambda a: a - - -class ModelField: - def __init__(self, *, init: bool = True, default: Any | None = None) -> None: ... - - -def model_field( - *, init: bool = True, default: Any | None = None, alias: str | None = None -) -> Any: ... - - -@__dataclass_transform__( - kw_only_default=True, - field_specifiers=(ModelField, model_field), -) -class ModelBase: - not_a_field: str - - def __init_subclass__( - cls, - *, - frozen: bool = False, - kw_only: bool = True, - order: bool = True, - ) -> None: ... - - -class Customer1(ModelBase, frozen=True): - id: int = model_field() - name: str = model_field() - name2: str = model_field(alias="other_name", default="None") - - -# This should generate an error because a non-frozen dataclass cannot -# derive from a frozen one. -class Customer1Subclass(Customer1): - salary: float = model_field() - - -class Customer2(ModelBase, order=True): - id: int - name: str = model_field(default="None") - - -c1_1 = Customer1(id=3, name="Sue", other_name="Susan") - -# This should generate an error because the class is frozen. -c1_1.id = 4 - -# This should generate an error because the class is kw_only. -c1_2 = Customer1(3, "Sue") - -c1_3 = Customer1(id=3, name="John") - -# This should generate an error because comparison methods are -# not synthesized. -v1 = c1_1 < c1_2 - -c2_1 = Customer2(id=0, name="John") - -c2_2 = Customer2(id=1) - -v2 = c2_1 < c2_2 - -# This should generate an error because Customer2 supports -# keyword-only parameters for its constructor. -c2_3 = Customer2(0, "John") - -_T = TypeVar("_T") - - -@__dataclass_transform__( - kw_only_default=True, - field_specifiers=(ModelField, model_field), -) -class GenericModelBase(Generic[_T]): - not_a_field: _T - - def __init_subclass__( - cls, - *, - frozen: bool = False, - kw_only: bool = True, - order: bool = True, - ) -> None: ... - - -class GenericCustomer(GenericModelBase[int]): - id: int = model_field() - - -gc_1 = GenericCustomer(id=3) - - -@__dataclass_transform__(frozen_default=True) -class ModelBaseFrozen: - not_a_field: str - - -class Customer3(ModelBaseFrozen): - id: int - name: str - - -c3_1 = Customer3(id=2, name="hi") - -# This should generate an error because Customer3 is frozen. -c3_1.id = 4 diff --git a/packages/vipeye-internal/src/tests/samples/dataclassTransform4.py b/packages/vipeye-internal/src/tests/samples/dataclassTransform4.py deleted file mode 100644 index d36f3797..00000000 --- a/packages/vipeye-internal/src/tests/samples/dataclassTransform4.py +++ /dev/null @@ -1,84 +0,0 @@ -# This sample tests the case where a field descriptor has an implicit -# "init" parameter type based on an overload. - -from typing import ( - Any, - Callable, - Literal, - TypeVar, - overload, -) - -T = TypeVar("T") - - -@overload -def field1( - *, - default: str | None = None, - resolver: Callable[[], Any], - init: Literal[False] = False, -) -> Any: ... - - -@overload -def field1( - *, - default: str | None = None, - resolver: None = None, - init: Literal[True] = True, -) -> Any: ... - - -def field1( - *, - default: str | None = None, - resolver: Callable[[], Any] | None = None, - init: bool = True, -) -> Any: ... - - -def field2(*, init=False, kw_only=True) -> Any: ... - - -def __dataclass_transform__( - *, - eq_default: bool = True, - order_default: bool = False, - kw_only_default: bool = False, - field_specifiers: tuple[type | Callable[..., Any], ...] = (()), -) -> Callable[[T], T]: - # If used within a stub file, the following implementation can be - # replaced with "...". - return lambda a: a - - -@__dataclass_transform__(kw_only_default=True, field_specifiers=(field1, field2)) -def create_model(*, init: bool = True) -> Callable[[type[T]], type[T]]: ... - - -@create_model() -class CustomerModel1: - id: int = field1(resolver=lambda: 0) - name: str = field1(default="Voldemort") - - -CustomerModel1() -CustomerModel1(name="hi") - -# This should generate an error because "id" is not -# supposed to be part of the init function. -CustomerModel1(id=1, name="hi") - - -@create_model() -class CustomerModel2: - id: int = field2() - name: str = field2(init=True) - - -# This should generate an error because kw_only is True -# by default for field2. -CustomerModel2(1) - -CustomerModel2(name="Fred") diff --git a/packages/vipeye-internal/src/tests/samples/decorator1.py b/packages/vipeye-internal/src/tests/samples/decorator1.py deleted file mode 100644 index 3de75291..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator1.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the a class-based decorator that uses a -# __get__ method as a way to provide access to a __call__ method. - -# viper: reportIncompatibleMethodOverride=false - - -class Wrapper: - def __init__(self, func): - self.func = func - - def __get__(self, instance, owner): - return lambda **kwargs: self.func(instance, wrapped=True, **kwargs) - - -class Foo: - @Wrapper - def __init__(self, **kwargs): - print(f"{kwargs}") - - -Foo(bar=3) diff --git a/packages/vipeye-internal/src/tests/samples/decorator2.py b/packages/vipeye-internal/src/tests/samples/decorator2.py deleted file mode 100644 index 0d76d988..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator2.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the usage of overloads in decorators. - -from typing import Callable, TypeVar, overload, Optional, Union - -F = TypeVar("F", bound=Callable[[], None]) - - -@overload -def atomic(__func: F) -> F: ... - - -@overload -def atomic(*, savepoint: bool = True) -> Callable[[F], F]: ... - - -def atomic( - __func: Optional[Callable[..., None]] = None, *, savepoint: bool = True -) -> Union[Callable[[], None], Callable[[F], F]]: ... - - -@atomic -def func1() -> None: ... - - -@atomic(savepoint=False) -def func2() -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/decorator3.py b/packages/vipeye-internal/src/tests/samples/decorator3.py deleted file mode 100644 index 4050d6b1..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator3.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests that arbitrary expressions (including -# subscripts) work for decorators. This support was added -# in Python 3.9. - -my_decorators = (staticmethod, classmethod, property) - - -class Foo: - # This should generate an error if version < 3.9. - @my_decorators[0] - def my_static_method(): - return 3 - - # This should generate an error if version < 3.9. - @my_decorators[1] - def my_class_method(cls): - return 3 - - # This should generate an error if version < 3.9. - @my_decorators[2] - def my_property(self): - return 3 - - -Foo.my_static_method() -Foo.my_class_method() -Foo().my_property diff --git a/packages/vipeye-internal/src/tests/samples/decorator4.py b/packages/vipeye-internal/src/tests/samples/decorator4.py deleted file mode 100644 index c3c1edcd..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator4.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests whether a decorator that contains an unknown -# type is ignored and treated as though it wasn't applied. - -# viper: reportMissingImports=false - -import my_module - - -class Class2: - pass - - -def decorator1(fn): - # This decorator returns a value that is - # inferred to be a union containing an Unknown type. - if fn: - return my_module.unknown - return Class2 - - -@decorator1 -class ClassA: - def __init__(self, a, b, c): - pass - - -v1 = ClassA(1, 2, 3) -reveal_type(v1, expected_text="ClassA") - - -@decorator1 -def func1() -> int: - return 3 - - -v2 = func1() -reveal_type(v2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/decorator5.py b/packages/vipeye-internal/src/tests/samples/decorator5.py deleted file mode 100644 index 3bf309cd..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator5.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the logic that determines whether -# an unannotated decorator should allow the decorated -# function type (and docstring) to pass through unmodified. - - -def decorator1(method): - def wrapper(*args, **kw): - result = method(*args, **kw) - return result - - return wrapper - - -@decorator1 -def func1(var: str, kvar: str): - return - - -reveal_type(func1, expected_text="(var: str, kvar: str) -> None") - - -class ClassA: - @decorator1 - def method1(self, var: str, kvar: str): - return - - -reveal_type(ClassA().method1, expected_text="(var: str, kvar: str) -> None") -reveal_type(ClassA.method1, expected_text="(self: ClassA, var: str, kvar: str) -> None") diff --git a/packages/vipeye-internal/src/tests/samples/decorator6.py b/packages/vipeye-internal/src/tests/samples/decorator6.py deleted file mode 100644 index a41d300d..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator6.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests that function decorators can be combined with -# staticmethod or classmethod. - -from typing import Callable, TypeVar -import functools - -_T = TypeVar("_T") - - -def decorator1(func: Callable[[_T, str], None]) -> Callable[[_T, str], None]: - @functools.wraps(func) - def func_wrapper(param1: _T, param2: str) -> None: - return func(param1, param2) - - return func_wrapper - - -class ClassA: - def __init__(self): - self.test1(1, "a") - self.test2("hi") - - @staticmethod - @decorator1 - def test1(param1: int, param2: str) -> None: - print(param2) - - @classmethod - @decorator1 - def test2(cls, param2: str) -> None: - print(param2) - - -ClassA() diff --git a/packages/vipeye-internal/src/tests/samples/decorator7.py b/packages/vipeye-internal/src/tests/samples/decorator7.py deleted file mode 100644 index 32492022..00000000 --- a/packages/vipeye-internal/src/tests/samples/decorator7.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a class decorator needs to evaluate -# the type of __init__ prior to the class being fully evaluated. - -from typing import Any, Callable, Generic, TypeVar - -T = TypeVar("T") -FuncType = Callable[..., Any] -FT = TypeVar("FT", bound=FuncType) - - -def decorate() -> Callable[[FT], FT]: ... - - -@decorate() -class ValueDecorated(Generic[T]): - def __init__(self, value: T) -> None: - self._value: T = value - - def __call__(self) -> T: - return self._value diff --git a/packages/vipeye-internal/src/tests/samples/defaultInitializer1.py b/packages/vipeye-internal/src/tests/samples/defaultInitializer1.py deleted file mode 100644 index 6de9a4dd..00000000 --- a/packages/vipeye-internal/src/tests/samples/defaultInitializer1.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the type analyzer's reporting of issues -# with parameter default initializer expressions. This is -# covered by the reportCallInDefaultInitializer diagnostic rule. - - -def func1( - a=None, - # This should generate an error - b=dict(), - # This should generate an error - c=max(3, 4), -): - return 3 - - -def func2( - a=None, - # This should generate an error - b={}, - # This should generate an error - c=[], - # This should generate an error - d={1, 2, 3}, - e=(1, 2, 3), -): - return 3 diff --git a/packages/vipeye-internal/src/tests/samples/del1.py b/packages/vipeye-internal/src/tests/samples/del1.py deleted file mode 100644 index 79d08fdd..00000000 --- a/packages/vipeye-internal/src/tests/samples/del1.py +++ /dev/null @@ -1,68 +0,0 @@ -# This sample tests del statements. - -# This should generate two errors because x1 and x2 are not defined. -del x1, x2 - -x1 = 1 -del x1 - -# This should generate an error because x1 isn't defined. -del x1 - - -def func1(y1: int): - # This should generate an error because y2 is unbound. - del y1, y2 - - # This should generate an error because y1 is unbound. - del y1 - - y2 = 1 - del y2 - - -class ClassA: - # This should generate an error because z1 is unbound. - del z1 - - z1 = 1 - del z1 - - -class ClassB: - x: int - - -b = ClassB() -b.x = 3 -reveal_type(b.x, expected_text="Literal[3]") -del b.x -reveal_type(b.x, expected_text="int") - -x2: list[str | int] = ["a", 1, "b", 2] -reveal_type(x2[0], expected_text="str | int") -x2[0] = 0 -reveal_type(x2[0], expected_text="Literal[0]") -reveal_type(x2[1], expected_text="str | int") -del x2[0] -reveal_type(x2[0], expected_text="str | int") - - -class ClassC: - @property - def x(self) -> str: ... - - @x.setter - def x(self, value: str) -> None: ... - - @x.deleter - def x(self) -> None: ... - - -c = ClassC() -c.x = "x" - -reveal_type(c.x, expected_text="Literal['x']") - -del c.x -reveal_type(c.x, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/del2.py b/packages/vipeye-internal/src/tests/samples/del2.py deleted file mode 100644 index f8759f0c..00000000 --- a/packages/vipeye-internal/src/tests/samples/del2.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests that the type analyzer flags as an error -# an attempt to assign to or delete a generic type. - -from typing import Dict - -# This should generate an error because assignment -# of generic types isn't allowed. -Dict[str, int] = {} - -# This should generate an error because deletion -# of generic types isn't allowed. -del Dict[str, int] diff --git a/packages/vipeye-internal/src/tests/samples/deprecated2.py b/packages/vipeye-internal/src/tests/samples/deprecated2.py deleted file mode 100644 index 0182004c..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated2.py +++ /dev/null @@ -1,175 +0,0 @@ -# This sample tests the @warning.deprecated decorator introduced in PEP 702. - -from contextlib import contextmanager -from typing import Any, Callable, Self, TypeVar - -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - deprecated, - overload, -) - - -@deprecated("Use ClassB instead") -class ClassA: ... - - -# This should generate an error if reportDeprecated is enabled. -ClassA() - - -class ClassC: - @deprecated("Don't temp me") - def method1(self) -> None: ... - - @overload - @deprecated("Int is no longer supported") - def method2(self, a: int) -> None: ... - - @overload - def method2(self, a: None = None) -> None: ... - - def method2(self, a: int | None = None) -> None: ... - - -c1 = ClassC() - -# This should generate an error if reportDeprecated is enabled. -c1.method1() - -c1.method2() - -# This should generate an error if reportDeprecated is enabled. -c1.method2(2) - - -@deprecated("Test") -def func1() -> None: ... - - -# This should generate an error if reportDeprecated is enabled. -func1() - - -@overload -def func2(a: str) -> None: ... - - -@overload -@deprecated("int no longer supported") -def func2(a: int) -> int: ... - - -def func2(a: str | int) -> int | None: ... - - -func2("hi") - -# This should generate an error if reportDeprecated is enabled. -func2(3) - - -class ClassD: - @overload - def __init__(self, x: int) -> None: ... - - @overload - @deprecated("str no longer supported") - def __init__(self, x: str) -> None: ... - - def __init__(self, x: int | str) -> None: ... - - -ClassD(3) - -# This should generate an error if reportDeprecated is enabled. -ClassD("") - - -class ClassE: - @overload - def __new__(cls, x: int) -> Self: ... - - @overload - @deprecated("str no longer supported") - def __new__(cls, x: str) -> Self: ... - - def __new__(cls, x: int | str) -> Self: ... - - -ClassE(3) - -# This should generate an error if reportDeprecated is enabled. -ClassE("") - - -@deprecated("Deprecated async function") -async def func3(): ... - - -async def func4(): - # This should generate an error if reportDeprecated is enabled. - await func3() - - -@overload -def func5(val: int): ... - - -@overload -def func5(val: str): ... - - -@deprecated("All overloads are deprecated") -def func5(val: object): ... - - -# This should generate an error if reportDeprecated is enabled. -func5(1) - -# This should generate an error if reportDeprecated is enabled. -func5("") - -# This should generate an error if reportDeprecated is enabled. -v1 = func5 - - -T = TypeVar("T", bound=Callable[..., Any]) - - -@deprecated("Use different decorator") -@overload -def deco1(value: T) -> T: ... - - -@overload -def deco1(value: str): ... - - -def deco1(value: object) -> object: ... - - -# This should generate an error if reportDeprecated is enabled. -@deco1 -def func6(): ... - - -@contextmanager -@deprecated("Func is deprecated") -def func7(): - yield - - -# This should generate an error if reportDeprecated is enabled. -with func7(): - ... - - -@deprecated("Func is deprecated") -@contextmanager -def func8(): - yield - - -# This should generate an error if reportDeprecated is enabled. -with func8(): - ... diff --git a/packages/vipeye-internal/src/tests/samples/deprecated3.py b/packages/vipeye-internal/src/tests/samples/deprecated3.py deleted file mode 100644 index f5aab774..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated3.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the @warning.deprecated decorator introduced in PEP 702. - -# This should generate an error if reportDeprecated is enabled. -from .deprecated2 import func1 - -# This should generate an error if reportDeprecated is enabled. -from .deprecated2 import ClassA as A - -from .deprecated2 import func2 -from .deprecated2 import ClassC as C - -func2("hi") - -# This should generate an error if reportDeprecated is enabled. -func2(1) - -# This should generate an error if reportDeprecated is enabled. -c1 = C.method1 - - -c2 = C() -c2.method2() - -# This should generate an error if reportDeprecated is enabled. -c2.method2(3) diff --git a/packages/vipeye-internal/src/tests/samples/deprecated4.py b/packages/vipeye-internal/src/tests/samples/deprecated4.py deleted file mode 100644 index 53a02f2b..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated4.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests the handling of deprecated properties and decorators. - -from typing import overload - -from typing_extensions import deprecated # viper: ignore[reportMissingModuleSource] - - -class A: - @property - @deprecated("Deprecated v1 getter") - def v1(self) -> str: - return "" - - @v1.setter - def v1(self, value: str) -> None: ... - - @v1.deleter - def v1(self) -> None: ... - - @property - def v2(self) -> str: - return "" - - @deprecated("Deprecated v2 setter") - @v2.setter - def v2(self, value: str) -> None: ... - - @v2.deleter - @deprecated("Deprecated v2 deleter") - def v2(self) -> None: ... - - -a = A() - -# This should generate an error if reportDeprecated is enabled. -v1 = a.v1 - -a.v1 = "" -del a.v1 - - -v2 = a.v2 - -# This should generate an error if reportDeprecated is enabled. -a.v2 = "" - -# This should generate an error if reportDeprecated is enabled. -a.v2 += "" - -# This should generate an error if reportDeprecated is enabled. -del a.v2 - - -class DescB1: - @overload - @deprecated("DescB1 __get__") - def __get__(self, obj: None, owner: object) -> str: ... - - @overload - def __get__(self, obj: object, owner: object) -> str: ... - - def __get__(self, obj: object | None, owner: object) -> str: - return "" - - -class DescB2: - def __get__(self, obj: object | None, owner: object) -> str: - return "" - - @deprecated("DescB2 __set__") - def __set__(self, obj: object | None, value: str) -> None: ... - - @deprecated("DescB2 __delete__") - def __delete__(self, obj: object | None) -> None: ... - - -class B: - b1: DescB1 = DescB1() - b2: DescB2 = DescB2() - - -# This should generate an error if reportDeprecated is enabled. -v3 = B.b1 - -b = B() -v4 = b.b1 - - -# This should generate an error if reportDeprecated is enabled. -b.b2 = "" - -# This should generate an error if reportDeprecated is enabled. -del b.b2 diff --git a/packages/vipeye-internal/src/tests/samples/deprecated5.py b/packages/vipeye-internal/src/tests/samples/deprecated5.py deleted file mode 100644 index a9579e9e..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated5.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the deprecation messages for class properties. - - -class A: - @classmethod - @property - # This should generate an error if reportDeprecated is enabled. - def prop1(cls) -> int: - return 1 - - @classmethod - @prop1.setter - # This should generate an error if reportDeprecated is enabled. - def prop1(cls, value: int) -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/deprecated6.py b/packages/vipeye-internal/src/tests/samples/deprecated6.py deleted file mode 100644 index 31caa08f..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated6.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the case where a __call__ is marked deprecated. - -from typing import Callable, Generic, ParamSpec, TypeVar -from typing_extensions import deprecated # viper: ignore[reportMissingModuleSource] - - -class A: - @deprecated("Use ClassB instead") - def __call__(self) -> None: ... - - -a = A() - -# This should generate an error if reportDeprecated is enabled. -a() - -P = ParamSpec("P") -R = TypeVar("R") - - -class B(Generic[P, R]): - def __init__(self, cb: Callable[P, R]) -> None: - self.cb = cb - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: - return self.cb(*args, **kwargs) - - -@B -@deprecated("Don't use this.") -def func1(x: int) -> None: - pass - - -# This should generate an error if reportDeprecated is enabled. -func1(3) - - -def deco1(cb: Callable[P, R]) -> B[P, R]: - return B(cb) - - -@deco1 -@deprecated("Don't use this.") -def func2(x: int) -> None: - pass - - -# This should generate an error if reportDeprecated is enabled. -func2(3) diff --git a/packages/vipeye-internal/src/tests/samples/deprecated7.py b/packages/vipeye-internal/src/tests/samples/deprecated7.py deleted file mode 100644 index c28461da..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated7.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the case where a "deprecated" instance is instantiated -# prior to being used as a decorator. - -# viper: reportMissingModuleSource=false - -from typing_extensions import deprecated - - -todo = deprecated("This needs to be implemented!!") - - -@todo -class ClassA: ... - - -# This should generate an error if reportDeprecated is enabled. -ClassA() - - -@todo -def func1() -> None: - pass - - -# This should generate an error if reportDeprecated is enabled. -func1() - - -def func2() -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/deprecated8.py b/packages/vipeye-internal/src/tests/samples/deprecated8.py deleted file mode 100644 index d2670e95..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecated8.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests reporting of deprecated magic methods. - -# viper: reportMissingModuleSource=false - -from typing import Self, overload - -from typing_extensions import deprecated - - -class ClassA: - @deprecated("Adding a str is deprecated") - @overload - def __add__(self, other: str) -> Self: ... - - @overload - def __add__(self, other: object) -> Self: ... - - def __add__(self, other: object) -> Self: ... - - @deprecated("Bool is not supported") - def __bool__(self) -> bool: ... - - @deprecated("Negation is no longer supported") - def __neg__(self) -> Self: ... - - -a = ClassA() - -v1 = a + 1 - -# This should be marked as deprecated. -v2 = a + "" - -a += 1 - -# This should be marked as deprecated. -a += "" - - -# This should be marked as deprecated. -v3 = -a - -# This should be marked as deprecated. -v4 = not a diff --git a/packages/vipeye-internal/src/tests/samples/deprecatedAlias1.py b/packages/vipeye-internal/src/tests/samples/deprecatedAlias1.py deleted file mode 100644 index 3c221348..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecatedAlias1.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests the detection of deprecated classes from the typing -# module. - -from typing import ( - ChainMap as CM1, - Counter as CT1, - DefaultDict, - Deque, - Dict, - FrozenSet, - List, - Optional, - OrderedDict as OD1, - Set, - Tuple, - Type, - Union, - Awaitable, - Coroutine, - AsyncIterable, - AsyncGenerator, - Iterable, - Iterator, - Generator, - Reversible, - Container, - Collection as C1, - Callable, - AbstractSet, - MutableSet, - Mapping, - MutableMapping, - Sequence, - MutableSequence, - ByteString as BS1, - MappingView, - KeysView, - ItemsView, - ValuesView, - ContextManager as CM1, - AsyncContextManager, - Pattern as P1, - Match as M1, -) - -from collections.abc import Collection, ByteString, Set as AS -from contextlib import AbstractContextManager -from re import Pattern, Match - -# These should be marked deprecated for Python >= 3.9 -v1: List[int] = [1, 2, 3] -v2: Dict[int, str] = {} -v3: Set[int] = set() -v4: Tuple[int] = (3,) -v5: FrozenSet[int] = frozenset() -v6: Type[int] = int -v7 = Deque() -v8 = DefaultDict() - -# These should be marked deprecated for Python >= 3.10 -v20: Union[int, str] -v21: Optional[int] diff --git a/packages/vipeye-internal/src/tests/samples/deprecatedAlias2.py b/packages/vipeye-internal/src/tests/samples/deprecatedAlias2.py deleted file mode 100644 index 43cf2a25..00000000 --- a/packages/vipeye-internal/src/tests/samples/deprecatedAlias2.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests the detection of deprecated classes from the -# typing_extensions module. - -# This test is heavily derived from deprecatedAlias1.py. - -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - ChainMap as CM1, - Counter as CT1, - DefaultDict, - Deque, - Dict, - FrozenSet, - List, - Optional, - OrderedDict as OD1, - Set, - Tuple, - Type, - Union, - Awaitable, - Coroutine, - AsyncIterable, - AsyncGenerator, - Iterable, - Iterator, - Generator, - Reversible, - Container, - Collection as C1, - Callable, - AbstractSet, - MutableSet, - Mapping, - MutableMapping, - Sequence, - MutableSequence, - # ByteString as BS1, # This symbol doesn't exist in typing_extensions - MappingView, - KeysView, - ItemsView, - ValuesView, - ContextManager as CM1, # This symbol is reexported from contextlib - AsyncContextManager, # This symbol is reexported from contextlib - Pattern as P1, - Match as M1, -) - -from collections.abc import Collection, ByteString, Set as AS -from contextlib import AbstractContextManager -from re import Pattern, Match - -# These should be marked deprecated for Python >= 3.9 -v1: List[int] = [1, 2, 3] -v2: Dict[int, str] = {} -v3: Set[int] = set() -v4: Tuple[int] = (3,) -v5: FrozenSet[int] = frozenset() -v6: Type[int] = int -v7 = Deque() -v8 = DefaultDict() - -# These should be marked deprecated for Python >= 3.10 -v20: Union[int, str] -v21: Optional[int] diff --git a/packages/vipeye-internal/src/tests/samples/descriptor1.py b/packages/vipeye-internal/src/tests/samples/descriptor1.py deleted file mode 100644 index 564473c1..00000000 --- a/packages/vipeye-internal/src/tests/samples/descriptor1.py +++ /dev/null @@ -1,165 +0,0 @@ -# This sample tests the detection and handling of asymmetric descriptors -# and properties. Type narrowing should be disabled in these cases. - -from typing import Any, Hashable, Iterable, Literal, Self, overload - - -class A: - @property - def prop1(self) -> int | None: ... - - @prop1.setter - def prop1(self, val: int | None) -> None: ... - - @property - def prop2(self) -> int | None: ... - - @prop2.setter - def prop2(self, val: int) -> None: ... - - @prop2.deleter - def prop2(self) -> None: ... - - @property - def prop3(self) -> int: ... - - @prop3.setter - def prop3(self, val: int | None) -> None: ... - - @prop3.deleter - def prop3(self) -> None: ... - - -def func1(obj: A) -> Literal[3]: - obj.prop1 = None - - b: None = obj.prop1 - - obj.prop1 = 3 - - v1 = obj.prop1 + 1 - return obj.prop1 - - -def func2(obj: A) -> Literal[3]: - obj.prop2 = 3 - - # This should generate an error because prop2 isn't - # narrowed in this case. - b: int = obj.prop2 - - # This should generate an error because prop2 isn't - # narrowed in this case. - return obj.prop2 - - -def func3(obj: A) -> Literal[3]: - obj.prop3 = 3 - - b: int = obj.prop3 - - # This should generate an error because prop2 isn't - # narrowed in this case. - return obj.prop3 - - -class Descriptor1: - def __get__(self, instance: Any, owner: Any) -> int | None: ... - - def __set__(self, owner: Any, value: int | None) -> None: ... - - -class Descriptor2: - def __get__(self, instance: Any, owner: Any) -> int | None: ... - - def __set__(self, owner: Any, value: int) -> None: ... - - -class Descriptor3: - def __get__(self, instance: Any, owner: Any) -> int: ... - - def __set__(self, owner: Any, value: int | None) -> None: ... - - -class Descriptor4: - @overload - def __get__(self, instance: None, owner: Any) -> int: ... - @overload - def __get__(self, instance: Any, owner: Any) -> str: ... - def __get__(self, instance: Any, owner: Any) -> int | str: ... - - def __set__(self, owner: Any, value: int | None) -> None: ... - - -class Descriptor5: - def __get__(self, instance: Any, owner: Any) -> int: ... - - @overload - def __set__(self, owner: bytes, value: int | None) -> None: ... - @overload - def __set__(self, owner: "B", value: int | None) -> None: ... - def __set__(self, owner: Any, value: int | None) -> None: ... - - -class Descriptor6[GT, ST]: - @overload - def __get__(self, instance: None, owner: Any) -> Self: ... - - @overload - def __get__(self, instance: Any, owner: Any) -> GT: ... - def __get__(self, instance: Any, owner: Any) -> Any: ... - - def __set__(self, instance: Any, value: ST): ... - - -class B: - desc1: Descriptor1 - desc2: Descriptor2 - desc3: Descriptor3 - desc4: Descriptor4 - desc5: Descriptor5 - desc6: Descriptor6[int | None, int | None] - - -def func4(obj: B) -> Literal[3]: - obj.desc1 = None - - b: None = obj.desc1 - - obj.desc1 = 3 - - v1 = obj.desc1 + 1 - return obj.desc1 - - -def func5(obj: B) -> Literal[3]: - obj.desc2 = 3 - - # This should generate an error because desc2 isn't - # narrowed in this case. - b: int = obj.desc2 - - # This should generate an error because desc2 isn't - # narrowed in this case. - return obj.desc2 - - -def func6(obj: B) -> Literal[3]: - obj.desc3 = 3 - - b: int = obj.desc3 - - # This should generate an error because prop2 isn't - # narrowed in this case. - return obj.desc3 - - -def func7(obj: B): - obj.desc4 = 3 - reveal_type(obj.desc4, expected_text="str") - - obj.desc5 = 3 - reveal_type(obj.desc5, expected_text="int") - - obj.desc6 = 1 - reveal_type(obj.desc6, expected_text="Literal[1]") diff --git a/packages/vipeye-internal/src/tests/samples/descriptor2.py b/packages/vipeye-internal/src/tests/samples/descriptor2.py deleted file mode 100644 index b5702a9f..00000000 --- a/packages/vipeye-internal/src/tests/samples/descriptor2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample validates that a member's descriptor protocol is -# accessed via a member access expression only when accessing it -# through a class variable, not through an instance variable. - -from typing import Any - - -class Descriptor: - def __get__(self, obj: Any, objtype: Any = None) -> float: - return 1.0 - - -class ClassA: - x: Descriptor - - def __init__(self, x: Descriptor): - reveal_type(self.x, expected_type="float") - - def func1(self): - reveal_type(self.x, expected_type="float") - - -class ClassB: - def __init__(self, x: Descriptor): - self.x = x - reveal_type(self.x, expected_type="Descriptor") - - def func1(self): - reveal_type(self.x, expected_type="Descriptor") diff --git a/packages/vipeye-internal/src/tests/samples/descriptor3.py b/packages/vipeye-internal/src/tests/samples/descriptor3.py deleted file mode 100644 index 0ae13b46..00000000 --- a/packages/vipeye-internal/src/tests/samples/descriptor3.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests that bidirectional type inference works when -# assigning to a class-scoped variable that is annotated with a -# descriptor. The setter type should not be used in this case. - - -from typing import Callable, Generic, TypeVar - - -T = TypeVar("T") - - -class Desc1(Generic[T]): - def __get__( - self, instance: object | None, owner: type | None = None - ) -> list[T]: ... - - def __set__(self, instance: object, value: list[T]) -> None: ... - - -def func1(factory: Callable[[], list[T]]) -> Desc1[T]: ... - - -class ClassA: - not_working: Desc1[int] = func1(list) diff --git a/packages/vipeye-internal/src/tests/samples/descriptor4.py b/packages/vipeye-internal/src/tests/samples/descriptor4.py deleted file mode 100644 index 0c62f9ea..00000000 --- a/packages/vipeye-internal/src/tests/samples/descriptor4.py +++ /dev/null @@ -1,67 +0,0 @@ -# This sample tests type narrowing when a descriptor is accessed -# through a subclass. The type of the instance should not be narrowed -# to Never after an assertion involving the descriptor value. - -import typing - -T = typing.TypeVar("T", bound=typing.Any) - - -class SQLCoreOperations(typing.Generic[T]): - pass - - -class ORMDescriptor(typing.Generic[T]): - @typing.overload - def __get__( - self, instance: typing.Any, owner: typing.Literal[None] - ) -> "ORMDescriptor[T]": ... - - @typing.overload - def __get__( - self, instance: typing.Literal[None], owner: typing.Any - ) -> SQLCoreOperations[T]: ... - - @typing.overload - def __get__(self, instance: object, owner: typing.Any) -> T: ... - - def __get__( - self, instance: object, owner: typing.Any - ) -> "typing.Union[ORMDescriptor[T], SQLCoreOperations[T], T]": ... - - -class MappedColumn(ORMDescriptor[T]): - pass - - -class User: - email: MappedColumn[str | None] - - -u = User() -reveal_type(u, expected_text="User") -reveal_type(u.email, expected_text="str | None") -assert u.email is None -reveal_type(u, expected_text="User") # Should remain "User", not "Never" - - -# Test with direct descriptor type as well -class User2: - email2: ORMDescriptor[str | None] - - -u2 = User2() -reveal_type(u2, expected_text="User2") -reveal_type(u2.email2, expected_text="str | None") -assert u2.email2 is None -reveal_type(u2, expected_text="User2") # Should remain "User2", not "Never" - - -# Test negative case (is not None) -def func1(u3: User): - if u3.email is not None: - reveal_type(u3, expected_text="User") - reveal_type(u3.email, expected_text="str") - else: - reveal_type(u3, expected_text="User") - reveal_type(u3.email, expected_text="None") diff --git a/packages/vipeye-internal/src/tests/samples/dictionary1.py b/packages/vipeye-internal/src/tests/samples/dictionary1.py deleted file mode 100644 index 0258d191..00000000 --- a/packages/vipeye-internal/src/tests/samples/dictionary1.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the type checker's type inference logic for -# dictionaries. - -from typing import Any, Callable, Literal, Sequence - - -def wants_int_dict(a: dict[int, int]): - pass - - -wants_int_dict({3: 3, 5: 5}) -wants_int_dict({x: x for x in [2, 3, 4]}) - -# This should generate an error because -# the type is wrong. -wants_int_dict({"hello": 3, "bye": 5}) - -# This should generate an error because -# the type is wrong. -wants_int_dict({"sdf": x for x in [2, 3, 4]}) - -t1 = () - -# This should generate an error because t1 is not a mapping. -d1 = {**t1} - -d2 = {"hi": 3} -d3 = {**d2, "": 4} -reveal_type(d3, expected_text="dict[str, int]") - - -LitChoices = Literal["ab", "bcd"] - -keys: list[LitChoices] = ["ab", "bcd"] -d4: dict[LitChoices, int] = {k: len(k) for k in keys} - - -d5: dict[str, Callable[[Sequence[Any]], float]] = { - "min": min, - "max": max, - "sum": sum, -} - -LiteralDict = dict[LitChoices, str] - -d6: LiteralDict = {"ab": "x"} -d7: LiteralDict = {"bcd": "y"} -d6 = {**d6, **d7} -d6 = d6 | d7 - - -def func1(args): - d1 = {**args, "x": 123} - reveal_type(d1, expected_text="dict[Unknown, Unknown]") - - -# diff --git a/packages/vipeye-internal/src/tests/samples/dictionary2.py b/packages/vipeye-internal/src/tests/samples/dictionary2.py deleted file mode 100644 index 5d668ca6..00000000 --- a/packages/vipeye-internal/src/tests/samples/dictionary2.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests dictionary inference logic. - -from typing import Mapping, TypeAlias, TypeVar - -T = TypeVar("T") - - -def func1(mapping: Mapping[str | bytes, int]): - return mapping - - -func1({"x": 1}) -func1({b"x": 1}) - -# This should generate an error. -func1({3: 1}) - - -RecursiveMapping: TypeAlias = ( - int | Mapping[int, "RecursiveMapping"] | Mapping[str, "RecursiveMapping"] -) - - -class HasName: - name: str | None - - -def func2(x: T | None) -> T: - assert x is not None - return x - - -def func3(v: list[HasName]) -> RecursiveMapping: - return {func2(x.name): 1 for x in v} diff --git a/packages/vipeye-internal/src/tests/samples/dictionary3.py b/packages/vipeye-internal/src/tests/samples/dictionary3.py deleted file mode 100644 index fe1067de..00000000 --- a/packages/vipeye-internal/src/tests/samples/dictionary3.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests various dictionary diagnostics. - -from typing import Generic, Mapping, TypeVar - -t1 = () - -# This should generate an error because t1 is not a mapping. -d1 = {**t1} - - -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") - - -def func1(m: Mapping[str, int] | Mapping[str, str]): - d1 = {**m} - reveal_type(d1, expected_text="dict[str, int | str]") - - -class MyMapping(Generic[_KT, _VT]): - def keys(self) -> list[_KT]: - raise NotImplementedError - - def __getitem__(self, key: _KT) -> _VT: - raise NotImplementedError - - -def func2(m: MyMapping[str, int] | MyMapping[str, str]): - d1 = {**m} - reveal_type(d1, expected_text="dict[str, int | str]") diff --git a/packages/vipeye-internal/src/tests/samples/dictionary4.py b/packages/vipeye-internal/src/tests/samples/dictionary4.py deleted file mode 100644 index 55cb3078..00000000 --- a/packages/vipeye-internal/src/tests/samples/dictionary4.py +++ /dev/null @@ -1,106 +0,0 @@ -# This sample tests a relatively expensive dictionary type evaluation -# case. It is included to ensure that the performance of this case -# is reasonable and doesn't regress. - -CONFIG: dict[str, list] = { - "0": [], - "1": [()], - "2": [(), ("2",)], - "3": [(), ("3",), ("3", 3)], - "4": [(), ("4",), ("4", 4), ()], - "5": [(), ("5",), ("5", 5), (), ("5",)], - "6": [(), ("6",), ("6", 6), (), ("6",), ("6", 6)], - "7": [], - "8": [()], - "9": [(), ("9",)], - "10": [(), ("10",), ("10", 10)], - "11": [(), ("11",), ("11", 11), ()], - "12": [(), ("12",), ("12", 12), (), ("12",)], - "13": [(), ("13",), ("13", 13), (), ("13",), ("13", 13)], - "14": [], - "15": [()], - "16": [(), ("16",)], - "17": [(), ("17",), ("17", 17)], - "18": [(), ("18",), ("18", 18), ()], - "19": [(), ("19",), ("19", 19), (), ("19",)], - "20": [(), ("20",), ("20", 20), (), ("20",), ("20", 20)], - "21": [], - "22": [()], - "23": [(), ("23",)], - "24": [(), ("24",), ("24", 24)], - "25": [(), ("25",), ("25", 25), ()], - "26": [(), ("26",), ("26", 26), (), ("26",)], - "27": [(), ("27",), ("27", 27), (), ("27",), ("27", 27)], - "28": [], - "29": [()], - "30": [(), ("30",)], - "31": [(), ("31",), ("31", 31)], - "32": [(), ("32",), ("32", 32), ()], - "33": [(), ("33",), ("33", 33), (), ("33",)], - "34": [(), ("34",), ("34", 34), (), ("34",), ("34", 34)], - "35": [], - "36": [()], - "37": [(), ("37",)], - "38": [(), ("38",), ("38", 38)], - "39": [(), ("39",), ("39", 39), ()], - "40": [(), ("40",), ("40", 40), (), ("40",)], - "41": [(), ("41",), ("41", 41), (), ("41",), ("41", 41)], - "42": [], - "43": [()], - "44": [(), ("44",)], - "45": [(), ("45",), ("45", 45)], - "46": [(), ("46",), ("46", 46), ()], - "47": [(), ("47",), ("47", 47), (), ("47",)], - "48": [(), ("48",), ("48", 48), (), ("48",), ("48", 48)], - "49": [], - "50": [()], - "51": [(), ("51",)], - "52": [(), ("52",), ("52", 52)], - "53": [(), ("53",), ("53", 53), ()], - "54": [(), ("54",), ("54", 54), (), ("54",)], - "55": [(), ("55",), ("55", 55), (), ("55",), ("55", 55)], - "56": [], - "57": [()], - "58": [(), ("58",)], - "59": [(), ("59",), ("59", 59)], - "60": [(), ("60",), ("60", 60), ()], - "61": [(), ("61",), ("61", 61), (), ("61",)], - "62": [(), ("62",), ("62", 62), (), ("62",), ("62", 62)], - "63": [], - "64": [()], - "65": [(), ("65",)], - "66": [(), ("66",), ("66", 66)], - "67": [(), ("67",), ("67", 67), ()], - "68": [(), ("68",), ("68", 68), (), ("68",)], - "69": [(), ("69",), ("69", 69), (), ("69",), ("69", 69)], - "70": [], - "71": [()], - "72": [(), ("72",)], - "73": [(), ("73",), ("73", 73)], - "74": [(), ("74",), ("74", 74), ()], - "75": [(), ("75",), ("75", 75), (), ("75",)], - "76": [(), ("76",), ("76", 76), (), ("76",), ("76", 76)], - "77": [], - "78": [()], - "79": [(), ("79",)], - "80": [(), ("80",), ("80", 80)], - "81": [(), ("81",), ("81", 81), ()], - "82": [(), ("82",), ("82", 82), (), ("82",)], - "83": [(), ("83",), ("83", 83), (), ("83",), ("83", 83)], - "84": [], - "85": [()], - "86": [(), ("86",)], - "87": [(), ("87",), ("87", 87)], - "88": [(), ("88",), ("88", 88), ()], - "89": [(), ("89",), ("89", 89), (), ("89",)], - "90": [(), ("90",), ("90", 90), (), ("90",), ("90", 90)], - "91": [], - "92": [()], - "93": [(), ("93",)], - "94": [(), ("94",), ("94", 94)], - "95": [(), ("95",), ("95", 95), ()], - "96": [(), ("96",), ("96", 96), (), ("96",)], - "97": [(), ("97",), ("97", 97), (), ("97",), ("97", 97)], - "98": [], - "99": [()], -} diff --git a/packages/vipeye-internal/src/tests/samples/dunderAll1.py b/packages/vipeye-internal/src/tests/samples/dunderAll1.py deleted file mode 100644 index c1f5af5a..00000000 --- a/packages/vipeye-internal/src/tests/samples/dunderAll1.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the reportUnsupportedDunderAll diagnostic rule. - -# viper: reportMissingModuleSource=false - -from typing import Any - -test = 3 -hello = 3 -bar = 3 - -__all__: Any - -__all__ = ("test", "hello") -__all__ = ["test", "hello"] -__all__.append("foo") -__all__.extend(["foo"]) -__all__.remove("foo") -__all__ += ["bar"] - - -my_string = "foo" - -# The following should all generate diagnostics if reportUnsupportedDunderAll -# is enabled. -__all__ = ("test", my_string) -__all__ = ["test", my_string] -__all__ = "test" -__all__.append(my_string) -__all__.extend([my_string]) -__all__.remove(my_string) -__all__ += [my_string] -__all__.something() diff --git a/packages/vipeye-internal/src/tests/samples/dunderAll2.py b/packages/vipeye-internal/src/tests/samples/dunderAll2.py deleted file mode 100644 index d7cbe993..00000000 --- a/packages/vipeye-internal/src/tests/samples/dunderAll2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the check for symbols that are present in __all__ but -# are not present in the module (reportUnsupportedDunderAll). - -a = 3 -b = 4 -g = 4 - -# This should generate an error for "d" -__all__ = ["a", "b", "c", "d"] -__all__.remove("c") - -# This should generate an error for "e" -__all__.append("e") - -# This should generate an error for "f" -__all__ += ["f", "g"] diff --git a/packages/vipeye-internal/src/tests/samples/dunderAll3.pyi b/packages/vipeye-internal/src/tests/samples/dunderAll3.pyi deleted file mode 100644 index eb4d6628..00000000 --- a/packages/vipeye-internal/src/tests/samples/dunderAll3.pyi +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests that __all__ manipulations in a stub file are not -# flagged as invalid stub statements. - -# viper: reportInvalidStubStatement=true - -import typing - -a: int -b: int - -__all__ = ["a", "b"] -__all__ += ["b"] -__all__.extend(["a", "b"]) -__all__.extend(typing.__all__) -__all__.append("a") -__all__.remove("a") diff --git a/packages/vipeye-internal/src/tests/samples/duplicateDeclaration1.py b/packages/vipeye-internal/src/tests/samples/duplicateDeclaration1.py deleted file mode 100644 index 89977c37..00000000 --- a/packages/vipeye-internal/src/tests/samples/duplicateDeclaration1.py +++ /dev/null @@ -1,113 +0,0 @@ -# This sample tests the detection of duplicate (overwritten) symbols. - - -from typing import Callable, overload - - -class C: - # This should generate an error. - def f(self): - return 0 - - # This should generate an error. - def f(self): - return 0 - - def f(self): - return 1 - - # This should generate an error. - def g(self): - return 0 - - g: int - - @property - def h(self) -> int: - return 1 - - @h.setter - def h(self, val: int): - pass - - # This should generate an error. - @property - def j(self) -> int: - return 1 - - def j(self) -> int: - return 3 - - -@overload -def a() -> None: ... - - -@overload -def a(x: int) -> None: ... - - -# This should generate an error. -def a(x: int = 3): - pass - - -def a(x: int = 3): - pass - - -# This should generate an error. -def b(): - pass - - -b: int = 3 - - -def func1(cond: bool): - if cond: - - def a() -> int: - return 3 - - # This should generate an error because its inferred return - # type differs from b above. - def b(): - return 3 - - # This should generate an error because the parameter names don't match. - def c(a: int, b: str) -> None: - return None - - # This should generate an error because the parameter is positional-only. - def d(a: int) -> None: - return None - - def e(a: int, /) -> None: - return None - - # This should generate an error because the parameter is not positional-only. - f: Callable[[int], None] = lambda a: None - - g: Callable[[int], None] = lambda a: None - - else: - - def a() -> int: - return 2 - - def b(): - return 2 - - def c(a: int, c: str) -> None: - return None - - d: Callable[[int], None] = lambda a: None - - e: Callable[[int], None] = lambda a: None - - def f(a: int) -> None: - return None - - def g(a: int, /) -> None: - return None diff --git a/packages/vipeye-internal/src/tests/samples/duplicateDeclaration2.py b/packages/vipeye-internal/src/tests/samples/duplicateDeclaration2.py deleted file mode 100644 index 257cf5e0..00000000 --- a/packages/vipeye-internal/src/tests/samples/duplicateDeclaration2.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the detection of duplicate (overwritten) -# properties. - -# viper: strict - - -class MyClass: - def __init__(self): - self._property: str = "" - - # This should generate an error because "prop" - # is overwritten below. - @property - def prop(self): - return self._property - - # This should generate an error because "prop" - # is overwritten below. - @prop.setter - def prop(self, val: str): - self._property = val - - # This should generate an error because "prop" - # is overwritten below. - @prop.deleter - def prop(self): - pass - - # This should generate an error because "prop" - # is overwritten below. - @property - def prop(self): - return self._property - - @property - def prop(self): - return self._property - - @prop.setter - def prop(self, val: str): - self._property = val - - @prop.deleter - def prop(self): - pass diff --git a/packages/vipeye-internal/src/tests/samples/duplicateImports1.py b/packages/vipeye-internal/src/tests/samples/duplicateImports1.py deleted file mode 100644 index de0493e0..00000000 --- a/packages/vipeye-internal/src/tests/samples/duplicateImports1.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the duplicate import detection. - -import sys - -# This should generate an error because Any is duplicated -from typing import Any, Dict, Any - -# This should generate an error because sys is duplicated -import sys - - -a: Dict[Any, Any] -b = sys.api_version diff --git a/packages/vipeye-internal/src/tests/samples/ellipsis1.pyi b/packages/vipeye-internal/src/tests/samples/ellipsis1.pyi deleted file mode 100644 index 8cab1cd1..00000000 --- a/packages/vipeye-internal/src/tests/samples/ellipsis1.pyi +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests cases where the ellipsis operator can -# and cannot be used. - -from typing import Any, Callable, Generic, Optional, TypeVar, Union - -_T1 = TypeVar("_T1") - -class MyGenericClass1(Generic[_T1]): - pass - -# This should generate an error because ... is not a type variable. -class MyGenericClass2(Generic[_T1, ...]): - pass - -MyGenericClass1[int] - -# This should generate an error because ... cannot be used -# in a specialization list. -MyGenericClass1[...] - -a: tuple[int, ...] - -# This should generate an error because ... cannot be used -# in this context. -b: tuple[..., int] - -c: Callable[..., Any] - -# This should generate an error because ... cannot be used -# in this context. -d: Callable[[...], Any] - -# This should generate an error because ... cannot be used -# in this context. -e: Callable[[], ...] - -# This should generate two errors because ... cannot be used -# in this context. -f: dict[..., ...] - -# This should generate an error because ... cannot be used -# in this context. -g: int | str | ... - -# This should generate an error because ... cannot be used -# in this context. -h: Union[int, str, ...] - -# This should generate an error because ... cannot be used -# in this context. -i: Optional[...] diff --git a/packages/vipeye-internal/src/tests/samples/emptyContainers1.py b/packages/vipeye-internal/src/tests/samples/emptyContainers1.py deleted file mode 100644 index 8919a6cd..00000000 --- a/packages/vipeye-internal/src/tests/samples/emptyContainers1.py +++ /dev/null @@ -1,85 +0,0 @@ -# This sample tests type inference for empty lists and dictionaries. - -# viper: reportUnknownVariableType=true, reportUnknownArgumentType=true - - -def func1(a: bool): - val1 = [] - - if a: - val1 = [2, 3] - - reveal_type(val1, expected_text="list[int]") - - if a: - val2 = [] - else: - val2 = [] - - reveal_type(val2, expected_text="list[Unknown]") - - # This should generate an error because val2 is partially unknown. - val2 += [3] - - val3 = val2 - - # This should generate an error because val3 is partially unknown. - print(val3) - reveal_type(val3, expected_text="list[Unknown]") - - if a: - val3 = [3.4] - - print(val3) - reveal_type(val3, expected_text="list[float]") - - -def func2(a: bool): - val1 = {} - - if a: - val1 = {"a": 2} - - reveal_type(val1, expected_text="dict[str, int]") - - if a: - val2 = {} - else: - val2 = {} - - reveal_type(val2, expected_text="dict[Unknown, Unknown]") - - # This should generate an error because val2 is partially unknown. - val2.pop() - - val3 = val2 - - # This should generate an error because val3 is partially unknown. - print(val3) - reveal_type(val3, expected_text="dict[Unknown, Unknown]") - - if a: - val3 = {"b": 3.4} - - print(val3) - reveal_type(val3, expected_text="dict[str, float]") - - -class A: - def method1(self): - self.val1 = [] - self.val2 = {} - self.val3 = [] - - def method2(self): - self.val1 = [3.4] - self.val2 = {"a": 1} - - def method3(self): - reveal_type(self.val1, expected_text="list[float]") - reveal_type(self.val2, expected_text="dict[str, int]") - reveal_type(self.val3, expected_text="list[Unknown]") - - def method4(self) -> list[int]: - # This should generate an error because of a type mismatch. - return self.val1 diff --git a/packages/vipeye-internal/src/tests/samples/enum1.py b/packages/vipeye-internal/src/tests/samples/enum1.py deleted file mode 100644 index 7092eb86..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum1.py +++ /dev/null @@ -1,291 +0,0 @@ -# This sample tests the type checker's handling of Enum. - -from enum import Enum, EnumMeta, IntEnum -from typing import Self - - -TestEnum1 = Enum("TestEnum1", " A B, , ,C , \t D\t") -TestEnum2 = IntEnum("TestEnum2", "AA BB CC DD") - - -class TestEnum3(Enum): - A = 0 - B = 1 - C = 2 - D = 3 - - -a = TestEnum1["A"] -aa = TestEnum1.A -reveal_type(aa.name, expected_text="Literal['A']") -reveal_type(aa._name_, expected_text="Literal['A']") -reveal_type(aa.value, expected_text="Literal[1]") -reveal_type(aa._value_, expected_text="Literal[1]") -reveal_type(TestEnum1.D.name, expected_text="Literal['D']") -reveal_type(TestEnum1.D._name_, expected_text="Literal['D']") -reveal_type(TestEnum1.D.value, expected_text="Literal[4]") -reveal_type(TestEnum1.D._value_, expected_text="Literal[4]") - - -def func1(te3: TestEnum3): - reveal_type(te3.name, expected_text="Literal['A', 'B', 'C', 'D']") - reveal_type(te3._name_, expected_text="Literal['A', 'B', 'C', 'D']") - reveal_type(te3.value, expected_text="Literal[0, 1, 2, 3]") - reveal_type(te3._value_, expected_text="Literal[0, 1, 2, 3]") - - -reveal_type(TestEnum3.name, expected_text="property") -reveal_type(TestEnum3._name_, expected_text="str") -reveal_type(TestEnum3.value, expected_text="property") -reveal_type(TestEnum3._value_, expected_text="Any") - - -# This should generate an error because "Z" isn't -# a valid member. -z = TestEnum1.Z - - -bb = TestEnum2.BB - -# This should generate an error because "A" isn't -# a valid member. -z = TestEnum2.A - - -b = TestEnum3.B - -# This should generate an error because "Z" isn't -# a valid member. -z = TestEnum3.Z - -reveal_type(TestEnum3["A"], expected_text="TestEnum3") - -# Test that enum classes are iterable. -list1 = list(TestEnum3) -reveal_type(list1, expected_text="list[TestEnum3]") - -list2 = [i for i in TestEnum3] -reveal_type(list2, expected_text="list[TestEnum3]") - -num_items_in_enum3 = len(TestEnum3) -reveal_type(num_items_in_enum3, expected_text="int") - -reveal_type(TestEnum3.A.name, expected_text="Literal['A']") -reveal_type(TestEnum3.B._name_, expected_text="Literal['B']") -reveal_type(TestEnum3.C.value, expected_text="Literal[2]") -reveal_type(TestEnum3.D._value_, expected_text="Literal[3]") - - -TestEnum4 = Enum("TestEnum4", ["A", "B", "C", "D"]) -reveal_type(TestEnum4.A, expected_text="Literal[TestEnum4.A]") -reveal_type(TestEnum4.D, expected_text="Literal[TestEnum4.D]") -reveal_type(TestEnum4.A.name, expected_text="Literal['A']") -reveal_type(TestEnum4.B._name_, expected_text="Literal['B']") -reveal_type(TestEnum4.C.value, expected_text="Literal[3]") -reveal_type(TestEnum4.D._value_, expected_text="Literal[4]") - -TestEnum5 = Enum("TestEnum5", ("A", "B", "C", "D")) -reveal_type(TestEnum5.A, expected_text="Literal[TestEnum5.A]") -reveal_type(TestEnum5.D, expected_text="Literal[TestEnum5.D]") -reveal_type(TestEnum5.A.name, expected_text="Literal['A']") -reveal_type(TestEnum5.B._name_, expected_text="Literal['B']") -reveal_type(TestEnum5.C.value, expected_text="Literal[3]") -reveal_type(TestEnum5.D._value_, expected_text="Literal[4]") - -d_value = "d" - -TestEnum6 = Enum("TestEnum6", [("A", 1), ("B", [1, 2]), ("C", "c"), ("D", d_value)]) -reveal_type(TestEnum6.A, expected_text="Literal[TestEnum6.A]") -reveal_type(TestEnum6.D, expected_text="Literal[TestEnum6.D]") -reveal_type(TestEnum6.A.name, expected_text="Literal['A']") -reveal_type(TestEnum6.B._name_, expected_text="Literal['B']") -reveal_type(TestEnum6.A.value, expected_text="Literal[1]") -reveal_type(TestEnum6.B.value, expected_text="list[int]") -reveal_type(TestEnum6.C.value, expected_text="Literal['c']") -reveal_type(TestEnum6.D._value_, expected_text="Literal['d']") - -TestEnum7 = Enum("TestEnum7", (("A", 1), ("D", "d"))) -reveal_type(TestEnum7.A, expected_text="Literal[TestEnum7.A]") -reveal_type(TestEnum7.D, expected_text="Literal[TestEnum7.D]") -reveal_type(TestEnum7.A.name, expected_text="Literal['A']") -reveal_type(TestEnum7.A.value, expected_text="Literal[1]") -reveal_type(TestEnum7.D._value_, expected_text="Literal['d']") - -TestEnum8 = Enum("TestEnum8", {"A": 1, "B": [1, 2], "C": "c", "D": d_value}) -reveal_type(TestEnum8.A, expected_text="Literal[TestEnum8.A]") -reveal_type(TestEnum8.D, expected_text="Literal[TestEnum8.D]") -reveal_type(TestEnum8.A.name, expected_text="Literal['A']") -reveal_type(TestEnum8.B._name_, expected_text="Literal['B']") -reveal_type(TestEnum8.A.value, expected_text="Literal[1]") -reveal_type(TestEnum8.B.value, expected_text="list[int]") -reveal_type(TestEnum8.C.value, expected_text="Literal['c']") -reveal_type(TestEnum8.D._value_, expected_text="Literal['d']") - - -class TestEnum9(Enum): - _other1: int - _other2: int - - def __new__(cls, value: str, other1: int, other2: int): - obj = object.__new__(cls) - obj._value_ = value - obj._other1 = other1 - obj._other2 = other2 - return obj - - A = ("a", 1, 2) - B = ("b", 2, 3) - - -te9_A = TestEnum9.A -reveal_type(te9_A, expected_text="Literal[TestEnum9.A]") -reveal_type(te9_A.value, expected_text="Any") -reveal_type(te9_A._value_, expected_text="Any") -reveal_type(te9_A.name, expected_text="Literal['A']") -reveal_type(te9_A._name_, expected_text="Literal['A']") - - -class CustomEnumMeta1(EnumMeta): - pass - - -class TestEnum10(Enum, metaclass=CustomEnumMeta1): - A = 1 - B = 2 - - -te10_A = TestEnum10.A -reveal_type(te10_A, expected_text="Literal[TestEnum10.A]") -reveal_type(te10_A.value, expected_text="Any") -reveal_type(te9_A._value_, expected_text="Any") -reveal_type(te9_A.name, expected_text="Literal['A']") -reveal_type(te9_A._name_, expected_text="Literal['A']") - - -def func2(e: type[Enum]): - values = {v.value for v in e} - reveal_type(values, expected_text="set[Any]") - - names = {v.name for v in e} - reveal_type(names, expected_text="set[str]") - - -class TestEnum11(Enum): - (A, B, C) = range(3) - - -te11_A = TestEnum11.A -reveal_type(te11_A, expected_text="Literal[TestEnum11.A]") -reveal_type(te11_A.value, expected_text="int") - - -def func3(self) -> None: - pass - - -class TestEnum12(Enum): - a = 1 - b = lambda self: None - c = func3 - - -reveal_type(TestEnum12.a, expected_text="Literal[TestEnum12.a]") -reveal_type(TestEnum12.b, expected_text="(self: Unknown) -> None") -reveal_type(TestEnum12.c, expected_text="(self: Unknown) -> None") - - -class TestEnum13(metaclass=CustomEnumMeta1): - pass - - -TestEnum14 = TestEnum13("TestEnum14", "A, B, C") -reveal_type(TestEnum14.A, expected_text="Literal[TestEnum14.A]") - - -class TestEnum15(Enum): - _value_: str - A = 1 - B = 2 - - def __init__(self, value: int): - self._value_ = str(value) - - -te15_A = TestEnum15.A -reveal_type(te15_A, expected_text="Literal[TestEnum15.A]") -reveal_type(te15_A.value, expected_text="str") -reveal_type(te15_A._value_, expected_text="str") - - -class TestEnum16(IntEnum): - A = 1 - B = 2 - C = 3 - - D = C # Alias for C - - -reveal_type(TestEnum16.D, expected_text="Literal[TestEnum16.C]") -reveal_type(TestEnum16.D.value, expected_text="Literal[3]") - - -class TestEnum17(IntEnum): - def __new__(cls, val: int, doc: str) -> Self: - obj = int.__new__(cls, val) - obj._value_ = val - obj.__doc__ = doc - return obj - - -class TestEnum18(TestEnum17): - A = (1, "A") - B = (2, "B") - - -class TestEnum19(Enum): - A = 1 - __B = 2 - - -reveal_type(TestEnum19.A, expected_text="Literal[TestEnum19.A]") -reveal_type(TestEnum19.__B, expected_text="Literal[2]") - - -class TestEnum20(Enum): - A = 1 - B = A + 1 - - -reveal_type(TestEnum20.A, expected_text="Literal[TestEnum20.A]") -reveal_type(TestEnum20.A.value, expected_text="Literal[1]") -reveal_type(TestEnum20.B, expected_text="Literal[TestEnum20.B]") -reveal_type(TestEnum20.B.value, expected_text="Literal[2]") -reveal_type(TestEnum20.A.A.A, expected_text="Literal[TestEnum20.A]") -reveal_type(TestEnum20.A.B.A, expected_text="Literal[TestEnum20.A]") -reveal_type(TestEnum20.A.B, expected_text="Literal[TestEnum20.B]") - - -class TestEnum21Base(Enum, metaclass=CustomEnumMeta1): - @property - def value(self) -> str: - return "test" - - -class TestEnum21(TestEnum21Base): - A = 1 - - -reveal_type(TestEnum21.A.value, expected_text="str") - - -class TestEnum22Base(Enum): - @property - def value(self) -> str: - return "test" - - -class TestEnum22(TestEnum22Base): - A = 1 - - -reveal_type(TestEnum22.A.value, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/enum10.py b/packages/vipeye-internal/src/tests/samples/enum10.py deleted file mode 100644 index f185dd6c..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum10.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that a call to an enum class does not invoke the -# constructor for the class if the enum class defines members. - -from enum import Enum - - -class Example(Enum): - A = (1, 2) - - def __init__(self, value, other) -> None: - self._value_ = value - self.other = other - - -Example(1) diff --git a/packages/vipeye-internal/src/tests/samples/enum11.py b/packages/vipeye-internal/src/tests/samples/enum11.py deleted file mode 100644 index e80497ca..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum11.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the validation of member values. - -from enum import Enum - - -class Enum1(Enum): - _value_: int - RED = 1 - - # This should generate an error because of a type mismatch. - GREEN = "green" - - -class Enum2(Enum): - def __new__(cls, value: int): - obj = object.__new__(cls) - obj._value_ = value - - RED = 1 - - # This should generate an error because of a type mismatch. - GREEN = "green" - - # This should generate an error because of a type mismatch. - BLUE = (1, "blue") - - -class Enum3(Enum): - def __init__(self, value: int): - self._value_ = value - - RED = 1 - - # This should generate an error because of a type mismatch. - GREEN = "green" - - # This should generate an error because of a type mismatch. - BLUE = (1, "blue") - - -class Enum4(Enum): - def __init__(self, value: int, other: str): - self._value_ = value - - # This should generate an error because of a type mismatch. - RED = 1 - - # This should generate an error because of a type mismatch. - GREEN = "green" - - BLUE = (1, "blue") - - # This should generate an error because of a type mismatch. - GRAY = (1, "blue", 1) diff --git a/packages/vipeye-internal/src/tests/samples/enum12.py b/packages/vipeye-internal/src/tests/samples/enum12.py deleted file mode 100644 index f2cbf631..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum12.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests that any attribute that is treated as a member at -# runtime does not have a type annotation. The typing spec indicates that -# type checkers should flag such conditions as errors. - -from enum import Enum -from typing import Callable, Final - - -class Enum1(Enum): - # This should generate an error. - MEMBER_1: int = 1 - - # This should generate an error. - MEMBER_2: Final = 3 - - _NON_MEMBER_: int = 3 - - NON_MEMBER_CALLABLE: Callable[[], int] = lambda: 1 diff --git a/packages/vipeye-internal/src/tests/samples/enum13.py b/packages/vipeye-internal/src/tests/samples/enum13.py deleted file mode 100644 index f250c804..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum13.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests the handling of IntEnum and StrEnum literal values. - -from enum import IntEnum, StrEnum, ReprEnum -from typing import Literal, LiteralString - - -class IntEnum1(IntEnum): - MEMBER_1 = 1 - MEMBER_2 = 2 - - -i1: Literal[1] = IntEnum1.MEMBER_1.value - -# This should generate an error. -i2: Literal[1] = IntEnum1.MEMBER_2.value - - -class StrEnum1(StrEnum): - MEMBER_1 = "a" - MEMBER_2 = "b" - - -s1: Literal["a"] = StrEnum1.MEMBER_1.value - -# This should generate an error. -s2: Literal["b"] = StrEnum1.MEMBER_1.value - -s3: LiteralString = StrEnum1.MEMBER_1.value - - -class BytesEnum(bytes, ReprEnum): - MEMBER_1 = b"1" - MEMBER_2 = b"2" - - -b1: Literal[b"1"] = BytesEnum.MEMBER_1.value - -# This should generate an error. -b2: Literal[b"2"] = BytesEnum.MEMBER_1.value diff --git a/packages/vipeye-internal/src/tests/samples/enum14.py b/packages/vipeye-internal/src/tests/samples/enum14.py deleted file mode 100644 index 1bba055f..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum14.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests certain error conditions that previously caused -# an infinite recursion condition in the type evaluator. - -from __future__ import annotations -from enum import Enum -from typing import Literal - - -class A(Enum): - # This should generate two errors. - x: Literal[A.x] - - -class B(Enum): - # This should generate an error. - x: B.x diff --git a/packages/vipeye-internal/src/tests/samples/enum2.py b/packages/vipeye-internal/src/tests/samples/enum2.py deleted file mode 100644 index fc61ef7c..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum2.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample verifies that enums are iterable and indexable. - -import enum -from typing import Type - - -class Color(enum.Enum): - RED = enum.auto() - GREEN = enum.auto() - - -class Foo: - _foo: Type[enum.Enum] - - def __init__(self): - self._foo = Color - - def _print_foo(self): - for f in self._foo: - print(f) - - -def test_fn(color: Type[enum.Enum]): - print(color["RED"]) diff --git a/packages/vipeye-internal/src/tests/samples/enum3.py b/packages/vipeye-internal/src/tests/samples/enum3.py deleted file mode 100644 index 1660e0e9..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum3.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests that enum values are treated as constant even if -# they are not named as such. - -from enum import Enum - - -class EnumA(Enum): - bad = 0 - good = 1 - - -class EnumB: - def __init__(self): - self.status = EnumA.bad - self.foo = 1 - - -myobj = EnumB() - -reveal_type(myobj.status, expected_text="EnumA") - -myobj.status = EnumA.good -reveal_type(myobj.status, expected_text="Literal[EnumA.good]") diff --git a/packages/vipeye-internal/src/tests/samples/enum4.py b/packages/vipeye-internal/src/tests/samples/enum4.py deleted file mode 100644 index a7139fa6..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum4.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests logical operators on enums. - -import enum - - -class CustomFlags(enum.Flag): - A = enum.auto() - B = enum.auto() - C = A | B - - -flags1 = CustomFlags.A | CustomFlags.B -reveal_type(flags1, expected_text="CustomFlags") - -flags2 = CustomFlags.A & CustomFlags.B -reveal_type(flags2, expected_text="CustomFlags") diff --git a/packages/vipeye-internal/src/tests/samples/enum5.py b/packages/vipeye-internal/src/tests/samples/enum5.py deleted file mode 100644 index 641ac204..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum5.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the handling of instance variables within -# an enum class that are initialized by a custom initializer. -# They should not be treated as enum objects. - -from enum import Enum - - -class Descriptor: - def __get__(self, instance, owner=None) -> complex: - return 3j - - -class EnumA(Enum): - ENTRY = (123, "abc") - - desc = Descriptor() - - _exempt_ = 12 - - foo: int - bar: str - - def __init__(self, foo: int, bar: str) -> None: - self.foo = foo - self.bar = bar - - -baz = 123 + EnumA.ENTRY.foo -reveal_type(baz, expected_text="int") - -reveal_type(EnumA._exempt_, expected_text="int") - -reveal_type(EnumA.desc, expected_text="complex") diff --git a/packages/vipeye-internal/src/tests/samples/enum6.py b/packages/vipeye-internal/src/tests/samples/enum6.py deleted file mode 100644 index d0346919..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum6.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests error detection of duplicate enum members and -# an attempt to subclass an enum. - -from enum import Enum - - -class Color(Enum): - red = "red" - blue = "blue" - yellow = "yellow" - - # This should generate an error because the enum member - # already exists. - blue = "blue" - - def __init__(self, value: str): - if value == "blue": - self.foo = False - else: - self.foo = True - - -class NonEnum: ... - - -# This should generate an error because enums cannot -# be subclassed. -class ExtraColor(NonEnum, Color): - pass - - -# This should generate an error because reassignment of enum -# values is not allowed. -Color.red = "new" - - -class EnumWithoutValue(Enum): - def do_something(self): - pass - - @property - def y(self) -> None: - pass - - -class EnumWithValue(EnumWithoutValue): - x = 0 - - -# This should generate an error because enums with values -# cannot be subclassed. -class EnumSubclass(EnumWithValue): - z: int diff --git a/packages/vipeye-internal/src/tests/samples/enum7.py b/packages/vipeye-internal/src/tests/samples/enum7.py deleted file mode 100644 index b770e3fe..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum7.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the custom __call__ method on the EnumMeta class. - -from enum import Enum - - -class Foo(Enum): - A = 1 - B = 2 - - -Foo(1) - -# This would have previously generated an error prior to Python 3.12, -# but it now does not because of an additional overload on the EnumMeta -# __call__ method. -Foo(1, 2, 3, 4) diff --git a/packages/vipeye-internal/src/tests/samples/enum8.py b/packages/vipeye-internal/src/tests/samples/enum8.py deleted file mode 100644 index 8ce053dd..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum8.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where an enum class is used as a bound -# for a TypeVar and instantiated. - -# viper: strict - -from enum import Enum -from typing import TypeVar - -TEnum = TypeVar("TEnum", bound=Enum) - - -def func1(enum_cls: type[TEnum], enum_value: object) -> TEnum: - enum_member = enum_cls(enum_value) - reveal_type(enum_member, expected_text="TEnum@func1") - return enum_member diff --git a/packages/vipeye-internal/src/tests/samples/enum9.py b/packages/vipeye-internal/src/tests/samples/enum9.py deleted file mode 100644 index cb7cdea1..00000000 --- a/packages/vipeye-internal/src/tests/samples/enum9.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the enum.member and enum.nonmember classes introduced -# in Python 3.11. - -import sys -from enum import Enum, member, nonmember -from typing import Literal - - -class Enum1(Enum): - MEMBER = 1 - ANOTHER_MEMBER = member(2) - NON_MEMBER = nonmember(3) - - @member - @staticmethod - def ALSO_A_MEMBER() -> Literal[4]: - return 4 - - @member - class ClassA: - pass - - @nonmember - class ClassB: - pass - - class ClassC: - pass - - -reveal_type(Enum1.MEMBER, expected_text="Literal[Enum1.MEMBER]") -reveal_type(Enum1.ANOTHER_MEMBER, expected_text="Literal[Enum1.ANOTHER_MEMBER]") -reveal_type(Enum1.ALSO_A_MEMBER, expected_text="Literal[Enum1.ALSO_A_MEMBER]") -reveal_type(Enum1.NON_MEMBER, expected_text="int") -reveal_type(Enum1.ClassA, expected_text="Literal[Enum1.ClassA]") -reveal_type(Enum1.ClassB, expected_text="type[ClassB]") - -if sys.version_info >= (3, 13): - reveal_type(Enum1.ClassC, expected_text="type[ClassC]") -else: - reveal_type(Enum1.ClassC, expected_text="Literal[Enum1.ClassC]") - - -reveal_type(Enum1.MEMBER.value, expected_text="Literal[1]") -reveal_type(Enum1.ANOTHER_MEMBER.value, expected_text="int") -reveal_type(Enum1.ALSO_A_MEMBER.value, expected_text="() -> Literal[4]") -reveal_type(Enum1.ClassA.value, expected_text="type[ClassA]") - -if sys.version_info < (3, 13): - reveal_type(Enum1.ClassC.value, expected_text="type[ClassC]") diff --git a/packages/vipeye-internal/src/tests/samples/enumAuto1.py b/packages/vipeye-internal/src/tests/samples/enumAuto1.py deleted file mode 100644 index 901e6b8f..00000000 --- a/packages/vipeye-internal/src/tests/samples/enumAuto1.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests enum types with auto() values. - -from enum import Enum, auto - - -class CacheBehavior(Enum): - ALWAYS = auto() - NEVER = auto() - AUTO = auto() - - -a: CacheBehavior = CacheBehavior.ALWAYS -b: CacheBehavior = CacheBehavior["ALWAYS"] -foo = "A" + "UTO" -c: CacheBehavior = CacheBehavior[foo] diff --git a/packages/vipeye-internal/src/tests/samples/enumGenNextValue1.py b/packages/vipeye-internal/src/tests/samples/enumGenNextValue1.py deleted file mode 100644 index 57dc8931..00000000 --- a/packages/vipeye-internal/src/tests/samples/enumGenNextValue1.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the handling of a custom _generate_next_value_ override. - -from enum import Enum, auto - - -class EnumA(Enum): - x = auto() - - -reveal_type(EnumA.x.value, expected_text="int") - - -class EnumC(str, Enum): - @staticmethod - def _generate_next_value_(name, start, count, last_values) -> str: - return name - - -class EnumD(EnumC): - x = auto() - - -reveal_type(EnumD.x.value, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/exceptionGroup1.py b/packages/vipeye-internal/src/tests/samples/exceptionGroup1.py deleted file mode 100644 index c1916921..00000000 --- a/packages/vipeye-internal/src/tests/samples/exceptionGroup1.py +++ /dev/null @@ -1,127 +0,0 @@ -# This sample tests the syntax handling for Python 3.11 exception groups -# as described in PEP 654. - - -def func1(): - - try: - pass - - # This should generate an error if using Python 3.10 or earlier. - except* ValueError as e: - reveal_type(e, expected_text="ExceptionGroup[ValueError]") - pass - - # This should generate an error if using Python 3.10 or earlier. - except*: - pass - - -def func2(): - try: - pass - # This should generate an error because ExceptionGroup derives - # from BaseExceptionGroup. - except* ExceptionGroup as e: - pass - - # This should generate an error because ExceptionGroup derives - # from BaseExceptionGroup. - except* (ValueError, ExceptionGroup) as e: - pass - -def func3(): - try: - pass - - except* ValueError: - pass - - # This should generate an error because except and except* cannot be mixed. - except NameError: - pass - - except* ValueError: - pass - -def func4(): - try: - pass - - except ValueError: - pass - - except NameError: - pass - - # This should generate an error because except and except* cannot be mixed. - except* ValueError: - pass - - -def func5(): - try: - pass - - except* ValueError: - pass - - # This should generate an error because except and except* cannot be mixed. - except: - pass - -def func6(): - try: - pass - - # This should generate an error because except* requires an exception type. - except*: - pass - - -def func7(): - while True: - try: - ... - except* ValueError: - def inner(): - while True: - if 1 < 1: - continue - else: - break - return - - if 1 < 2: - # This should generate an error because - # break is not allowed in an except* block. - break - if 1 < 2: - # This should generate an error because - # continue is not allowed in an except* block. - continue - - while 1 < 2: - # This is allowed because it's within a nested loop. - break - - # This should generate an error because - # return is not allowed in an except* block. - return - - - -def func8(): - - try: - pass - - # This should generate an error if using Python 3.10 or earlier. - except* (ValueError, FloatingPointError) as e: - reveal_type(e, expected_text="ExceptionGroup[ValueError | FloatingPointError]") - pass - - # This should generate an error if using Python 3.10 or earlier. - except* BaseException as e: - reveal_type(e, expected_text="BaseExceptionGroup[BaseException]") - pass diff --git a/packages/vipeye-internal/src/tests/samples/expression1.py b/packages/vipeye-internal/src/tests/samples/expression1.py deleted file mode 100644 index f395ca47..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression1.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests various arithmetic expressions. - - -def returnsInt1() -> int: - a = 1 - b = 2 - - return a + b % b // a - b // a - - -def returnsInt2() -> int: - a = 1.0 - b = 2 - - # This should generate an error because - # it should evaluate to a float, which is - # not compatible with the specified return - # type. - return a + b % b // a - b // a - - -def returnsFloat1() -> float: - a = 1 - b = 2 - return a + b % b / a - b // a - - -def returnsFloat2() -> float: - a = complex(1, 2) - b = 2 - - # This should generate an error because it - # should evaluate to a complex, which is - # not compatible with the specified return - # type. - return a + b % b / a - b // a - - -def returnsComplex1() -> complex: - a = complex(1, 2) - b = 2 - c = 4.0 - - # This should generate an error because a - # float should be divisible by a complex. - return a + b % (b / a - c // a) - - -a = 3 -b = 4 - -# This should generate an error because matrix multiply -# isn't supported for int. -c = a @ b diff --git a/packages/vipeye-internal/src/tests/samples/expression2.py b/packages/vipeye-internal/src/tests/samples/expression2.py deleted file mode 100644 index b41609c3..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests various logical expressions. - - -class Foo: - def do_something1(self): - pass - - def do_something2(self): - pass - - -class Bar: - def do_something1(self): - pass - - -a = 0 -foo = Foo() -bar = Bar() - -b = a and foo or bar - -# This should not be flagged as an error because -# the type of b should be type Foo. -b.do_something1() - -# This should be flagged as an error because -# Bar doesn't define a do_something2 method. -b.do_something2() diff --git a/packages/vipeye-internal/src/tests/samples/expression3.py b/packages/vipeye-internal/src/tests/samples/expression3.py deleted file mode 100644 index 83faa2a4..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression3.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests various unary expressions. - - -def returnsFloat1() -> float: - a = 1 - b = not a - - return b - - -def returnsInt1() -> int: - a = 1 - b = -a - return b - - -def returnsInt2() -> int: - a = 1 - b = +a - return b - - -def returnsInt3() -> int: - a = 4 - b = ~a - return b diff --git a/packages/vipeye-internal/src/tests/samples/expression4.py b/packages/vipeye-internal/src/tests/samples/expression4.py deleted file mode 100644 index 9388caf4..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression4.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the handling of "in" and "not in" operators. - - -def func1(a: int | str): - # This should generate an error because a's type doesn't - # support a __contains__ method. - if 3 in a: - pass - - # This should generate an error because a's type doesn't - # support a __contains__ method. - if 3 not in a: - pass - - -def func(a: list[int] | set[float]): - if 3 in a: - pass - - if 3 not in a: - pass diff --git a/packages/vipeye-internal/src/tests/samples/expression5.py b/packages/vipeye-internal/src/tests/samples/expression5.py deleted file mode 100644 index 3b8e09f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression5.py +++ /dev/null @@ -1,70 +0,0 @@ -# This sample tests the validation of binary operations, especially -# in cases where one or both operands are union types and some combination -# of the types is not supported. - -from typing import Optional, Union - - -def arith( - v1: Union[str, int], - v2: Optional[Union[str, int]], - v3: str, - v4: int, - v5: Optional[int], -): - # This should generate an error. - a1 = v1 + v2 - - # This should generate an error - a2 = 3 + v2 - - # This should generate an error - a3 = 3 + v3 - - # This should generate an error - a4 = 3 + None - - a5 = 3 + v4 - - a6 = "hi" + v3 - - # This should generate an error - a7 = "hi" + v4 - - # This should generate an error - a8 = 3 + v5 - - assert v5 is not None - a8 = 3 + v5 - - -def comparison( - v1: Union[str, int], - v2: Optional[Union[str, int]], - v3: str, - v4: int, - v5: Optional[int], -): - # This should generate an error. - a1 = v1 < v2 - - # This should generate an error - a2 = 3 > v2 - - a3 = 3 <= v3 - - # This should generate an error - a4 = 3 >= None - - a5 = 3 < v4 - - a6 = "hi" < v3 - - # This should generate an error - a7 = "hi" < v4 - - # This should generate an error - a8 = 3 < v5 - - assert v5 is not None - a8 = 3 < v5 diff --git a/packages/vipeye-internal/src/tests/samples/expression6.py b/packages/vipeye-internal/src/tests/samples/expression6.py deleted file mode 100644 index 9889eed9..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression6.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests that binary operations "or" and "and" -# properly handle bidirectional type inference. - -from typing import Any - - -def func_or(a: dict[str, Any] | None): - a = a or {"": 0} - reveal_type(a, expected_text="dict[str, Any]") - - -def func_and(): - a: dict[str, Any] | None = True and {"": 0} - reveal_type(a, expected_text="dict[str, Any]") diff --git a/packages/vipeye-internal/src/tests/samples/expression7.py b/packages/vipeye-internal/src/tests/samples/expression7.py deleted file mode 100644 index 5b7f52ca..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression7.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests various conditions with AND and OR operators. - - -def func1() -> bool: ... - - -def func2() -> int: ... - - -def func3() -> str: ... - - -reveal_type(func1() and func2(), expected_text="int | Literal[False]") -reveal_type(func1() and func3(), expected_text="str | Literal[False]") -reveal_type(func2() and func1(), expected_text="bool | Literal[0]") -reveal_type(func3() and func1(), expected_text="bool | Literal['']") - -reveal_type(func1() or func2(), expected_text="int | Literal[True]") -reveal_type(func1() or func3(), expected_text="str | Literal[True]") -reveal_type(func2() or func1(), expected_text="int | bool") -reveal_type(func3() or func1(), expected_text="str | bool") - - -class ClassA: ... - - -class ClassB: ... - - -# This should generate an error because binary operators are not allowed -# in type annotations. -def func4(a: ClassA and ClassB): ... - - -# This should generate an error because binary operators are not allowed -# in type annotations. -def func5(a: ClassA or ClassB): ... diff --git a/packages/vipeye-internal/src/tests/samples/expression8.py b/packages/vipeye-internal/src/tests/samples/expression8.py deleted file mode 100644 index cdf02196..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression8.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample verifies that binary expressions like "less than" -# work if the operands are constrained TypeVars. - -from abc import abstractmethod -from typing import Protocol, TypeVar - -_T_contra = TypeVar("_T_contra", contravariant=True) -_T = TypeVar("_T") - - -class ComparableTo(Protocol[_T_contra]): - @abstractmethod - def __lt__(self, __x: _T_contra) -> bool: - pass - - -def custom_compare(a: ComparableTo[_T], b: _T) -> bool: - return a < b - - -custom_compare("first", "second") - -custom_compare(3, 2) - -# This should generate an error. -custom_compare(3, "hi") diff --git a/packages/vipeye-internal/src/tests/samples/expression9.py b/packages/vipeye-internal/src/tests/samples/expression9.py deleted file mode 100644 index 9633a9f4..00000000 --- a/packages/vipeye-internal/src/tests/samples/expression9.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests binary expressions that use list expressions as -# a RHS operand. - - -def func1(a: list[int | str]): - a += [5] - - return a + [5] - - -def func2(a: list[int], b: int): - return a + [b] diff --git a/packages/vipeye-internal/src/tests/samples/final1.py b/packages/vipeye-internal/src/tests/samples/final1.py deleted file mode 100644 index e795e233..00000000 --- a/packages/vipeye-internal/src/tests/samples/final1.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the handling of the @final class decorator. - -from typing import final - - -@final -class ClassA: - pass - - -# This should generate an error because ClassA is -# decorated as final. -class ClassB(ClassA): - pass diff --git a/packages/vipeye-internal/src/tests/samples/final2.py b/packages/vipeye-internal/src/tests/samples/final2.py deleted file mode 100644 index d38bf97d..00000000 --- a/packages/vipeye-internal/src/tests/samples/final2.py +++ /dev/null @@ -1,162 +0,0 @@ -# This sample tests the handling of the @final method decorator. - -from typing import Any, cast, final, overload - - -class ClassA: - def func1(self): - pass - - @classmethod - def func2(cls): - pass - - @final - def func3(self): - pass - - @final - @classmethod - def func4(cls): - pass - - @final - def _func5(self): - pass - - @final - def __func6(self): - pass - - @overload - def func7(self, x: int) -> int: ... - - @overload - def func7(self, x: str) -> str: ... - - @final - def func7(self, x: int | str) -> int | str: ... - - # This should generate an error because the implementation - # of func8 is marked as not final but this overload is. - @overload - @final - def func8(self, x: int) -> int: ... - - @overload - def func8(self, x: str) -> str: ... - - def func8(self, x: int | str) -> int | str: ... - - @final - @property - def prop1(self) -> int: ... - - @property - @final - def prop2(self) -> int: ... - - @property - def prop3(self) -> int: ... - - @prop3.setter - @final - def prop3(self, value: int) -> None: ... - - -# This should generate an error because func3 is final. -ClassA.func3 = lambda self: None - -# This should generate an error because func4 is final. -ClassA.func4 = lambda cls: None - -# This should generate an error because _func5 is final. -ClassA._func5 = lambda self: None - -# This should generate an error because func7 is final. -ClassA.func7 = cast(Any, lambda self, x: "") - - -class ClassB(ClassA): - def func1(self): - # This should generate an error because @final isn't allowed - # on non-method functions. - @final - def func1_inner(): - pass - - @classmethod - def func2(cls): - pass - - # This should generate an error because func3 is - # defined as final. - def func3(self): - pass - - # This should generate an error because func3 is - # defined as final. - @classmethod - def func4(cls): - pass - - # This should generate an error because func3 is - # defined as final. - def _func5(self): - pass - - # This should not generate an error because double - # underscore symbols are exempt from this check. - def __func6(self): - pass - - @overload - def func7(self, x: int) -> int: ... - - @overload - def func7(self, x: str) -> str: ... - - @final - # This should generate an error because func7 is - # defined as final. - def func7(self, x: int | str) -> int | str: ... - - # This should generate an error because prop1 is - # defined as final. - @property - def prop1(self) -> int: ... - - # This should generate an error because prop2 is - # defined as final. - @property - def prop2(self) -> int: ... - - @property - def prop3(self) -> int: ... - - # This should generate an error because prop3's setter is - # defined as final. - @prop3.setter - @final - def prop3(self, value: int) -> None: ... - - -class Base4: ... - - -class Base5: - @final - def __init__(self, v: int) -> None: ... - - -class C(Base4, Base5): - # This should generate an error because it overrides Base5, - # and __init__ is marked final there. - def __init__(self) -> None: ... - - -# This should generate an error because @final isn't allowed on -# non-method functions. -@final -def func1(): - return None diff --git a/packages/vipeye-internal/src/tests/samples/final3.py b/packages/vipeye-internal/src/tests/samples/final3.py deleted file mode 100644 index f58799a6..00000000 --- a/packages/vipeye-internal/src/tests/samples/final3.py +++ /dev/null @@ -1,270 +0,0 @@ -# This sample tests the "Final" type annotation -# introduced in Python 3.8. - -import typing -from typing import Annotated, Any, Final, Protocol, TypeVar - -T = TypeVar("T") - -v1: typing.Final = 3 - -must_be_int: int = v1 - -# This should generate an error because -# reassignment of a Final variable should -# not be allowed. -v1 = 4 - -# This should generate an error because there -# is a previous Final declaration. -v1: Final[int] - -# This should generate an error because -# the type doesn't match. -v2: Final[str] = 3 - -# This should generate an error because -# we expect only one type argument for Final. -v3: Final[str, int] = "hello" - - -v4: Final = 5 -reveal_type(v4, expected_text="Literal[5]") - - -class ClassA: - member1: Final = 4 - - # This should generate an error because only - # one declaration can have a Final attribute. - member1: Final - - member2: typing.Final[int] = 3 - - member4: Final[int] - - # This should generate an error because there is - # no assignment. - member5: Final[str] - - member6: Final[int] - - _member7: Final = 6 - __member8: Final = 6 - - member9: Final = 2 - - # This should generate an error. - member9 = 3 - - def __init__(self, a: bool): - # This should generate an error because a Final - # member outside of a stub file or a class body - # must have an initializer. - self.member3: Final - - # This should generate an error because this symbol - # already has a final declaration. - self.member2: Final[int] - - if a: - self.member4 = 5 - else: - self.member4 = 6 - - self.member4 = 6 - - def another_method(self): - # This should generate an error because assignments - # can occur only within class bodies or __init__ methods. - self.member6 = 4 - - # This should generate an error because 'Final' cannot - # be used to annotate instance variables outside of - # an __init__ method. - self.member7: Final = 6 - - -reveal_type(ClassA.member1, expected_text="Literal[4]") -reveal_type(ClassA(True).member1, expected_text="Literal[4]") - - -class ClassB(ClassA): - # This should generate an error because we are overriding - # a member that is marked Final in the parent class. - member1 = 5 - - # This should generate an error because we are overriding - # a member that is marked Final in the parent class. - _member7: Final = 6 - - # This should not generate an error because it's private. - __member8: Final = 6 - - def __init__(self): - # This should generate an error because we are overriding - # a member that is marked Final in the parent class. - self.member6 = 5 - - -# This should generate an error because Final isn't allowed for -# function parameters. -def func1(a: Final[int]): - pass - - -# This should generate an error because Final must the outermost -# type in assignments. -b: list[Final[int]] = [] - - -class ClassC: - member1: Final = 3 - member2: Final - member4: Final - member5: Final = 3 - - def __init__(self): - # This should generate an error. - self.member1 = 5 - - self.member2 = "hi" - - self.member3: Final = "hi" - - # This should generate an error. - ClassC.member4 = "hi" - - # This should generate an error. - ClassC.member5 = 3 - - def other(self): - # This should generate an error. - self.member1 = 5 - - # This should generate an error. - self.member2 = "hi" - - # This should generate an error. - self.member3 = "hi" - - -a = ClassC() - -# This should generate an error. -a.member1 = 4 - -# This should generate an error. -a.member3 = "x" - - -def func2(): - x: Final[Any] = 3 - - # This should generate an error because x is Final. - x += 1 - - # This should generate an error because x is Final. - a = (x := 4) - - # This should generate an error because x is Final. - for x in [1, 2, 3]: - pass - - # This should generate an error because x is Final. - with open("Hi") as x: - pass - - try: - pass - # This should generate an error because x is Final. - except ModuleNotFoundError as x: - pass - - # This should generate an error because x is Final. - (a, x) = (1, 2) - - -class ClassD: - def __init__(self): - self.x: Final = 1 - - def method1(self): - # This should generate an error because x is Final. - self.x += 1 - - -class ClassE(Protocol): - x: Final[int] - - -def func3(x: type[T]) -> T: - return x() - - -# This should generate an error because Final isn't compatible with type. -func3(Final[int]) - - -v5: Final = lambda: None - - -# This should generate an error because foo5 is declared as Final. -def v5() -> None: - pass - - -# This should generate an error because ClassVar is Final. -from typing import ClassVar - -ClassVar: Final = 3 - - -v6: Annotated[Final[int], "meta"] = 1 - -# This should generate an error -v6 = 2 - -v7: Annotated[Annotated[Final[int], "meta"], "meta"] = 1 - -# This should generate an error -v7 = 2 - -v8: Annotated[Final, "meta"] = 1 - -# This should generate an error -v8 = 2 - -v9: Final = 2 or "2" -reveal_type(v9, expected_text="Literal[2]") - -v10: Final = 0 or "2" -reveal_type(v10, expected_text="Literal['2']") - -v11: Final = b"" and True -reveal_type(v11, expected_text='Literal[b""]') - -v12: Final = b"2" and True -reveal_type(v12, expected_text="Literal[True]") - - -def func4(): - while 1 < 1: - # This should generate an error because it's in a loop. - x1: Final = 1 - - for i in range(10): - if i < 3: - # This should generate an error because it's in a loop. - x2: Final[int] = 1 - - -class ClassF: - while 1 < 2: - # This should generate an error because it's in a loop. - x1: Final = 1 - - for i in range(10): - if i < 3: - # This should generate an error because it's in a loop. - x2: Final[int] = 1 diff --git a/packages/vipeye-internal/src/tests/samples/final4.pyi b/packages/vipeye-internal/src/tests/samples/final4.pyi deleted file mode 100644 index fe0c06c1..00000000 --- a/packages/vipeye-internal/src/tests/samples/final4.pyi +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the "Final" type annotation -# introduced in Python 3.8. - -from typing import Final - -class ClassA: - foo1: Final[int] - def __init__(self): - self.foo2: Final[str] - def other(self): - # This should generate an error because Final is - # not allowed in methods other than __init__. - self.foo3: Final[str] - -# This should generate an error because Final isn't allowed in -# parameter annotations. -def func1(a: Final[str]) -> None: ... - -# This should generate an error because Final isn't allowed in -# return type annotations. -def func2() -> Final[str]: ... diff --git a/packages/vipeye-internal/src/tests/samples/final5.py b/packages/vipeye-internal/src/tests/samples/final5.py deleted file mode 100644 index 17ce2f05..00000000 --- a/packages/vipeye-internal/src/tests/samples/final5.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests that instance variables declared as Final within -# a dataclass do not need to have an explicit assignment because -# the generated __init__ method will assign them. - -from dataclasses import dataclass -from typing import Final - - -class ClassA: - x: Final[int] - - def __init__(self, x: int) -> None: - self.x = x - - -@dataclass -class ClassB: - x: Final[int] diff --git a/packages/vipeye-internal/src/tests/samples/final6.pyi b/packages/vipeye-internal/src/tests/samples/final6.pyi deleted file mode 100644 index 5c9ab97a..00000000 --- a/packages/vipeye-internal/src/tests/samples/final6.pyi +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests that an overloaded method in a stub honors the -# @final on the first overload. - -from typing import final, overload - -class ClassA: - @overload - @final - def method1(self, x: int) -> int: ... - @overload - def method1(self, x: str) -> str: ... - @overload - def method2(self, x: int) -> int: ... - @overload - @final - # This should generate an error because the first overload - # is not marked @final but this one is. - def method2(self, x: str) -> str: ... - -class ClassB(ClassA): - @overload - def method1(self, x: int) -> int: ... - @overload - # This should generate an error. - def method1(self, x: str) -> str: ... diff --git a/packages/vipeye-internal/src/tests/samples/final7.py b/packages/vipeye-internal/src/tests/samples/final7.py deleted file mode 100644 index 275687ae..00000000 --- a/packages/vipeye-internal/src/tests/samples/final7.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample is used in conjunction with final8.py to test that imported -# Final symbols cannot be overwritten. - -from typing import Final - - -var1: Final[int] = 1 -var2: Final = 2 diff --git a/packages/vipeye-internal/src/tests/samples/final8.py b/packages/vipeye-internal/src/tests/samples/final8.py deleted file mode 100644 index 58952ad5..00000000 --- a/packages/vipeye-internal/src/tests/samples/final8.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests that final variables imported from another module -# cannot be overwritten. - -from .final7 import * - -# This should generate an error. -var1 = 1 - -# This should generate an error. -var2 = 1 - - -def func1(): - from .final7 import var1, var2 - - # This should generate an error. - var1 = 1 - - # This should generate an error. - var2 = 1 diff --git a/packages/vipeye-internal/src/tests/samples/forLoop1.py b/packages/vipeye-internal/src/tests/samples/forLoop1.py deleted file mode 100644 index 7539d36c..00000000 --- a/packages/vipeye-internal/src/tests/samples/forLoop1.py +++ /dev/null @@ -1,118 +0,0 @@ -# This sample tests 'for' operations (both simple for loops -# and list comprehension for loops). - -from typing import overload - - -def requires_int(val: int): - pass - - -list1: list[int] = [1, 2, 3] - -for a in list1: - requires_int(a) - - -int1 = 1 - -# This should generate an error because -# an int type is not iterable. -for foo1 in int1: - pass - - -async def func1(): - # This should generate an error because - # list1 isn't an async iterator. - async for foo2 in list1: - requires_int(foo2) - - -class AsyncIterable1(object): - def __aiter__(self): - return self - - async def __anext__(self): - return 1 - - -iter1 = AsyncIterable1() - - -async def func2(): - async for foo3 in iter1: - requires_int(foo3) - - for d in [b for b in list1]: - requires_int(d) - - for e in [b async for b in iter1]: - requires_int(e) - - -class ClassWithGetItem(object): - def __getitem__(self, item) -> str: - return "hello" - - -def testGetItemIterator() -> str: - objWithGetItem = ClassWithGetItem() - for f in objWithGetItem: - return f - return "none" - -# This should generate a syntax error. -for in range(3): - pass - - -class A: - def __init__(self): - self.__iter__ = lambda: iter([]) - - -# This should generate an error because A -# is not iterable. The __iter__ method is an -# instance variable. -for a in A(): - ... - -class B: - __slots__ = ("__iter__",) - def __init__(self): - self.__iter__ = lambda: iter([]) - - -for b in B(): - ... - -def func3(): - x = None - for x in range(1): - pass - - reveal_type(x, expected_text="int | None") - - -class C: - @overload - def __getitem__(self, i: int) -> str: - ... - - @overload - def __getitem__(self, i: slice) -> list[str]: - ... - - def __getitem__(self, i: int | slice) -> str | list[str]: - ... - - -c = C() - -for c1 in iter(c): - reveal_type(c1, expected_text="str") - -for c2 in c: - reveal_type(c2, expected_text="str") - diff --git a/packages/vipeye-internal/src/tests/samples/forLoop2.py b/packages/vipeye-internal/src/tests/samples/forLoop2.py deleted file mode 100644 index d3d7ddb1..00000000 --- a/packages/vipeye-internal/src/tests/samples/forLoop2.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests for/else loops for cases where variables -# are potentially unbound. - - -# For with no break and no else. -def func1(): - for x in []: - a = 0 - - # This should generate a "potentially unbound" error. - print(a) - - # This should generate a "potentially unbound" error. - print(x) - - -# For with no break and else. -def func2(): - for x in []: - a = 0 - else: - b = 0 - - # This should generate a "potentially unbound" error. - print(a) - - print(b) - - # This should generate a "potentially unbound" error. - print(x) - - -# For with break and else. -def func3(): - for x in []: - a = 0 - break - else: - b = 0 - - # This should generate a "potentially unbound" error. - print(a) - - # This should generate a "potentially unbound" error. - print(b) - - # This should generate a "potentially unbound" error. - print(x) diff --git a/packages/vipeye-internal/src/tests/samples/fstring1.py b/packages/vipeye-internal/src/tests/samples/fstring1.py deleted file mode 100644 index e3499434..00000000 --- a/packages/vipeye-internal/src/tests/samples/fstring1.py +++ /dev/null @@ -1,159 +0,0 @@ -# This tests various f-string parsing and analysis cases. - -# Test nested f-strings. -a = f'hello { f"hi {1}" } bye { f"hello" }' - - -# Test f-string with a backslash in the expression. -# This should generate an error. -b = f"hello { \t1 }" - -# This should generate an error prior to Python 3.12. -b1 = f"""{"\n"}""" - -# This should generate an error prior to Python 3.12. -b2 = f"{r'\n'}" - - -# Test f-string with unterminated expression. -# This should generate an error. -c = f"hello { 1 " - - -# Test f-string with double braces. -d = f"hello {{{1}}}" - -# Test f-string with formatting directives. -e = f"hello { 2 != 3 !r:2 }" - -# Test f-string with formatting directives. -f = f"hello { 2 != 3 :3 }" - -# Test f-string with embedded colon. -g = f"hello { a[2:3] :3 }" - -# Test f-string with embedded bang. -h = f"hello { {}['hello!'] :3 }" - -# Test f-string with expression that contains newlines. -i = f""" - { - f''' hi ''' + - 'bye' - } -""" - -j = f""" -{ - f''' - {f' { f":" } '} - ''' -} -""" - -# Test f-string with raw string and backslash. -j = rf"aaa\{4}" - -# Test f-string with comma-separated expressions. -h = f"List: { 2 + 3, 'hi' + ' there'}" - -# Test f-string with unpack operator. -my_dict = {"a": "A", "b": "B"} -i = f"{*my_dict.keys(),}" - -# f-string with empty expression should generate error. -j = f"{}" - -# f-string with quotes within quotes within quotes. -k = f"""{"#M's#".replace(f"'", '')!r}""" - - -# f-strings with escape characters in the format string section. -my_str = "" -width = 3 -l = f"{my_str:\>{width}s}" -m = f"{my_str:\x00>{width}s}" -n = f"{my_str:\u2007>{width}s}" - -# f-strings with nested expressions in the format string section. -o = f"{1+2:{1+2:{1+1:}}}" - -# This should generate an error because the nesting is too deep. -p = f"{1+2:{1+2:{1+1:{1}}}}" - -# This should generate a warning because of the unknown -# escape sequence but not an error. -q = f"hello\{4}" - -s1 = f"""{f'''{f'{f"{1+1}"}'}'''}""" - -# This should generate an error prior to Python 3.12. -s2 = f"""{f'''{f'{f"""{1+1}"""}'}'''}""" - -# This should generate an error prior to Python 3.12. -s3 = f'{f'''{r'abc'}'''}' - -q1 = f"""{ - 1 + 1 # Comment - }""" - -# This should generate an error prior to Python 3.12, but -# pyright doesn't currently detect this error. -q2 = f'{ - 1 + 1 # Comment - }' - -# This should generate an error because an expression is missing. -r1 = f'{!r}' - -# This should generate an error because an expression is missing. -r2 = f'{!}' - -# This should generate an error because an expression is missing. -r3 = f'{:}' - -# This should generate an error because an expression is missing. -r4 = f'{=}' - -r5 = f'{1!s:}' -r6 = f'{1:}' -r7 = f'{1=}' -r8 = f'{1=:}' -r9 = f'{1=!r:}' - -s1 = f"}}" - -# This should generate an error because a single right brace is used. -s2 = f"}" - -t1 = f'{0==1}' -t2 = f'{0!=1}' -t3 = f'{0<=1}' - -# This should generate an error because this isn't a walrus -# operator as it appears. -t4 = f'{x1:=3}' - -t5 = f"{(x2:=3):{(x3:=0)}}" - -u1 = f"'{{\"{0}\": {0}}}'" - -def func1(x): - f"x:{yield (lambda i: x * i)}" - -v1 = f"x \ -y" - -v2 = f'x \ -y' - -w1 = 1 - -w2 = f"__{ - w1:d -}__" - - -# This should generate an error because it's unterminated. -w3 = f"test - diff --git a/packages/vipeye-internal/src/tests/samples/fstring2.py b/packages/vipeye-internal/src/tests/samples/fstring2.py deleted file mode 100644 index b2e4156c..00000000 --- a/packages/vipeye-internal/src/tests/samples/fstring2.py +++ /dev/null @@ -1,12 +0,0 @@ -# This tests f-strings with format expressions. - -# viper: strict - - -def return_right_aligned_string(): - some_length = 10 - some_length2 = 2 - some_string = "some string to print" - - string_right_aligned = f"{some_string:>{some_length - 2} {some_length2: 3}}" - return string_right_aligned diff --git a/packages/vipeye-internal/src/tests/samples/fstring3.py b/packages/vipeye-internal/src/tests/samples/fstring3.py deleted file mode 100644 index 5b697b1c..00000000 --- a/packages/vipeye-internal/src/tests/samples/fstring3.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests f-strings where expressions contain -# other string literals. - -# viper: strict - -a1 = f"[{{name}}{'}' if True else ''}]" - -b1 = f"{'''hello'''}" - -c1 = f"""{'"'}""" - -hello1 = 3 -d1 = f"{f'{hello1}'}" - -print(f"{'a' if 'b' != d1 else 'd'}") - - -a2 = rf"[{{name}}{'}' if True else ''}]" - -b2 = rf"{'''hello'''}" - -c2 = rf"""{'"'}""" - -hello2 = 3 -d2 = rf"{rf'{hello2}'}" - -e1 = f""" {f''' {"".join(["this", "that"])}'''}""" diff --git a/packages/vipeye-internal/src/tests/samples/fstring4.py b/packages/vipeye-internal/src/tests/samples/fstring4.py deleted file mode 100644 index a2ab6520..00000000 --- a/packages/vipeye-internal/src/tests/samples/fstring4.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests nested braces within an f-string. - - -def foo(spam, dictval: dict): - print(dictval) - return "Done" - - -print(f"{foo(0, {'bar' : 1, 'baz': 2})}") - -hello = 200 -print(f"({hello} \N{greek capital letter sigma})") -print(f"({hello} \N{GREEK CAPITAL LETTER SIGMA})") -print(f"({hello} \N{VARIATION SELECTOR-16})") -print(f"({hello} \N{VARIATION SELECTOR-16})") diff --git a/packages/vipeye-internal/src/tests/samples/fstring5.py b/packages/vipeye-internal/src/tests/samples/fstring5.py deleted file mode 100644 index b037ca9a..00000000 --- a/packages/vipeye-internal/src/tests/samples/fstring5.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the parsing and analysis of f-strings -# that end in an "=" sign. Support for this was added -# in Python 3.8. - -key = 3 - -print(f"Value for {key =}") - -print(f"Value for {key = }") - -print(f"Value for {key = :.2f}") - -print(f"Value for {key=}") - -print(f"Value for {key= }") - -print(f"Value for {key= :.2f}") diff --git a/packages/vipeye-internal/src/tests/samples/function1.py b/packages/vipeye-internal/src/tests/samples/function1.py deleted file mode 100644 index dfebdd6e..00000000 --- a/packages/vipeye-internal/src/tests/samples/function1.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that args and kwargs parameters are -# properly typed. - - -def function_with_args(*args: str): - reveal_type(args, expected_text="tuple[str, ...]") - - -def function_with_kwargs(**kwargs: list[str]): - reveal_type(kwargs, expected_text="dict[str, list[str]]") diff --git a/packages/vipeye-internal/src/tests/samples/function10.py b/packages/vipeye-internal/src/tests/samples/function10.py deleted file mode 100644 index 38bb6441..00000000 --- a/packages/vipeye-internal/src/tests/samples/function10.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a union of callables is passed -# to a generic function and the parameter types are subtypes of -# each other. - -from typing import Any, Callable, Generic, TypeVar - -T_contra = TypeVar("T_contra", contravariant=True) - - -class Thing1: - prop1: str - - -class Thing2: - prop1: str - prop2: str - - -class ClassA(Generic[T_contra]): - def __init__(self, callback: Callable[[T_contra], Any]) -> None: ... - - -def func1(cb: Callable[[Thing1], Any] | Callable[[Thing1 | Thing2], Any]): - reveal_type(ClassA(cb), expected_text="ClassA[Thing1]") diff --git a/packages/vipeye-internal/src/tests/samples/function2.py b/packages/vipeye-internal/src/tests/samples/function2.py deleted file mode 100644 index 7c4dfaed..00000000 --- a/packages/vipeye-internal/src/tests/samples/function2.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests the case where a param with no default -# arg value can follow a param with a default arg value -# if they are both followed by a *args param. - - -def f(*a, b=1, c): - pass diff --git a/packages/vipeye-internal/src/tests/samples/function3.py b/packages/vipeye-internal/src/tests/samples/function3.py deleted file mode 100644 index ede2a43d..00000000 --- a/packages/vipeye-internal/src/tests/samples/function3.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests assignment of a function that uses -# a synthesized TypeVar type for the "self" parameter. - -from typing import Callable - - -class TestClass: - def method(self) -> None: - pass - - -# This should generate an error. -func1: Callable[[float], None] = TestClass.method diff --git a/packages/vipeye-internal/src/tests/samples/function5.py b/packages/vipeye-internal/src/tests/samples/function5.py deleted file mode 100644 index 6861efb6..00000000 --- a/packages/vipeye-internal/src/tests/samples/function5.py +++ /dev/null @@ -1,13 +0,0 @@ -# This test validates that a function can be treated as an object -# for type checking purposes. - -from typing import Hashable - - -def func1(a: int) -> int: - return a - - -x: object = func1 - -y: Hashable = func1 diff --git a/packages/vipeye-internal/src/tests/samples/function6.py b/packages/vipeye-internal/src/tests/samples/function6.py deleted file mode 100644 index 45f5db6e..00000000 --- a/packages/vipeye-internal/src/tests/samples/function6.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample verifies that functions are treated as though they -# derive from object. - -from typing import Callable, overload - - -@overload -def func1(a: str) -> str: ... - - -@overload -def func1(a: int) -> int: ... - - -def func1(a: str | int) -> str | int: ... - - -def func2(a: str | int) -> str | int: ... - - -def takes_object(val: object) -> None: ... - - -takes_object(func1) -takes_object(func2) - - -def func3(b: Callable[[str], bool]) -> None: - if b == func1: - pass - - if b != func2: - pass diff --git a/packages/vipeye-internal/src/tests/samples/function7.py b/packages/vipeye-internal/src/tests/samples/function7.py deleted file mode 100644 index 230e4ec2..00000000 --- a/packages/vipeye-internal/src/tests/samples/function7.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests the case where a function type is compared to another -# function type where one contains a positional-only marker and the -# other does not. - -from typing import Protocol - - -class _Writer1(Protocol): - def write(self, a: str, b: str) -> object: - pass - - -class Writer1: - def write(self, a: str, /, b: str): - pass - - -def make_writer1(w: _Writer1): - pass - - -# This should generate an error because the source function is positional-only. -make_writer1(Writer1()) - - -class _Writer2(Protocol): - def write(self, a: str, /, b: str) -> object: - pass - - -class Writer2: - def write(self, a: str, b: str): - pass - - -def make_writer2(w: _Writer2): - pass - - -make_writer2(Writer2()) - - -class _Writer3(Protocol): - def write(self, a: str, b: str) -> object: - pass - - -class Writer3: - def write(self, __a: str, b: str): - pass - - -def make_writer3(w: _Writer3): - pass - - -# This should generate an error because the source function is positional-only. -make_writer3(Writer3()) - - -class _Writer4(Protocol): - def write(self, __a: str, b: str) -> object: - pass - - -class Writer4: - def write(self, a: str, b: str): - pass - - -def make_writer4(w: _Writer4): - pass - - -make_writer4(Writer4()) diff --git a/packages/vipeye-internal/src/tests/samples/function8.py b/packages/vipeye-internal/src/tests/samples/function8.py deleted file mode 100644 index d7d5c23a..00000000 --- a/packages/vipeye-internal/src/tests/samples/function8.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests bidirectional type inference for a function when -# a union includes a "bare" TypeVar and another (non-generic) type. - -from dataclasses import dataclass -from typing import Generic, Sequence, TypeVar - -T = TypeVar("T") - - -@dataclass -class Container(Generic[T]): - values: Sequence[float | T] - - -def create_container(values: Sequence[float | T]) -> Container[T]: - return Container(values) - - -arg: Sequence[float | int] = (1, 2.0) -x: Container[int] = create_container(arg) diff --git a/packages/vipeye-internal/src/tests/samples/function9.py b/packages/vipeye-internal/src/tests/samples/function9.py deleted file mode 100644 index 1d08f3ea..00000000 --- a/packages/vipeye-internal/src/tests/samples/function9.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the case where a function type is assigned to another -# and the source contains parameters that are annotated as literals and -# the destination has corresponding TypeVars. - -from typing import Callable, TypeVar, Literal - -_A = TypeVar("_A") - - -def wrapper1(fn: Callable[[_A], int]) -> _A: ... - - -def f1(a: Literal[0]) -> int: ... - - -reveal_type(wrapper1(f1), expected_text="Literal[0]") - - -def wrapper2(fn: Callable[..., _A]) -> Callable[..., _A]: ... - - -def f2() -> Literal["Foo"]: - return "Foo" - - -reveal_type(wrapper2(f2)(), expected_text="Literal['Foo']") - - -def f3(): - return "Foo" - - -reveal_type(wrapper2(f3)(), expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/functionAnnotation1.py b/packages/vipeye-internal/src/tests/samples/functionAnnotation1.py deleted file mode 100644 index b2703ddb..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionAnnotation1.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests support for comment-style function annotations. - -# viper: strict, reportMissingParameterType=false, reportTypeCommentUsage=false - -from typing import Optional, Literal as _Literal, Union - - -def func1a(a, b): - # type: (int, str) -> str - return "" - - -def func1b(a, b): # type: (Optional[str], int) -> str - return "" - - -def func1c( - a, # type: int - b, # type: str -): - # type: (...) -> str - return "" - - -def func1d( - a, # type: int - b, # type: Foo -): - # type: (...) -> str - return "" - - -def func1e( - a, # type: int - b, # type: str -): - # type: (...) -> str - return "" - - -# This should generate an error because a is unannotated. -def func1f(a): - # type: (...) -> str - return "" - - -class Foo: - pass - - -def func1g(*args, **kwargs): - # type: (*int, **float) -> int - return sum(args) + sum(round(kwarg) for kwarg in kwargs.values()) - - -def func1h( - a, # type: _Literal["{", "}"] - b, # type: Union[_Literal["%"], _Literal["{"], _Literal["$"]] -): - # type: (...) -> str - return "" diff --git a/packages/vipeye-internal/src/tests/samples/functionAnnotation2.py b/packages/vipeye-internal/src/tests/samples/functionAnnotation2.py deleted file mode 100644 index 445e4ec0..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionAnnotation2.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests support for comment-style function annotations. - - -# Too few annotations -def func1a(a, b): - # type: (str) -> str - return "" - - -# Too many annotations -def func1b(a, b): # type: (str, int, int) -> str - return "" - - -class ClassA: - def method0(self, a, b): - # type: (str, int) -> str - return "" - - # Too few annotations - def method1(self, a, b): - # type: (str) -> str - return "" - - # Too many annotations - def method2(self, a, b): # type: (str, int, int, int) -> str - return "" diff --git a/packages/vipeye-internal/src/tests/samples/functionAnnotation3.py b/packages/vipeye-internal/src/tests/samples/functionAnnotation3.py deleted file mode 100644 index a7245af2..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionAnnotation3.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests support for comment-style function annotations -# that include extra annotations for the "self" or "cls" parameters. - -from typing import TypeVar - - -_T = TypeVar("_T", bound="ClassA") - - -class ClassA: - foo: str - - def method0(self, a, b): - # type: (_T, str, list[_T]) -> str - return self.foo - - def method1(self, a, b): - # type: (_T, str, list[_T]) -> ClassB - return ClassB() - - # Too many annotations - def method2(self, a, b): # type: (_T, str, int, list[_T]) -> str - return "" - - # Too few annotations - @staticmethod - def method3(a, b): - # type: (int) -> str - return "" - - def method4(self, a, b): - # type: (str, ClassB) -> str - return self.foo - - -class ClassB: ... diff --git a/packages/vipeye-internal/src/tests/samples/functionAnnotation4.py b/packages/vipeye-internal/src/tests/samples/functionAnnotation4.py deleted file mode 100644 index 66f5b7c3..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionAnnotation4.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the reportTypeCommentUsage diagnostic check. - -from typing import Optional - - -# This should generate an error if reportTypeCommentUsage is enabled. -def func1a(a, b): - # type: (int, str) -> str - return "" - - -# This should generate an error if reportTypeCommentUsage is enabled. -def func1b(a, b): # type: (Optional[str], int) -> str - return "" - - -# This should generate an error if reportTypeCommentUsage is enabled. -def func1c( - a, # type: int - b, # type: str -): - # type: (...) -> str - return "" diff --git a/packages/vipeye-internal/src/tests/samples/functionAssignabilityMessage1.py b/packages/vipeye-internal/src/tests/samples/functionAssignabilityMessage1.py deleted file mode 100644 index 0eeae461..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionAssignabilityMessage1.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the wording and operand ordering of the function -# assignability diagnostic addendum for positional-parameter count mismatches. - -from typing import Callable - - -def decorator(func: Callable[[int], int]) -> Callable[[int], int]: - return func - - -# The decorated function accepts too few positional parameters (0 < 1), so the -# addendum must say "too few" with expected=1 (dest) and received=0 (source). -@decorator -def too_few() -> int: - return 1 - - -# The decorated function accepts too many positional parameters (2 > 1), so the -# addendum must say "too many" with expected=1 (dest) and received=2 (source). -@decorator -def too_many(a: int, b: int, /) -> int: - return 1 diff --git a/packages/vipeye-internal/src/tests/samples/functionMember1.py b/packages/vipeye-internal/src/tests/samples/functionMember1.py deleted file mode 100644 index 571360bb..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionMember1.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the reportFunctionMemberAccess diagnostic rule. - - -def func1(): - pass - - -a = func1.__annotations__ -b = func1.__class__ - -# This should generate an error -c = func1.bar - -# This should generate an error -func1.baz = 3 - -# This should generate an error -del func1.baz diff --git a/packages/vipeye-internal/src/tests/samples/functionMember2.py b/packages/vipeye-internal/src/tests/samples/functionMember2.py deleted file mode 100644 index e156adda..00000000 --- a/packages/vipeye-internal/src/tests/samples/functionMember2.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests the special-case handling of the __self__ -# attribute for a function when it is bound to a class or object. - -# viper: reportFunctionMemberAccess=error - - -from typing import Protocol - - -def func1(a: int) -> str: ... - - -# This should generate an error because func1 isn't -# bound to a "self". -s1 = func1.__self__ - - -class A: - def method1(self) -> None: ... - - @classmethod - def method2(cls) -> None: ... - - @staticmethod - def method3() -> None: ... - - -s2 = A().method1.__self__ -reveal_type(s2, expected_text="A") - -s3 = A.method2.__self__ -reveal_type(s3, expected_text="type[A]") - -s3 = A.method2.__self__ -reveal_type(s3, expected_text="type[A]") - -s4 = A().method2.__self__ -reveal_type(s4, expected_text="type[A]") - -# This should generate an error because method3 is static. -s5 = A().method3.__self__ - -# This should generate an error because method3 is static. -s6 = A.method3.__self__ - - -class HasSelf(Protocol): - @property - def __self__(self, /) -> object: ... - - -f1: HasSelf -f1 = A.method2 -f1 = A().method1 -f1 = A().method2 - -# These three should generate an error because they are not -# MethodTypes but are instead FunctionTypes. -f1 = A.method1 -f1 = A.method3 -f1 = A().method3 diff --git a/packages/vipeye-internal/src/tests/samples/futureImport1.py b/packages/vipeye-internal/src/tests/samples/futureImport1.py deleted file mode 100644 index 69346e31..00000000 --- a/packages/vipeye-internal/src/tests/samples/futureImport1.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests that __future__ imports are found -# only at the beginning of a file. - -""" Doc String """ "Extension" - -from __future__ import annotations -from __future__ import with_statement diff --git a/packages/vipeye-internal/src/tests/samples/futureImport2.py b/packages/vipeye-internal/src/tests/samples/futureImport2.py deleted file mode 100644 index f2bb34e2..00000000 --- a/packages/vipeye-internal/src/tests/samples/futureImport2.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests that __future__ imports are found -# only at the beginning of a file. - -"""Doc String""" - -"Extension" -from __future__ import annotations # This should generate an error - - -def func(): - from __future__ import annotations # This should generate an error diff --git a/packages/vipeye-internal/src/tests/samples/futureImport3.py b/packages/vipeye-internal/src/tests/samples/futureImport3.py deleted file mode 100644 index 7f09203e..00000000 --- a/packages/vipeye-internal/src/tests/samples/futureImport3.py +++ /dev/null @@ -1,5 +0,0 @@ -# This sample tests that __future__ imports are found -# only at the beginning of a file. - -from typing import Any -from __future__ import annotations # This should generate an error diff --git a/packages/vipeye-internal/src/tests/samples/generator1.py b/packages/vipeye-internal/src/tests/samples/generator1.py deleted file mode 100644 index 6abe6240..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator1.py +++ /dev/null @@ -1,170 +0,0 @@ -# This sample tests various type checking operations relating to -# generator functions (those with a "yield" method). - -from typing import ( - Any, - Awaitable, - Generator, - Generic, - Iterable, - Iterator, - NamedTuple, - Protocol, - TypedDict, - TypeVar, -) - -T = TypeVar("T") - - -class ClassA: - pass - - -s = True - - -class ClassB: - def shouldContinue(self): - global s - return s - - -class ClassC: - pass - - -class NT1(NamedTuple, Generic[T]): - value: T - - -class ClassD(Generic[T]): - def __init__(self, obj: T) -> None: - self.obj = obj - - def ingest(self) -> Generator[NT1[T], None, None]: - yield NT1(self.obj) - - -def generator1() -> Generator[ClassA, ClassB, ClassC]: - cont = ClassB() - while cont.shouldContinue(): - yield ClassA() - - return ClassC() - - -# This should generate an error because the function -# has no return statement at the bottom, so it -# returns None which is not assignable to ClassC. -def generator2() -> Generator[ClassA, ClassB, ClassC]: - cont = ClassB() - if cont.shouldContinue(): - # This should generate an error because False isn't - # assignable to the return type (ClassC). - return False - - while cont.shouldContinue(): - # This should generate an error because 3 isn't - # assignable to the yield type (ClassA). - yield 3 - - -def generator3() -> Generator[ClassA, int, Any]: - cont = ClassB() - if cont.shouldContinue(): - return 3 - - while cont.shouldContinue(): - # This should generate an error because 3 isn't - # assignable to the yield type (ClassA). - yield 3 - - -def generator4() -> Iterable[ClassA]: - yield ClassA() - - return True - - -def generator5() -> Iterator[ClassA]: - # This should generate an error because ClassB isn't - # assignable to ClassA. - yield ClassB() - - -def generate(): - for i in range(2): - yield i - - -s = generate() - -# Verify that a call to a Generator method succeeds -s.close() - - -def generator6(): - yield - - -def generator7() -> Generator[None, None, None]: - yield - - -def generator8() -> Iterator[dict[str, int]]: - # This tests the bidirectional type inference - # of dict types. It should not generate an error. - yield {"hello": 3} - - -# This should generate an error. -def generator9() -> int: - # This should generate an error. - yield None - return 3 - - -# This should generate an error. -async def generator10() -> int: - # This should generate an error. - yield None - - -# This should generate an error. -def generator11() -> list[int]: - # This should generate an error. - yield 3 - - -class TD1(TypedDict): - x: str - - -def generator12() -> Generator[TD1, None, None]: - yield {"x": "x"} - - -def generator13() -> Generator[TD1, None, None]: - # This should generate an error. - yield {"y": "x"} - - -def generator14() -> Iterator[TD1]: - yield {"x": "x"} - - -class IntIterator(Protocol): - def __next__(self, /) -> int: ... - - -def generator15() -> IntIterator: - yield 0 - - -class AsyncIntIterator(Protocol): - def __anext__(self, /) -> Awaitable[int]: ... - - -async def generator16() -> AsyncIntIterator: - yield 0 diff --git a/packages/vipeye-internal/src/tests/samples/generator10.py b/packages/vipeye-internal/src/tests/samples/generator10.py deleted file mode 100644 index d2fc6269..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator10.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests type inference for a generator returned -# by an __await__ function. - -from collections.abc import Awaitable -from asyncio import get_event_loop, sleep - - -class MyAwaitable(Awaitable): - def __await__(self): - yield from (sleep(0.1).__await__()) - - -async def func1(): - x: None = await MyAwaitable() - - -loop = get_event_loop() -loop.run_until_complete(func1()) diff --git a/packages/vipeye-internal/src/tests/samples/generator11.py b/packages/vipeye-internal/src/tests/samples/generator11.py deleted file mode 100644 index bb22c81a..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator11.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the return type inference for a generator. - -from typing import Awaitable, Generator, TypeVar - -S = TypeVar("S") -T = TypeVar("T") - - -def func1() -> Generator[int, int, str]: - yield 1 - return "done" - - -def func2() -> Generator[int, int, None]: - # This should generate an error because yield is not allowed - # from within a list comprehension. - x = [(yield from func1()) for lel in range(5)] - - v1 = yield from func1() - reveal_type(v1, expected_text="str") - - v2 = yield 4 - reveal_type(v2, expected_text="int") - - -def func3(): - [x for x in (yield [[[1]], [[2]], [[3]]]) for y in x] - - # This should generate an error. - [x for x in [[[1]], [[2]], [[3]]] for y in (yield x)] - - -class ClassA[S, T](Awaitable[T]): - def __init__(self, val: S) -> None: - self.val = val - - def __await__(self) -> Generator[S, T, T]: - z = yield self.val - reveal_type(z, expected_text="T@ClassA") - return z diff --git a/packages/vipeye-internal/src/tests/samples/generator12.py b/packages/vipeye-internal/src/tests/samples/generator12.py deleted file mode 100644 index 0f2777eb..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator12.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the inference of types relating to -# "yield from" statements. - -from typing import Generator - - -class Yielder: - def __iter__(self) -> Generator[int, None, bool]: - yield 1 - return True - - -def collect1() -> Generator[str, None, bool]: - y = Yielder() - - # This should generate an error because int doesn't match str. - z = yield from y - return z - - -def collect2(): - y = Yielder() - z = yield from y - reveal_type(z, expected_text="bool") - return z diff --git a/packages/vipeye-internal/src/tests/samples/generator13.py b/packages/vipeye-internal/src/tests/samples/generator13.py deleted file mode 100644 index 0b4b96a3..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator13.py +++ /dev/null @@ -1,74 +0,0 @@ -# This sample tests async generator and non-generator functions. - -import asyncio -from typing import AsyncGenerator, AsyncIterator, Protocol - - -async def get_data() -> list[int]: - await asyncio.sleep(1) - return [1, 2, 3] - - -async def generate(nums: list[int]) -> AsyncGenerator[str, None]: - for n in nums: - await asyncio.sleep(1) - yield f"The number is {n}" - - -async def func1() -> AsyncGenerator[str, None]: - data = await get_data() - v1 = generate(data) - reveal_type(v1, expected_text="AsyncGenerator[str, None]") - return v1 - - -async def func2() -> AsyncIterator[str]: - data = await get_data() - v1 = generate(data) - reveal_type(v1, expected_text="AsyncGenerator[str, None]") - return v1 - - -async def get_value(v: int) -> int: - await asyncio.sleep(1) - return v + 1 - - -async def func3() -> AsyncGenerator[int, None]: - return (await get_value(v) for v in [1, 2, 3]) - - -def func4() -> AsyncGenerator[int, None]: - return (await get_value(v) for v in [1, 2, 3]) - - -async def func5() -> None: - v1 = func1() - reveal_type(v1, expected_text="CoroutineType[Any, Any, AsyncGenerator[str, None]]") - gen = await v1 - reveal_type(gen, expected_text="AsyncGenerator[str, None]") - async for s in gen: - print(s) - - -async def func6() -> None: - v1 = func2() - reveal_type(v1, expected_text="CoroutineType[Any, Any, AsyncIterator[str]]") - gen = await v1 - reveal_type(gen, expected_text="AsyncIterator[str]") - async for s in gen: - print(s) - - -loop = asyncio.get_event_loop() -loop.run_until_complete(func5()) -loop.run_until_complete(func6()) - - -class Proto(Protocol): - async def iter(self) -> AsyncGenerator[bytes, None]: ... - - -async def func7(p: Proto): - async for x in await p.iter(): - pass diff --git a/packages/vipeye-internal/src/tests/samples/generator14.py b/packages/vipeye-internal/src/tests/samples/generator14.py deleted file mode 100644 index 65df1d3c..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator14.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the inferred type of async and sync generators. - - -async def foo() -> int: ... - - -async def main() -> None: - v1 = (x for x in [2, 3] if x > 3) - reveal_type(v1, expected_text="Generator[int, None, None]") - - v2 = (x for x in [2, 3] if await foo()) - reveal_type(v2, expected_text="AsyncGenerator[int, None]") - - v3 = (x for x in [2, 3]) - reveal_type(v3, expected_text="Generator[int, None, None]") - - v4 = (await foo() for _ in [2, 3]) - reveal_type(v4, expected_text="AsyncGenerator[int, None]") - - v5 = ((0, await foo()) for _ in [1, 2]) - reveal_type(v5, expected_text="AsyncGenerator[tuple[int, int], None]") - - v6 = (x for x in [1, 2] if (x, await foo())) - reveal_type(v6, expected_text="AsyncGenerator[int, None]") diff --git a/packages/vipeye-internal/src/tests/samples/generator15.py b/packages/vipeye-internal/src/tests/samples/generator15.py deleted file mode 100644 index 195b9df7..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator15.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests that the parser emits an error when a generator -# is used as an argument without parentheses. - - -from typing import Any - - -def func1(*x: Any) -> None: - pass - -func1(x for x in [0, 1]) - -func1((x for x in [0, 1]), 1) - -func1((x for x in [0, 1]),) - -func1(1, (x for x in [0, 1])) - -# This should generate an error. -func1(x for x in [0, 1], 1) - -# This should generate an error. -func1(x for x in [0, 1],) - -# This should generate an error. -func1(1, x for x in [0, 1]) diff --git a/packages/vipeye-internal/src/tests/samples/generator16.py b/packages/vipeye-internal/src/tests/samples/generator16.py deleted file mode 100644 index c73a7b44..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator16.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a return statement within an async -# generator has an explicit return value. This generates a syntax -# error at runtime. - -from typing import Any, AsyncIterable - - -async def func1(n: int, fa: AsyncIterable[Any]): - if n <= 0: - # This should generate an error because return statements - # are not allowed in async generators. - return None - - g = aiter(fa) - - while True: - try: - yield await g.__anext__() - except StopAsyncIteration: - return diff --git a/packages/vipeye-internal/src/tests/samples/generator2.py b/packages/vipeye-internal/src/tests/samples/generator2.py deleted file mode 100644 index c0d41d83..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator2.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample tests various type checking operations relating to -# generator functions that use the "yield from" clause. - -from typing import Generator, Iterator, TypeVar - -T = TypeVar("T") - - -class ClassA: - pass - - -class ClassB: - def shouldContinue(self): - return True - - -class ClassC: - pass - - -def generator1() -> Iterator[ClassA]: - yield from generator1() - - -def generator2() -> Iterator[ClassB]: - # This should generate an error because it yields - # an iterator of the wrong type. - yield from generator1() - - # This should also generate an error because it - # yields the wrong type. - yield from [1] - - -def generator3( - arg: Generator[int, None, T] | Generator[str, None, T], -) -> Generator[int | str, None, T]: - x = yield from arg - reveal_type(x, expected_text="T@generator3") - return x - - -def generator4( - arg: Generator[int, None, int] | Generator[str, None, str], -) -> Generator[int | str, None, int | str]: - x = yield from arg - reveal_type(x, expected_text="int | str") - return x - - -def generator5() -> Generator[None, float, None]: - x: float = yield - - -def generator6() -> Generator[None, int, None]: - yield from generator5() - - -def generator7() -> Generator[None, int, None]: - x: float = yield - - -def generator8() -> Generator[None, float, None]: - # This should generate an error because of the send type. - yield from generator7() diff --git a/packages/vipeye-internal/src/tests/samples/generator3.py b/packages/vipeye-internal/src/tests/samples/generator3.py deleted file mode 100644 index 98ca70f8..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator3.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests various type checking operations relating to -# generator functions where the return type is inferred. - - -class ClassA: - pass - - -class ClassB: - pass - - -def generator1(): - yield ClassB() - - -reveal_type(generator1(), expected_text="Generator[ClassB, Any, None]") - - -def generator2(): - yield "Hello" - yield ClassA() - return 3 - - -reveal_type( - generator2(), expected_text="Generator[ClassA | Literal['Hello'], Any, Literal[3]]" -) - - -def generator3(): - x = yield 3 - return 0 - - -reveal_type(generator3(), expected_text="Generator[Literal[3], Unknown, Literal[0]]") - - -def consumer1() -> ClassB: - return next(generator1()) - - -def consumer2() -> ClassA: - # This should generate an error because the - # inferred type of generator1 should be incompatible - # with ClassA. - return next(generator1()) - - -def consumer3() -> ClassA | None: - value = next(generator2()) - - if isinstance(value, str): - print(str) - else: - return value - - -def generator4(): - return - yield 1 - - -reveal_type(generator4(), expected_text="Generator[Never, Any, None]") diff --git a/packages/vipeye-internal/src/tests/samples/generator4.py b/packages/vipeye-internal/src/tests/samples/generator4.py deleted file mode 100644 index d8780909..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator4.py +++ /dev/null @@ -1,71 +0,0 @@ -# This sample tests various type checking operations relating to -# async generator functions where the return type is inferred. - -from typing import AsyncGenerator, Awaitable, Generator, Iterator - - -async def g1(): - yield 1 - yield 2 - - -async def g2(): - async for v in g1(): - yield v - - -def g1_explicit1() -> Generator[int, None, None]: - yield 1 - yield 2 - - -async def g1_explicit2() -> AsyncGenerator[int, None]: - yield 1 - yield 2 - - -async def g2_explicit(): - for v in g1_explicit1(): - yield v - - async for v in g1_explicit2(): - yield v - - -async def g3(xs: Awaitable[list[int]]) -> list[int]: - return [x for x in await xs] - - -async def g4(xs: list[Awaitable[int]]) -> list[int]: - return [await x for x in xs] - - -class SomeIterable: - def __init__(self): - self.x = 1 - - def __iter__(self) -> Iterator[int]: - yield self.x - - -async def func1() -> SomeIterable: - return SomeIterable() - - -def func2() -> Iterator[int]: - yield 2 - - -def g5() -> None: - val = (y for y in func2()) - reveal_type(val, expected_text="Generator[int, None, None]") - - -async def g6() -> None: - val = (x + y for y in func2() for x in await func1()) - reveal_type(val, expected_text="AsyncGenerator[int, None]") - - -async def g7() -> None: - val = (x + y for y in await func1() for x in func2()) - reveal_type(val, expected_text="Generator[int, None, None]") diff --git a/packages/vipeye-internal/src/tests/samples/generator5.py b/packages/vipeye-internal/src/tests/samples/generator5.py deleted file mode 100644 index 060f329a..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator5.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests various type checking operations relating to -# async generator functions where the return type is declared. - -from typing import AsyncIterable, AsyncIterator - - -async def g1_explicit() -> AsyncIterator[int]: - yield 1 - yield 2 - - -async def g2_explicit(): - async for v in g1_explicit(): - yield v - - -async def g3_explicit() -> AsyncIterable[int]: - yield 1 - yield 2 - - -async def g4_explicit(): - async for v in g3_explicit(): - yield v diff --git a/packages/vipeye-internal/src/tests/samples/generator6.py b/packages/vipeye-internal/src/tests/samples/generator6.py deleted file mode 100644 index 6eb9f54a..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator6.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests that functions containing unreachable -# yield statements are still treated as generators. - -from typing import Iterable, AsyncIterable - - -def func1() -> Iterable[str]: - return - yield "" - - -async def func2() -> AsyncIterable[str]: - return - yield "" diff --git a/packages/vipeye-internal/src/tests/samples/generator7.py b/packages/vipeye-internal/src/tests/samples/generator7.py deleted file mode 100644 index 8c80ada6..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator7.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the handling of the "yield from" statement -# and inferred return types from generators that use this -# statement. - - -def func1(): - yield from [1, 2, 3] - - -def func2(): - yield from func1() - - -a: dict[int, int] = {} -for i in func2(): - a[i] = i diff --git a/packages/vipeye-internal/src/tests/samples/generator8.py b/packages/vipeye-internal/src/tests/samples/generator8.py deleted file mode 100644 index 1b3afbff..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator8.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample verifies that the "yield from" argument -# is wrapped in an Iterable. - -from typing import Generator - -ints1 = [1, 2] -ints2 = [3, 4] - - -def func1() -> Generator[int, None, None]: - yield from ints1 - yield from ints2 diff --git a/packages/vipeye-internal/src/tests/samples/generator9.py b/packages/vipeye-internal/src/tests/samples/generator9.py deleted file mode 100644 index 4b19068d..00000000 --- a/packages/vipeye-internal/src/tests/samples/generator9.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the check that "yield" is not used outside -# of a function or lambda. - -a = lambda: (yield) - - -def func1(a: bool): - if a: - yield 3 - yield 5 - - -# This should generate an error -yield 7 - - -class Foo: - # This should generate an error - yield diff --git a/packages/vipeye-internal/src/tests/samples/generic1.py b/packages/vipeye-internal/src/tests/samples/generic1.py deleted file mode 100644 index 8a776100..00000000 --- a/packages/vipeye-internal/src/tests/samples/generic1.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests error handling for the "Generic" special form. - -from typing import Generic, TypeVar - -T = TypeVar("T") - -# This should generate an error. -class Class1(Generic): - ... - -# This should generate two errors (a parse error and a semantic error). -class Class2(Generic[]): - ... - -# This should generate an error. -class Class3(Generic[int]): - ... - -# This should generate two errors. -class Class4(Generic[T, T, T]): - ... - - -# This should generate an error. -def func1(x: Generic[T]) -> T: - ... - -# This should generate an error. -def func2(x: T) -> Generic[T]: - ... - -class Class5(Generic[T]): - # This should generate an error. - x: Generic[T] - - -def func3(x: type): - if x is Generic: - return - - diff --git a/packages/vipeye-internal/src/tests/samples/generic2.py b/packages/vipeye-internal/src/tests/samples/generic2.py deleted file mode 100644 index 8dee0af4..00000000 --- a/packages/vipeye-internal/src/tests/samples/generic2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample verifies that "Generic" is tagged as -# invalid in contexts outside of a class definition. - -from typing import Generic, TypeVar - - -_T1 = TypeVar("_T1") - - -class ClassA(Generic[_T1]): - pass - - -# This should generate an error. -def func1(a: _T1) -> Generic[_T1]: ... - - -# This should generate an error. -def func2(p1: Generic[_T1]) -> _T1: ... - - -TA1 = Generic - - -# This should generate an error. -def func3(a: _T1) -> TA1[_T1]: ... - - -class ClassB(TA1[_T1]): ... diff --git a/packages/vipeye-internal/src/tests/samples/generic3.py b/packages/vipeye-internal/src/tests/samples/generic3.py deleted file mode 100644 index b987ba21..00000000 --- a/packages/vipeye-internal/src/tests/samples/generic3.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests that a Generic base class overrides the type parameter -# ordering of other type parameters. - -# viper: reportIncompatibleMethodOverride=false - -from typing import Generic, Iterable, Iterator, Mapping, TypeVar - -_T1 = TypeVar("_T1") -_T2 = TypeVar( - "_T2", "str", "int" -) # 'str' and 'int' should be treated as forward reference - - -class Foo(Iterable[_T2], Generic[_T1, _T2]): - def __init__(self, a: _T1, b: _T2): - pass - - def foo(self, a: _T1, b: _T2) -> _T2: - return b - - def __iter__(self) -> Iterator[int]: ... - - -a: Foo[int, str] = Foo(2, "") -b: str = a.foo(4, "") - - -# This should generate an error because a class shouldn't -# derive from Generic more than once. -class Bar(Generic[_T1], Generic[_T2]): - pass - - -K = TypeVar("K") -V = TypeVar("V") - - -# This should generate an error because V isn't included -# in the Generic type variable list. -class A(Mapping[K, V], Generic[K]): ... diff --git a/packages/vipeye-internal/src/tests/samples/genericType1.py b/packages/vipeye-internal/src/tests/samples/genericType1.py deleted file mode 100644 index 9cbfa38e..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType1.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests bidirectional type inference and constraint solving. - -m = int(1) -n = float(1.1) -p = "hello" - -a = dict(x=m, y=m) -a1: int = a["x"] - -b = dict(x=n, y=n) -reveal_type(b, expected_text="dict[str, float]") - -# This should generate an error. -b1: int = b["x"] -b2: float = b["x"] - -c = dict(x=m, y=n) -reveal_type(c, expected_text="dict[str, float]") - -# This should generate an error. -c1: int = c["x"] -c2: float = c["x"] - -d = dict(x=p, y=p) -reveal_type(d, expected_text="dict[str, str]") - -# This should generate an error. -d1: float = d["x"] -d2: str = d["x"] - -e = dict(x=n, y=p) -reveal_type(e, expected_text="dict[str, float | str]") - -# This should generate an error. -e1: str = e["x"] -# This should generate an error. -e2: float = e["x"] -e3: float | str = e["x"] diff --git a/packages/vipeye-internal/src/tests/samples/genericType10.py b/packages/vipeye-internal/src/tests/samples/genericType10.py deleted file mode 100644 index b8984e86..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType10.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where a bound TypeVar is bound to a -# class method. - -from typing import Any, Mapping, Type, TypeVar - -_Configuration = TypeVar("_Configuration", bound="Configuration") - - -class Configuration: - @classmethod - def _create( - cls: Type[_Configuration], data: Mapping[str, Any] - ) -> _Configuration: ... - - @classmethod - def _from_dict( - cls: Type[_Configuration], data: Mapping[str, Any] - ) -> _Configuration: - return cls._create({}) diff --git a/packages/vipeye-internal/src/tests/samples/genericType11.py b/packages/vipeye-internal/src/tests/samples/genericType11.py deleted file mode 100644 index 0b09bdf2..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType11.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests situations where bidirectional type inference -# influences the type of a generic function call. - -from typing import Callable, Iterable, List, Literal, TypeVar - -_T = TypeVar("_T") - - -def func1(arg: _T) -> _T: - return arg - - -v1: Literal["test"] = func1("test") - - -x: List[Literal["test"]] = ["test"] -v2: List[Literal["test"]] = func1(x) - - -def func2(arg: _T) -> List[_T]: - return [arg] - - -v3: List[Literal["test"]] = func2("test") - -v4 = func1("test") -reveal_type(v4, expected_text="str") - -v5 = func2("test") -reveal_type(v5, expected_text="List[str]") - - -def reduce(function: Callable[[_T, _T], _T], sequence: Iterable[_T]) -> _T: ... - - -dicts = [{"a": "b"}, {"c": "d"}] -v6 = reduce(lambda x, y: x | y, dicts) -reveal_type(v6, expected_text="dict[str, str]") - -v7 = reduce(lambda x, y: {**x, **y}, dicts) -reveal_type(v7, expected_text="dict[str, str]") - - -def func3(func: Callable[[_T], bool], b: dict[_T, int]) -> _T: - return next(iter(b.keys())) - - -def func4(func: Callable[[_T], bool]) -> _T: - return func3(func, {}) diff --git a/packages/vipeye-internal/src/tests/samples/genericType12.py b/packages/vipeye-internal/src/tests/samples/genericType12.py deleted file mode 100644 index d489425e..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType12.py +++ /dev/null @@ -1,60 +0,0 @@ -# This sample tests the case where the return type of a function is -# a generic Callable that can be specialized with type variables -# provided by the caller. - -from typing import Callable, List, TypeVar, Union - -_T = TypeVar("_T") - - -def identity_generic(x: _T) -> _T: - return x - - -def identity_callable_1(x: Callable[[_T], _T]) -> Callable[[_T], _T]: - return x - - -MyCallable = Callable[[_T], _T] - - -def identity_callable_2(x: MyCallable[_T]) -> MyCallable[_T]: - return x - - -def identity_int(x: int) -> int: - return x - - -v1 = identity_callable_1(identity_int) -reveal_type(v1, expected_text="(int) -> int") -reveal_type(v1(0), expected_text="int") - -v2 = identity_callable_1(identity_generic) -reveal_type(v2, expected_text="(_T@identity_generic) -> _T@identity_generic") -reveal_type(v2(0), expected_text="int") -reveal_type(v2(""), expected_text="str") - -v3 = identity_callable_2(identity_int) -reveal_type(v3, expected_text="(int) -> int") -reveal_type(v3(0), expected_text="int") - -v4 = identity_callable_2(identity_generic) -reveal_type(v4, expected_text="(_T@identity_generic) -> _T@identity_generic") -reveal_type(v4(0), expected_text="int") -reveal_type(v4(""), expected_text="str") - - -_U = TypeVar("_U") - - -def dec() -> Callable[[_U], _U]: ... - - -@dec() -def func1(x: _T, y: Union[_T, List[_T]]) -> None: - pass - - -func1(1, 2) -func1(1, [2, 3]) diff --git a/packages/vipeye-internal/src/tests/samples/genericType13.py b/packages/vipeye-internal/src/tests/samples/genericType13.py deleted file mode 100644 index f48497d9..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType13.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests that various types can be assigned to Type[Any]. - -from typing import Any, Type, TypeVar - - -class ClassA: ... - - -T = TypeVar("T") - - -def func1(x: Type[Any], y: Type[T]) -> T: - v1: Type[Any] = x - v2: Type[Any] = ClassA - v3: Type[Any] = y - - return y() diff --git a/packages/vipeye-internal/src/tests/samples/genericType14.py b/packages/vipeye-internal/src/tests/samples/genericType14.py deleted file mode 100644 index 833c3564..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType14.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests a case where Type[X] and X are used within the -# same class declaration. - -from typing import Generic, TypeVar -from dataclasses import dataclass, field - -K = TypeVar("K") -V = TypeVar("V") - - -@dataclass -class Registry(Generic[K, V]): - key: K - value: dict[str, V] = field(default_factory=dict) - - -class Base: - pass - - -BaseType = TypeVar("BaseType", bound=Base) - - -class BaseTypeRegistry(Registry[type[BaseType], BaseType]): - pass - - -class Thing1(Base): - pass - - -reveal_type(BaseTypeRegistry(Thing1), expected_text="BaseTypeRegistry[Thing1]") - -foo: BaseTypeRegistry[Thing1] = BaseTypeRegistry(Thing1) diff --git a/packages/vipeye-internal/src/tests/samples/genericType15.py b/packages/vipeye-internal/src/tests/samples/genericType15.py deleted file mode 100644 index a44c379b..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType15.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the assignment of invariant and contravariant -# type variables to other type variables. - - -from typing import Callable, Generic, TypeVar - - -T1 = TypeVar("T1") -T2 = TypeVar("T2") -T3 = TypeVar("T3") - - -class ClassA(Generic[T1]): ... - - -class ClassB(Generic[T2]): - def broken(self, p0: ClassA[T2], p1: Callable[[T2], object]): - func(p0, p1) - - -def func( - p0: ClassA[T3], - p1: Callable[[T3], object], -): ... diff --git a/packages/vipeye-internal/src/tests/samples/genericType16.py b/packages/vipeye-internal/src/tests/samples/genericType16.py deleted file mode 100644 index fba37256..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType16.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests a special case of bidirectional type inference when -# the expected type is a union and the destination type is a union that -# contains Any and a TypeVar. - - -from typing import Any, Literal, TypeVar - -_T = TypeVar("_T") - - -def func1(__o: object, __name: str, __default: _T) -> Any | _T: ... - - -x: Literal[1, 2, 3] = func1(object(), "", 1) - - -def func2(a: _T) -> bool | _T: ... - - -y = func2(None) -if y is not True: - z = y or func2(False) diff --git a/packages/vipeye-internal/src/tests/samples/genericType17.py b/packages/vipeye-internal/src/tests/samples/genericType17.py deleted file mode 100644 index d34c20db..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType17.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the handling of a generic type whose implementation -# includes the instantiation of another instance of itself using its -# own type parameters as type arguments. - -from typing import Generic, TypeVar - -A = TypeVar("A") -B = TypeVar("B") - - -class X(Generic[A, B]): - _dict: dict[A, B] - _pair: "X[B, A]" - - def method(self, a: A, b: B) -> None: - self._pair._dict[b] - - -x = X[int, str]() -x._pair._dict["foo"] - -reveal_type(x._pair, expected_text="X[str, int]") -reveal_type(x._pair._pair, expected_text="X[int, str]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType18.py b/packages/vipeye-internal/src/tests/samples/genericType18.py deleted file mode 100644 index c404acb4..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType18.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a generic function -# returns a generic Callable. - -from typing import Callable, TypeVar - - -_T = TypeVar("_T") - - -def func1(val1: _T) -> Callable[[_T], None]: - def f(a: str): ... - - # This should generate an error because str isn't - # compatible with _T. - return f - - -def func2(val1: _T) -> Callable[[_T], None]: - def f(a: _T): ... - - return f diff --git a/packages/vipeye-internal/src/tests/samples/genericType19.py b/packages/vipeye-internal/src/tests/samples/genericType19.py deleted file mode 100644 index d3881e7b..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType19.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests that a class that derives from Any can be used -# to satisfy a TypeVar. - -from typing import Any, TypeVar - - -T = TypeVar("T") - - -def foo(self, obj: T, foo: Any) -> T: - # NotImplemented is an instance of a class that derives from Any. - return NotImplemented diff --git a/packages/vipeye-internal/src/tests/samples/genericType2.py b/packages/vipeye-internal/src/tests/samples/genericType2.py deleted file mode 100644 index de60ce33..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType2.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the type checker's ability to do bidirectional -# type inference when the expected type is defined by a bound TypeVar. - -from typing import TypeVar - - -class A: - pass - - -class B(A): - pass - - -class C(A): - pass - - -_T_A = TypeVar("_T_A", bound=A) - - -def func1(value: dict[str, _T_A]) -> _T_A: - return value["a"] - - -x = func1({"b": B(), "c": C()}) -reveal_type(x, expected_text="B | C") diff --git a/packages/vipeye-internal/src/tests/samples/genericType20.py b/packages/vipeye-internal/src/tests/samples/genericType20.py deleted file mode 100644 index 8d9f0d3a..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType20.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a declared class variable with type -# type[T] is assigned a value in a base class that is not a type. - -from typing import Any, Generic, TypeVar - -T = TypeVar("T") - - -class Parent(Generic[T]): - y: type[T] - - -class Child(Parent[Any]): - # This should generate an error. - y = 42 diff --git a/packages/vipeye-internal/src/tests/samples/genericType21.py b/packages/vipeye-internal/src/tests/samples/genericType21.py deleted file mode 100644 index d8c6bb37..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType21.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample verifies that a type compatibility check that involves -# a union of a concrete type and a TypeVar does not depend on the order -# in the union. - -from typing import TypeVar - -_T = TypeVar("_T") - - -def f1(x: tuple[int | _T]) -> _T | None: - pass - - -def f2(x: tuple[_T | int]) -> None | _T: - pass - - -def g1(z: tuple[int] | tuple[_T]) -> _T | None: - reveal_type(f1(z), expected_text="_T@g1 | None") - reveal_type(f2(z), expected_text="_T@g1 | None") - - -def g2(z: tuple[_T] | tuple[int]) -> _T | None: - reveal_type(f1(z), expected_text="_T@g2 | None") - reveal_type(f2(z), expected_text="_T@g2 | None") diff --git a/packages/vipeye-internal/src/tests/samples/genericType22.py b/packages/vipeye-internal/src/tests/samples/genericType22.py deleted file mode 100644 index 0e45b63d..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType22.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that a generic callable passed to a function cannot -# be called with parameters that don't match the generic. - -from typing import TypeVar, Callable, Any - -T = TypeVar("T") - - -def func1(cb: Callable[[T], list[T]], param1: T, param2: Any, param3: Any | T) -> None: - cb(param1) - cb(param2) - cb(param3) - - # This should generate an error. - cb(0) diff --git a/packages/vipeye-internal/src/tests/samples/genericType23.py b/packages/vipeye-internal/src/tests/samples/genericType23.py deleted file mode 100644 index dca05975..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType23.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that a recursive call to a generic function -# evaluates correctly. - -# viper: strict - -from typing import TypeVar - -_T = TypeVar("_T") - - -def func1(x: list[_T]) -> list[_T]: - result = func1(x) - return result diff --git a/packages/vipeye-internal/src/tests/samples/genericType24.py b/packages/vipeye-internal/src/tests/samples/genericType24.py deleted file mode 100644 index 1663aa7c..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType24.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests a case where a default argument in a parent class -# needs to be specialized in the context of a child class. - -from typing import Generic, Iterable, Iterator, TypeVar - -T = TypeVar("T") - - -class IterableProxy(Iterable[T]): - def __iter__(self) -> Iterator[T]: ... - - -class Parent(Generic[T]): - def m1(self, v: Iterable[T] = IterableProxy()) -> None: ... - - -class Child(Parent[T]): - def m2(self) -> None: - self.m1() diff --git a/packages/vipeye-internal/src/tests/samples/genericType25.py b/packages/vipeye-internal/src/tests/samples/genericType25.py deleted file mode 100644 index fa218812..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType25.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that a union that includes two types that are subtypes -# of each other (like tuple[Any] and tuple[int]) is handled correctly -# when performing type compatibility tests. - -from typing import Any - - -def func(t: tuple[Any] | tuple[int]): - # This should generate a type violation. - x: int = t diff --git a/packages/vipeye-internal/src/tests/samples/genericType26.py b/packages/vipeye-internal/src/tests/samples/genericType26.py deleted file mode 100644 index cd1a981e..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType26.py +++ /dev/null @@ -1,82 +0,0 @@ -# This sample tests for the case where a generic callable type is -# specialized with type variables in a recursive manner. - -from dataclasses import dataclass -from typing import Callable, Generic, Iterable, Iterator, TypeVar, overload - -S = TypeVar("S") -T = TypeVar("T") -U = TypeVar("U") -V = TypeVar("V") - - -class ClassA(Generic[T, U]): - x: Callable[[T], U] - - def __init__(self, f: Callable[[T], U]): - self.x = f - - def __call__(self, x: T) -> U: - return self.x(x) - - def __add__(self, other: "ClassA[U, V]") -> "ClassA[T, V]": - f = self.x - g: Callable[[U], V] = other.x - return ClassA(lambda x: g(f(x))) - - -class ClassB(Generic[T]): - value: T - - def __init__(self, val: T) -> None: - self.value = val - - def method1(self, val: U) -> "ClassB[U]": - # This should generate an error. - return ClassB(self.value) - - -@dataclass -class DC1(Generic[T]): - value: T - - -@dataclass -class DC2(Generic[S]): - value: S - - -@dataclass -class ClassC(Generic[T, S]): - value: DC1[T] | DC2[S] - - def method1(self, val: U) -> "ClassC[U, S]": - if isinstance(self.value, DC1): - # This should generate an error. - return ClassC(self.value) - else: - return ClassC(self.value) - - -T_co = TypeVar("T_co", covariant=True) - - -class ClassD(Generic[T_co]): - @overload - def __init__(self, arg: Iterable[T_co]) -> None: ... - - @overload - def __init__(self, arg: Callable[[], Iterable[T_co]]) -> None: ... - - def __init__(self, arg: Iterable[T_co] | Callable[[], Iterable[T_co]]) -> None: ... - - def __iter__(self) -> Iterator[T_co]: ... - - -class ClassE(ClassD[T_co]): - def method(self) -> "ClassE[ClassE[T_co]]": - def inner(): - for x in self: - yield ClassE(lambda: [x]) - - return ClassE(inner) diff --git a/packages/vipeye-internal/src/tests/samples/genericType27.py b/packages/vipeye-internal/src/tests/samples/genericType27.py deleted file mode 100644 index e76972fb..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType27.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a type conditioned on a TypeVar -# is assigned to that same TypeVar in an invariant context. - -from typing import TypeVar - - -class ClassA: ... - - -T = TypeVar("T", bound=ClassA) - - -def func1(cls: type[T]) -> list[type[T]]: - result = [cls] - for c in cls.__subclasses__(): - result.extend(func1(c)) - return result diff --git a/packages/vipeye-internal/src/tests/samples/genericType28.py b/packages/vipeye-internal/src/tests/samples/genericType28.py deleted file mode 100644 index 5cefac83..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType28.py +++ /dev/null @@ -1,183 +0,0 @@ -# This sample tests that a class-scoped TypeVar used to parameterize -# a base class within a class definition cannot be covariant or -# contravariant if the base class requires an invariant type parameter. - -from typing import Generic, Sequence, TypeVar, TypeVarTuple, Unpack - -T = TypeVar("T") -T_co = TypeVar("T_co", covariant=True) -T_contra = TypeVar("T_contra", contravariant=True) - - -# This should generate an error because the type parameter for list -# is invariant, so T_co here cannot be covariant. -class Class1(list[T_co]): - pass - - -# This should generate an error because the type parameter for list -# is invariant, so T_co here cannot be contravariant. -class Class2(list[T_contra]): - pass - - -class Class3(Generic[T_co]): ... - - -class Class3_Child1(Class3[T_co]): ... - - -class Class3_Child2(Class3[T]): ... - - -# This should generate an error because T_contra isn't -# compatible with T_co. -class Class3_Child3(Class3[T_contra]): ... - - -class Class4(Generic[T_contra]): ... - - -class Class4_Child1(Class4[T_contra]): ... - - -class Class4_Child2(Class4[T]): ... - - -# This should generate an error because T_co isn't -# compatible with T_contra. -class Class4_Child3(Class4[T_co]): ... - - -class Class5(Generic[T_contra]): ... - - -class Class5_Child1(Class5[frozenset[T_contra]]): ... - - -# This should generate an error because Sequence[T_co] -# is covariant and is therefore not compatible with -# a contravariant type parameter. -class Class5_Child2(Class5[Sequence[T_co]]): ... - - -class Class5_Child3(Class5[Sequence[T]]): ... - - -class Class6(Generic[T_co, T_contra]): ... - - -class Class6_Child1(Class6[T_co, T_contra]): ... - - -# This should generate an error because T_co isn't -# compatible with T_contra. -class Class6_Child2(Class6[T_co, T_co]): ... - - -# This should generate an error because T_contra isn't -# compatible with T_co. -class Class6_Child3(Class6[T_contra, T_contra]): ... - - -class Class6_Child4(Class6[T, T]): ... - - -# This should generate an error because Sequence[T_co] isn't -# compatible with T_contra. -class Class6_Child5(Class6[Sequence[T_co], Sequence[T_co]]): ... - - -class Co(Generic[T_co]): ... - - -class Contra(Generic[T_contra]): ... - - -class CoToContra(Contra[Co[T_contra]]): ... - - -class ContraToContra(Contra[Contra[T_co]]): ... - - -class CoToCo(Co[Co[T_co]]): ... - - -class ContraToCo(Co[Contra[T_contra]]): ... - - -# This should generate an error. -class CoToContraToContra(Contra[Co[Contra[T_contra]]]): ... - - -# This should generate an error. -class ContraToContraToContra(Contra[Contra[Contra[T_co]]]): ... - - -Co_TA = Co[T_co] -Contra_TA = Contra[T_contra] - - -class CoToContra_WithTA(Contra_TA[Co_TA[T_contra]]): ... - - -class ContraToContra_WithTA(Contra_TA[Contra_TA[T_co]]): ... - - -class CoToCo_WithTA(Co_TA[Co_TA[T_co]]): ... - - -class ContraToCo_WithTA(Co_TA[Contra_TA[T_contra]]): ... - - -# This should generate an error. -class CoToContraToContra_WithTA(Contra_TA[Co_TA[Contra_TA[T_contra]]]): ... - - -# This should generate an error. -class ContraToContraToContra_WithTA(Contra_TA[Contra_TA[Contra_TA[T_co]]]): ... - - -Ts = TypeVarTuple("Ts") - - -class Variadic(Generic[Unpack[Ts]]): ... - - -class VariadicChild(Variadic[T]): ... - - -# This should generate an error. -class VariadicChildCo(Variadic[T_co]): ... - - -# This should generate an error. -class VariadicChildContra(Variadic[T_contra]): ... - - -Variadic_TA = Variadic[Unpack[tuple[int, Unpack[Ts]]]] - - -class VariadicChild_WithTA(Variadic_TA[T]): ... - - -# This should generate an error. -class VariadicChildCo_WithTA(Variadic_TA[T_co]): ... - - -# This should generate an error. -class VariadicChildContra_WithTA(Variadic_TA[T_contra]): ... - - -Variadic_TA2 = Variadic[Unpack[tuple[int, T]]] - - -class VariadicChild_WithTA2(Variadic_TA2[T]): ... - - -# This should generate an error. -class VariadicChildCo_WithTA2(Variadic_TA2[T_co]): ... - - -# This should generate an error. -class VariadicChildContra_WithTA2(Variadic_TA2[T_contra]): ... diff --git a/packages/vipeye-internal/src/tests/samples/genericType29.py b/packages/vipeye-internal/src/tests/samples/genericType29.py deleted file mode 100644 index 7652125a..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType29.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a contravariant type parameter -# has a union type that must be matched against another union -# type for purposes of bidirectional type inference. - -from typing import Generic, TypeVar - -T1 = TypeVar("T1", contravariant=True) -T2 = TypeVar("T2") - - -class A(Generic[T1]): ... - - -def func1(x: A[T2]) -> A[T2 | None]: ... - - -x1: A[int | None] = func1(A[int]()) diff --git a/packages/vipeye-internal/src/tests/samples/genericType3.py b/packages/vipeye-internal/src/tests/samples/genericType3.py deleted file mode 100644 index eee5d179..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType3.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the type checker's handling of constructors -# that specify a specialized class type. - -from typing import Generic, TypeVar, Callable - -T = TypeVar("T", bound=float) - - -class Root(Generic[T]): - def __init__(self, _lambda: Callable[[T], T]): - self._lambda = _lambda - - def call(self, val: T) -> T: - return self._lambda(val) - - -class Leaf(Root[T]): - pass - - -root_int: Root[int] = Root[int](lambda x: x << 2) - -# This should generate an error. -root_float: Root[float] = root_int - -# This should generate an error. -root_float: Root[float] = Root[int](lambda x: x << 2) diff --git a/packages/vipeye-internal/src/tests/samples/genericType30.py b/packages/vipeye-internal/src/tests/samples/genericType30.py deleted file mode 100644 index 7defeea9..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType30.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where a specialized generic class references -# itself in a magic method like __iter__. - -from typing import Iterator, Generic, TypeVar - -A = TypeVar("A") - - -class Iter(Generic[A]): - def __iter__(self) -> Iterator[A]: ... - - def enumerate(self) -> "Iter[tuple[int, A]]": ... - - def method1(self) -> None: - for x in self.enumerate(): - reveal_type(x, expected_text="tuple[int, A@Iter]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType31.py b/packages/vipeye-internal/src/tests/samples/genericType31.py deleted file mode 100644 index d52e407a..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType31.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the assignment of unions that contain TypeVars. - -from typing import TypeVar - - -T = TypeVar("T") - - -def func1(x: T | None) -> T | str: - # This should generate an error. - return x - - -def func2(x: T | int) -> T | str: - # This should generate an error. - return x diff --git a/packages/vipeye-internal/src/tests/samples/genericType32.py b/packages/vipeye-internal/src/tests/samples/genericType32.py deleted file mode 100644 index e8df863a..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType32.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where a invariant type parameter is used -# within a contravariant type argument. - -from typing import TypeVar, Generic - -T = TypeVar("T") -T_contra = TypeVar("T_contra", contravariant=True) - - -class Contra(Generic[T_contra]): ... - - -class Foo(Generic[T]): ... - - -class Bar(Foo[T]): ... - - -def func(x: Contra[Foo[int]]): - v: Contra[Bar[int]] = x diff --git a/packages/vipeye-internal/src/tests/samples/genericType33.py b/packages/vipeye-internal/src/tests/samples/genericType33.py deleted file mode 100644 index 5a6f623e..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType33.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the case where a contravariant TypeVar is used in a protocol. - -from typing import Generic, Protocol, TypeVar - -T_contra = TypeVar("T_contra", contravariant=True) - - -class Contra(Generic[T_contra]): ... - - -class Foo(Protocol[T_contra]): - def f(self) -> Contra[T_contra]: ... - - -def t1(x: Foo[T_contra]) -> list[T_contra] | None: ... - - -def t2(x: Foo[object]) -> None: ... - - -def func1(x: Foo[T_contra]) -> list[T_contra] | None: - # This should generate an error. - t2(x) - - -def func2(x: Foo[object]) -> None: - t1(x) diff --git a/packages/vipeye-internal/src/tests/samples/genericType34.py b/packages/vipeye-internal/src/tests/samples/genericType34.py deleted file mode 100644 index 2cc39000..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType34.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests bidirectional type inference for the call of a generic -# method that returns a generic type with multiple type arguments where -# some of these type arguments can be satisfied directly by the expected -# type's type arguments and some cannot. - -from typing import Generic, Literal, TypeVar - -_T_co = TypeVar("_T_co", covariant=True) -_N = TypeVar("_N", bound=int) - - -class ClassA(Generic[_T_co, _N]): ... - - -def func1(n: _N) -> ClassA[Literal[0], _N]: ... - - -v1: ClassA[int, Literal[1]] = func1(1) diff --git a/packages/vipeye-internal/src/tests/samples/genericType35.py b/packages/vipeye-internal/src/tests/samples/genericType35.py deleted file mode 100644 index e58f3a1a..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType35.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where a function that includes a tuple -# parameter type is assignable to a generic callable that also includes -# a tuple type. - -from typing import Callable, TypeVar - -X = TypeVar("X") -Y = TypeVar("Y") - - -def deco1(func: Callable[[tuple[X]], Y]) -> Callable[[X], Y]: ... - - -def func1(x: tuple[str]) -> int: ... - - -v1 = deco1(func1) -reveal_type(v1, expected_text="(str) -> int") - - -def deco2(func: Callable[[tuple[X, ...]], Y]) -> Callable[[X], Y]: ... - - -def func2(x: tuple[str]) -> int: ... - - -# This should generate an error because of a tuple size mismatch. -deco2(func2) diff --git a/packages/vipeye-internal/src/tests/samples/genericType36.py b/packages/vipeye-internal/src/tests/samples/genericType36.py deleted file mode 100644 index 255df5f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType36.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the case where bidirectional type inference is used -# for a call expression that returns a callable and requires bidirectional -# type inference to determine the desired results and the expected type -# is a union that includes some non-callable types. - -from typing import Callable, Literal, TypeVar - -ABC = Literal["a", "b", "c"] -T = TypeVar("T") - - -def func1(x: T | Callable[[], T]) -> Callable[[], T]: ... - - -def func2(a: Callable[[], ABC] | ABC, b: ABC | Callable[[], ABC]): - v1 = func1(a) - reveal_type(v1, expected_text="() -> str") - - v2 = func1(b) - reveal_type(v2, expected_text="() -> str") - - v3: Callable[[], ABC] = func1(a) - reveal_type(v3, expected_text="() -> Literal['a', 'b', 'c']") - - v4: Callable[[], ABC] = func1(b) - reveal_type(v4, expected_text="() -> Literal['a', 'b', 'c']") diff --git a/packages/vipeye-internal/src/tests/samples/genericType37.py b/packages/vipeye-internal/src/tests/samples/genericType37.py deleted file mode 100644 index d4b4e355..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType37.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests bidirectional type inference for cases that involve -# constructors and dict inference. - -from typing import TypeVar - -T = TypeVar("T") - - -def func1(some_dict: dict[str, set[T] | frozenset[T]]) -> list[T]: - return [] - - -v1 = func1({"foo": set({1, 2, 3})}) -reveal_type(v1, expected_text="list[int]") - -v2 = func1({"foo": frozenset({1, 2, 3})}) -reveal_type(v2, expected_text="list[int]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType38.py b/packages/vipeye-internal/src/tests/samples/genericType38.py deleted file mode 100644 index d4cbd05d..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType38.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests bidirectional type inference with nested constructors. - -from typing import Generic, Iterable, Iterator, TypeVar, overload, Any -from itertools import chain - -_T = TypeVar("_T") - - -class ClassA(Generic[_T]): - @overload - def __init__(self, _: _T): ... - - @overload - def __init__(self, _: Any): ... - - def __init__(self, _: Any): ... - - -class ClassB(Generic[_T]): - def __init__(self, _: ClassA[_T]): ... - - -v1 = ClassA(0) -v2 = ClassB(v1) -v3 = ClassB(ClassA(0)) - -reveal_type(v1, expected_text="ClassA[int]") -reveal_type(v2, expected_text="ClassB[int]") -reveal_type(v3, expected_text="ClassB[int]") - - -def func1(x: list[_T], /) -> list[_T]: - return x - - -def func2(any: Any): - v1 = list([any]) - v2 = func1(v1) - v3 = func1(list([any])) - - reveal_type(v1, expected_text="list[Any]") - reveal_type(v2, expected_text="list[Any]") - reveal_type(v3, expected_text="list[Any]") - - -def func3(val1: Iterator[Iterable[int]]): - val2 = list(chain.from_iterable(val1)) - reveal_type(val2, expected_text="list[int]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType39.py b/packages/vipeye-internal/src/tests/samples/genericType39.py deleted file mode 100644 index f2bc199b..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType39.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests bidirectional type inference for a generic class -# constructor that is passed an argument expression that contains a -# binary operator. - - -def func1(x: list[str] | None): - for _, v in enumerate(x or []): - reveal_type(v, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/genericType4.py b/packages/vipeye-internal/src/tests/samples/genericType4.py deleted file mode 100644 index e503fcd4..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType4.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the type checker's handling of derived specialized -# objects assigned to their parent class type (also specialized). - -from typing import Generic, TypeVar - -T = TypeVar("T", bound=float) - - -class Base1(Generic[T]): - pass - - -class Derived1(Base1[T]): - pass - - -val1: Base1[int] = Derived1[int]() - - -class Base2(Generic[T]): - pass - - -class Derived2(Base2[float], Generic[T]): - pass - - -val2_1: Base2[float] = Derived2[int]() - -# This should generate an error because Derived2[int] -# isn't assignable to Base2[int]. -val2_2: Base2[int] = Derived2[int]() diff --git a/packages/vipeye-internal/src/tests/samples/genericType40.py b/packages/vipeye-internal/src/tests/samples/genericType40.py deleted file mode 100644 index 94804470..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType40.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the case where a generic function returns a generic -# Callable. There are certain cases where we want the type variables in -# the return type to be rescoped to the return callable. - -from typing import Callable, TypeVar - - -_T1 = TypeVar("_T1") - - -def func1(a: _T1 | None) -> Callable[[_T1], _T1]: ... - - -v1 = func1(None) -reveal_type(v1, expected_text="(Unknown) -> Unknown") - - -def func2(a: None) -> Callable[[_T1], _T1]: ... - - -v2 = func2(None) -reveal_type(v2, expected_text="(_T1@func2) -> _T1@func2") - - -def func3(a: None) -> Callable[[type[_T1]], type[_T1]]: ... - - -v3 = func3(None) -reveal_type(v3, expected_text="(type[_T1@func3]) -> type[_T1@func3]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType41.py b/packages/vipeye-internal/src/tests/samples/genericType41.py deleted file mode 100644 index 86c49c90..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType41.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the case where a generic function that returns a tuple -# is called with an expected type. - -from typing import Iterable, Literal, TypeVar - -A = TypeVar("A") -B = TypeVar("B") - - -def func1(a: A, b: B) -> tuple[Iterable[A], Iterable[B]]: - return ((a,), (b,)) - - -def func2(a: A, b: B) -> tuple[Iterable[B], Iterable[A]]: - return ([b], [a]) - - -def func3() -> tuple[Iterable[str], Iterable[int]]: - return func1("", 3) - - -def func4() -> tuple[Iterable[Literal["hi"]], Iterable[Literal[3]]]: - return func2(3, "hi") diff --git a/packages/vipeye-internal/src/tests/samples/genericType42.py b/packages/vipeye-internal/src/tests/samples/genericType42.py deleted file mode 100644 index b009c9f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType42.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the case where a generic function call is nested -# within itself. - -from typing import Callable, ParamSpec, Protocol, Type, TypeVar, Union, overload -from itertools import chain - -P = ParamSpec("P") -R = TypeVar("R") -T = TypeVar("T", covariant=True) - - -def func1(): - return [ - f"{12 if hour == 0 else hour!s}:{minute!s:0>2} {meridian}" - for hour, minute, meridian in chain.from_iterable( - chain.from_iterable( - [(hour, minute, meridian) for minute in range(0, 60, 15)] - for hour in range(12) - ) - for meridian in ("am", "pm") - ) - ] - - -class A(Protocol[T, P]): - def __init__(self, *args: P.args, **kwds: P.kwargs): ... - - -def make_a(x: Callable[P, R]) -> Type[A[R, P]]: ... - - -@overload -def func2(x: Type[A[R, P]]) -> Type[A[R, P]]: ... - - -@overload -def func2(x: Callable[P, R]) -> Type[A[R, P]]: ... - - -def func2(x: Union[Type[A[R, P]], Callable[P, R]]) -> Type[A[R, P]]: ... - - -def func3(): - def foo(x: int) -> str: ... - - x = make_a(foo) - y = func2(x) - z = func2(make_a(foo)) - - reveal_type(y, expected_text="type[A[str, (x: int)]]") - reveal_type(z, expected_text="type[A[str, (x: int)]]") - - -def func4(my_dict: dict[str, str]): - reveal_type(my_dict.get("item1", ""), expected_text="str") - reveal_type(my_dict.get("item1", my_dict.get("item2", "")), expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/genericType43.py b/packages/vipeye-internal/src/tests/samples/genericType43.py deleted file mode 100644 index addbfe41..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType43.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests bidirectional type inference in cases where the -# expected type is a union of multiple class instances. - -from typing import Iterable, Sequence - - -def func1(points: tuple[float, float] | Iterable[tuple[float, float]]) -> None: ... - - -def test1(val: tuple[float, float]): - func1(tuple((val, val))) - - -def func2(points: tuple[float, float] | Sequence[tuple[float, float]]) -> None: ... - - -def test2(val: tuple[float, float]): - func2(tuple([val, val])) - - -def func3(points: tuple[float, float] | tuple[str, str]) -> None: ... - - -def test3(val: tuple[float, float]): - func3(val) diff --git a/packages/vipeye-internal/src/tests/samples/genericType44.py b/packages/vipeye-internal/src/tests/samples/genericType44.py deleted file mode 100644 index 3ff2786e..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType44.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case where a protocol uses a covariant -# type parameter but a corresponding implementation uses an -# invariant type parameter. Literal types need to be handled -# carefully in this case. - -from typing import Any, Awaitable, Generator, Literal, TypeVar - -_T = TypeVar("_T") - - -class Future(Awaitable[_T]): - def __await__(self) -> Generator[Any, None, _T]: ... - - -def func1(future: Future[_T]) -> Future[_T]: ... - - -def func2(cb: Awaitable[_T]) -> Future[_T]: ... - - -def func3() -> Awaitable[Literal[True]]: ... - - -v1 = func1(func2(func3())) -reveal_type(v1, expected_text="Future[Literal[True]]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType45.py b/packages/vipeye-internal/src/tests/samples/genericType45.py deleted file mode 100644 index ce033c55..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType45.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests that invariance is properly enforced when appropriate. - -from typing import Any, TypeVar - -T = TypeVar("T") - - -def func1(v: list[float | str]): - # This should generate an error. - x1: list[float] = v - - x2: list[str | float] = v - - # This should generate an error. - x3: list[float | str | None] = v - - x4: list[Any | str] = v - - # This should generate an error. - x5: list[int | str] = v - - x6: list[float | int | str] = v - - -def func2(v: list[T]) -> T: - x1: list[T] = v - - x2: list[Any | T] = v - - # This should generate an error. - x3: list[int | T] = v - - return v[0] - - -def func3(v: list[float | T]) -> float | T: - # This should generate an error. - x1: list[T] = v - - x2: list[Any | T] = v - - x3: list[T | float] = v - - # This should generate an error. - x4: list[T | int] = v - - x5: list[float | int | T] = v - - return v[0] - - -def func4(v: list[Any | int | str]): - x1: list[Any | int] = v - - x2: list[Any | list[str]] = v - - x3: list[Any | int | str | list[str]] = v diff --git a/packages/vipeye-internal/src/tests/samples/genericType46.py b/packages/vipeye-internal/src/tests/samples/genericType46.py deleted file mode 100644 index feb44448..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType46.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests calls to a generic class constructor from within the class. - -from typing import Callable, Generic, TypeVar - -T = TypeVar("T") -U = TypeVar("U") -W = TypeVar("W") - - -class ClassA(Generic[T]): - def __init__(self, vals: list[U], func: Callable[[U], T]): - self._vals = list(map(func, vals)) - - def method1(self, func: Callable[[T], W]) -> "ClassA[W]": - return ClassA(self._vals, func) - - -class ClassB(Generic[T]): - def __init__(self, vals: list[U], func: Callable[[U], T]): - self._vals = list(map(func, vals)) - - def method1(self, func: Callable[[T], W]) -> "ClassB[W]": - return func0(self, func) - - -def func0(c: ClassB[T], func: Callable[[T], W]) -> ClassB[W]: - return ClassB(c._vals, func) - - -class ClassC(Generic[T, U]): - def __init__(self): - pass - - def test2(self) -> None: - x1: ClassC[U, T] - x1 = ClassC[U, T]() diff --git a/packages/vipeye-internal/src/tests/samples/genericType47.py b/packages/vipeye-internal/src/tests/samples/genericType47.py deleted file mode 100644 index bedad80b..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType47.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests specialization of nested generic classes. - -# viper: strict - - -from typing import Collection, Generic, Iterable, Iterator, TypeVar - -A = TypeVar("A") -T = TypeVar("T") - - -class ClassA(Collection[T]): - def __init__(self, value: Iterable[T]) -> None: - self.values = tuple(value) - - def __contains__(self, item: object) -> bool: - return True - - def __iter__(self) -> Iterator[T]: - return iter(self.values) - - def __len__(self) -> int: - return len(self.values) - - -class ClassB(Generic[T]): - pass - - -def func1(input: ClassA[ClassB[A]]) -> ClassB[ClassA[A]]: - v = input.values - result = func1(ClassA(v)) - - return result diff --git a/packages/vipeye-internal/src/tests/samples/genericType5.py b/packages/vipeye-internal/src/tests/samples/genericType5.py deleted file mode 100644 index 859e7085..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType5.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests bidirectional inference when the type derives from the -# expected type and both are generic. - -from typing import Generic, Iterable, Mapping, TypeVar - -v0: Mapping[str, int | str] | None = dict([("test1", 1), ("test2", 2)]) - -v1: Mapping[str, float] | None = dict([("test1", 1), ("test2", 2)]) - -# This should generate an error because of a type mismatch. -v2: Mapping[str, str] = dict([("test1", 1), ("test2", "2")]) - - -options: dict[int | str, int] = {} -channel_types: dict[str, int] = {} - -keys = channel_types.keys() - -options.update(dict.fromkeys(keys, 1)) - - -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") -_S = TypeVar("_S") -_T = TypeVar("_T") -_X = TypeVar("_X") - - -class A(Generic[_KT, _VT]): - @classmethod - def method1(cls, i: Iterable[_T], v: _S) -> "A[_T, _S]": ... - - -def func1(__x: A[int, _X] | A[str, _X] | A[str | int, _X]) -> A[int, _X]: ... - - -v3 = func1(A.method1("a", "b")) -reveal_type(v3, expected_text="A[int, str]") - -v4 = str.maketrans(dict.fromkeys("a", "b")) -reveal_type(v4, expected_text="dict[int, str]") diff --git a/packages/vipeye-internal/src/tests/samples/genericType6.py b/packages/vipeye-internal/src/tests/samples/genericType6.py deleted file mode 100644 index fbf1b334..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType6.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample verifies that the use of a bound TypeVar defined -# by a generic class is not used inappropriately. - -from typing import Any, Generic, TypeVar - - -class ClassA: ... - - -_T = TypeVar("_T", bound=ClassA) - - -class ClassB(Generic[_T]): - def func1(self, a: _T): - pass - - def func2(self, y: _T): - x: int = 3 - # This should generate an error - self.func1(x) - - self.func1(y) - - z: Any = 3 - self.func1(z) diff --git a/packages/vipeye-internal/src/tests/samples/genericType7.py b/packages/vipeye-internal/src/tests/samples/genericType7.py deleted file mode 100644 index f5372682..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType7.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the handling of TypeVars defined by -# a generic function. - -from typing import Generic, TypeVar - - -class ClassA: - pass - - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2", bound=ClassA) -_T2A = TypeVar("_T2A", bound=ClassA) -_T3 = TypeVar("_T3", ClassA, int, str) - - -class Class1(Generic[_T1]): - def __init__(self, a: _T1): - self._a: dict[str, _T1] = {} - self._b: tuple[_T1, ...] = (a, a, a) - self._c: tuple[_T1, _T1] = (a, a) - self._d: list[_T1] = [a] - - -class Class2(Generic[_T2]): - def __init__(self, a: _T2): - self._a: dict[str, _T2] = {} - self._b: tuple[_T2, ...] = (a, a, a) - self._c: tuple[_T2, _T2] = (a, a) - self._d: list[_T2] = [a] - - -class Class2A(Generic[_T2, _T2A]): - def __init__(self, a: _T2, b: _T2A): - self._a1: dict[str, _T2A] = {"a": b} - self._a2: dict[str, _T2] = {"a": a} - self._b: tuple[_T2, ...] = (a, a, a) - self._c: tuple[_T2, _T2] = (a, a) - self._d: list[_T2] = [a] - - -class Class3(Generic[_T3]): - def __init__(self, a: _T3): - self._a: dict[str, _T3] = {} - self._b: tuple[_T3, ...] = (a, a, a) - self._c: tuple[_T3, _T3] = (a, a) - self._d: list[_T3] = [a] - - -class Animal: - pass - - -class Cow(Animal): - pass - - -_TA = TypeVar("_TA", bound=Animal) - - -def fn(p2: _TA) -> _TA: - # This should generate an error. - p2 = Animal() - - if 1 + 1 == 3: - return p2 - - # This should generate an error. - return Animal() diff --git a/packages/vipeye-internal/src/tests/samples/genericType8.py b/packages/vipeye-internal/src/tests/samples/genericType8.py deleted file mode 100644 index 8cf936d6..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType8.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests that default parameter values can be assigned -# to types that are generic. - -from typing import Generic, List, Type, TypeVar - - -class ClassA: - pass - - -T_A = TypeVar("T_A", bound=ClassA) -T = TypeVar("T") - - -class ClassB(Generic[T_A, T]): - def __init__( - self, - p1: Type[T_A] = ClassA, - p2: List[T] = [], - # This should generate an error. - p3: List[T_A] = [2], - p4: List[T] = [2], - ): - pass diff --git a/packages/vipeye-internal/src/tests/samples/genericType9.py b/packages/vipeye-internal/src/tests/samples/genericType9.py deleted file mode 100644 index 4fb1d9a1..00000000 --- a/packages/vipeye-internal/src/tests/samples/genericType9.py +++ /dev/null @@ -1,43 +0,0 @@ -# This sample tests the case where a method is invoked on a -# generic class that is not specialized prior to binding to -# the method but is specialized implicitly via the arguments -# to the method. - -from typing import Generic, TypeVar - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - - -class ClassA(Generic[_T1]): - @staticmethod - def func1(value: _T1) -> "ClassA[_T1]": - return ClassA[_T1]() - - @classmethod - def func2(cls, value: _T1) -> "ClassA[_T1]": - return cls() - - -class ClassASub1(ClassA[_T2]): - pass - - -class ClassASub2(ClassA[int]): - pass - - -def test1(val_str: str, val_int: int): - reveal_type(ClassA.func1(val_str), expected_text="ClassA[Unknown]") - reveal_type(ClassASub1.func1(val_str), expected_text="ClassA[Unknown]") - reveal_type(ClassASub2.func1(val_int), expected_text="ClassA[int]") - - # This should generate an error because the argument type doesn't match. - ClassASub2.func1(val_str) - - reveal_type(ClassA.func2(val_str), expected_text="ClassA[Unknown]") - reveal_type(ClassASub1.func2(val_str), expected_text="ClassA[Unknown]") - reveal_type(ClassASub2.func2(val_int), expected_text="ClassA[int]") - - # This should generate an error because the argument type doesn't match. - ClassASub2.func2(val_str) diff --git a/packages/vipeye-internal/src/tests/samples/hashability1.py b/packages/vipeye-internal/src/tests/samples/hashability1.py deleted file mode 100644 index 55dd4873..00000000 --- a/packages/vipeye-internal/src/tests/samples/hashability1.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the check for hashability that applies to entries -# within a set expression and keys within a dictionary expression. - -# viper: reportIncompatibleVariableOverride=false - -from dataclasses import dataclass -from typing import Any - - -# This should generate two errors because {} and [] are not hashable. -s1 = {{}, 2, dict, frozenset(), []} - -# This should generate two errors because {} and [] are not hashable. -s2: set[Any] = {{}, 2, dict, frozenset(), []} - - -class StrList(list[str]): - def __hash__(self) -> int: ... - - -s3 = {StrList()} - - -# This should generate two errors because {} and [] are not hashable. -d1 = {{}: None, None: 2, dict: 3, frozenset(): 4, []: ""} - -# This should generate two errors because {} and [] are not hashable. -d2: dict[Any, Any] = {{}: None, None: 2, dict: 3, frozenset(): 4, []: ""} - - -def func1(x: str | dict[Any, Any], y: Any, z: None): - # This should generate an error because dict isn't hashable - d3 = {x: "hi"} - - d4 = {y: "hi", z: "hi"} - - -@dataclass -class DC1: - a: int - - -@dataclass(frozen=True) -class DC2: - a: int - - -dc1 = DC1(0) - -# This should generate an error because a non-frozen -# dataclass is not hashable. -d5 = {dc1: 100} - - -dc2 = DC2(0) -d6 = {dc2: 100} diff --git a/packages/vipeye-internal/src/tests/samples/hashability2.py b/packages/vipeye-internal/src/tests/samples/hashability2.py deleted file mode 100644 index d1c606b1..00000000 --- a/packages/vipeye-internal/src/tests/samples/hashability2.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests that unhashable user classes are detected as unhashable. - -# viper: reportIncompatibleMethodOverride=false - - -class A: ... - - -s1 = {A()} -d1 = {A(): 100} - - -class B: - def __eq__(self, other): ... - - -# Both of these should generate an error because a class that -# defines __eq__ but not __hash__ is not hashable. -s2 = {B()} -d2 = {B(): 100} - - -class C: - __hash__: None = None - - -class D(B, C): ... - - -# Both of these should generate an error because B is unhashable. -s3 = {D()} -d3 = {D(): 100} - - -class E: - def __hash__(self): ... - - -class F(D, E): ... - - -# Both of these should generate an error because D is unhashable. -s4 = {F()} -d4 = {F(): 100} - - -class G(E, D): ... - - -s5 = {G()} -d5 = {G(): 100} diff --git a/packages/vipeye-internal/src/tests/samples/hashability3.py b/packages/vipeye-internal/src/tests/samples/hashability3.py deleted file mode 100644 index ae74edfc..00000000 --- a/packages/vipeye-internal/src/tests/samples/hashability3.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests that __hash__ is set to None if -# __hash__ isn't set but __eq__ is. - - -class A: ... - - -A().__hash__() - - -class B: - def __eq__(self, value: object) -> bool: ... - - ... - - -# This should generate an error because __hash__ is implicitly set to None -# for a class that defines __eq__ but not __hash__. -B().__hash__() diff --git a/packages/vipeye-internal/src/tests/samples/import1.py b/packages/vipeye-internal/src/tests/samples/import1.py deleted file mode 100644 index 380c59fd..00000000 --- a/packages/vipeye-internal/src/tests/samples/import1.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests the type analyzer's handling of the built-in -# __import__ function. - -reveal_type(__path__, expected_text="MutableSequence[str]") - -# This should not generate a type error. -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/vipeye-internal/src/tests/samples/import10.py b/packages/vipeye-internal/src/tests/samples/import10.py deleted file mode 100644 index 7d1cef89..00000000 --- a/packages/vipeye-internal/src/tests/samples/import10.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the handling of an unresolved import. -# It should report a single error but not have cascading -# errors when the unresolved symbol is used. - -# This should generate an error. -import unresolved_import - - -def test_zero_division(): - with unresolved_import.raises(ZeroDivisionError): - v = 1 / 0 diff --git a/packages/vipeye-internal/src/tests/samples/import11.py b/packages/vipeye-internal/src/tests/samples/import11.py deleted file mode 100644 index 295f1c61..00000000 --- a/packages/vipeye-internal/src/tests/samples/import11.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests that the type checker properly handles -# the "from .decoder import JSONDecodeError" statement in -# the json/__init__.pyi type stub file. According to PEP 484, -# this import statement should cause the json module to export -# not only the symbol JSONDecodeError but also the symbol -# "decoder". - -import json - -a = json.decoder.JSONDecodeError -b = json.JSONDecodeError diff --git a/packages/vipeye-internal/src/tests/samples/import12.py b/packages/vipeye-internal/src/tests/samples/import12.py deleted file mode 100644 index c2444539..00000000 --- a/packages/vipeye-internal/src/tests/samples/import12.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the reportWildcardImportFromLibrary option. - -# This should generate a warning or error depending on whether -# strict mode is enabled. -from typing import * - -# This should also generate the same warning or error. It's here to -# a double (redundant) wildcard import. -from typing import * - - -reveal_type(Dict, expected_text="type[Dict[Unknown, Unknown]]") diff --git a/packages/vipeye-internal/src/tests/samples/import13.py b/packages/vipeye-internal/src/tests/samples/import13.py deleted file mode 100644 index 435ff8f4..00000000 --- a/packages/vipeye-internal/src/tests/samples/import13.py +++ /dev/null @@ -1,5 +0,0 @@ -# This sample is used in conjunction with import14.py to test -# PEP 562 (module-level __getattr__) support. - - -def __getattr__(name: str) -> int: ... diff --git a/packages/vipeye-internal/src/tests/samples/import14.py b/packages/vipeye-internal/src/tests/samples/import14.py deleted file mode 100644 index 60ef227f..00000000 --- a/packages/vipeye-internal/src/tests/samples/import14.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample is used in conjunction with import13.py to test -# PEP 562 (module-level __getattr__) support. - -# viper: strict - -from .import13 import foo1 -from . import import13 - -reveal_type(foo1, expected_text="int") -reveal_type(import13.foo2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/import15.py b/packages/vipeye-internal/src/tests/samples/import15.py deleted file mode 100644 index 1b62bb5c..00000000 --- a/packages/vipeye-internal/src/tests/samples/import15.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the case where a symbol is imported from two different -# sources, one of them in a try block and another in an except block. - -try: - from typing import TypedDict -except ImportError: - from typing_extensions import TypedDict # viper: ignore[reportMissingModuleSource] - - -class TD1(TypedDict): - x: int diff --git a/packages/vipeye-internal/src/tests/samples/import16.py b/packages/vipeye-internal/src/tests/samples/import16.py deleted file mode 100644 index 228354d3..00000000 --- a/packages/vipeye-internal/src/tests/samples/import16.py +++ /dev/null @@ -1,6 +0,0 @@ -# This source ensures that a multi-part import statement without an alias -# implicitly imports all modules in the multi-part chain. - -import html.entities - -x = html.escape diff --git a/packages/vipeye-internal/src/tests/samples/import17.py b/packages/vipeye-internal/src/tests/samples/import17.py deleted file mode 100644 index 412af22c..00000000 --- a/packages/vipeye-internal/src/tests/samples/import17.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample is used by import18.py. - -a: str = "hi" -b: float = 1.0 -c: int - -_d: int -__e__: int diff --git a/packages/vipeye-internal/src/tests/samples/import18.py b/packages/vipeye-internal/src/tests/samples/import18.py deleted file mode 100644 index 448d3c4d..00000000 --- a/packages/vipeye-internal/src/tests/samples/import18.py +++ /dev/null @@ -1,11 +0,0 @@ -# This should generate two errors because b and c overwrite declared -# types in an incompatible manner. -from .import17 import * - -a: str -b: str -c: str - -_d: str -__e__: str -g: str diff --git a/packages/vipeye-internal/src/tests/samples/import2.py b/packages/vipeye-internal/src/tests/samples/import2.py deleted file mode 100644 index 42574e5c..00000000 --- a/packages/vipeye-internal/src/tests/samples/import2.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests import resolution for relative imports. - -from datetime import datetime - -# This should generate an error because relative imports can -# be used only with the "from . import A" form. -import .package1 as p0 - -from . import package1 as p1 -a = p1.foo() - -from .package1 import foo -b = foo() - -# This should generate an error because there is no -# directory or file named packageXXX. -from . import packageXXX as p2 - -from .package1.sub import subfoo -# subfoo should resolve to the package1/sub/__init__.py, -# which returns a datetime. Verify that it does. -c: datetime = subfoo() - -from .package1.psyche import psyche1 -# This should resolve to package1/psyche.py even though -# there is a package1/psyche directory present. -d: int = psyche1() diff --git a/packages/vipeye-internal/src/tests/samples/import3.py b/packages/vipeye-internal/src/tests/samples/import3.py deleted file mode 100644 index 6fea83b1..00000000 --- a/packages/vipeye-internal/src/tests/samples/import3.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample is imported by import4.py. - -__all__ = ["foo", "_foo", "_bar"] - -foo = 3 -_foo = 4 -bar = 5 -_bar = 6 diff --git a/packages/vipeye-internal/src/tests/samples/import4.py b/packages/vipeye-internal/src/tests/samples/import4.py deleted file mode 100644 index 234f7ccf..00000000 --- a/packages/vipeye-internal/src/tests/samples/import4.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests wildcard imports. - -from .import3 import * - -a = foo -b = _foo - -# This should generate an error because bar isn't -# included in the __all__ assignment. -c = bar -d = _bar - -# This should generate an error because a trailing comma -# isn't allowed in a "from import" statement without parens. -from .import3 import foo, diff --git a/packages/vipeye-internal/src/tests/samples/import5.py b/packages/vipeye-internal/src/tests/samples/import5.py deleted file mode 100644 index 5944a8f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/import5.py +++ /dev/null @@ -1,6 +0,0 @@ -# This sample is imported by import6.py. - -foo = 3 -__foo = 4 -bar = 5 -_bar = 6 diff --git a/packages/vipeye-internal/src/tests/samples/import6.py b/packages/vipeye-internal/src/tests/samples/import6.py deleted file mode 100644 index dd2142ca..00000000 --- a/packages/vipeye-internal/src/tests/samples/import6.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests wildcard imports. - -from .import5 import * - -a = foo - -# This should generate an error because there is no -# __all__ assignment, and names starting with a double underscore -# should not be imported in a wildcard. -b = __foo - -c = bar - -# This should generate an error because there is no __all__ assignment -# and names starting with a single underscore should not be imported -# in a wildcard. -d = _bar diff --git a/packages/vipeye-internal/src/tests/samples/import7.py b/packages/vipeye-internal/src/tests/samples/import7.py deleted file mode 100644 index 0d5388d3..00000000 --- a/packages/vipeye-internal/src/tests/samples/import7.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests that wildcard imports are not allowed -# outside of the module scope. - -from .import5 import * - - -class A: - # This should generate an error. - from .import5 import * - - -def func1(): - # This should generate an error. - from .import5 import * diff --git a/packages/vipeye-internal/src/tests/samples/import8.py b/packages/vipeye-internal/src/tests/samples/import8.py deleted file mode 100644 index dc07fa89..00000000 --- a/packages/vipeye-internal/src/tests/samples/import8.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample is imported by import9.py. - -# Implement __getattr__ function as described in PEP 562. - - -def __getattr__(name: str): - return str diff --git a/packages/vipeye-internal/src/tests/samples/import9.py b/packages/vipeye-internal/src/tests/samples/import9.py deleted file mode 100644 index b9f40fbf..00000000 --- a/packages/vipeye-internal/src/tests/samples/import9.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests support for PEP 562's __getattr__ function. - -# This should not generate an error because import8 has -# a __getattr__ method. -from .import8 import foo - -foo() diff --git a/packages/vipeye-internal/src/tests/samples/inconsistentConstructor1.py b/packages/vipeye-internal/src/tests/samples/inconsistentConstructor1.py deleted file mode 100644 index ffff3485..00000000 --- a/packages/vipeye-internal/src/tests/samples/inconsistentConstructor1.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the reportInconsistentConstructor diagnostic check. - -from typing import Any, Self - - -class Parent1: - def __init__(self, a: int) -> None: ... - - -class Child1(Parent1): - # This should generate an error if reportInconsistentConstructor is enabled. - def __new__(cls, a: int | str): ... - - -class Parent2: - def __init__(self, b: int) -> None: ... - - -class Child2(Parent2): - # This should generate an error if reportInconsistentConstructor is enabled. - def __new__(cls, b: str): ... - - -class Class3: - def __new__(cls, *args: object, **kwargs: object) -> Self: ... - - # This should generate an error if reportInconsistentConstructor is enabled. - def __init__(self, a: int) -> None: ... - - -class Class4: - def __new__(cls, *args: Any, **kwargs: Any) -> Self: ... - - def __init__(self, a: int) -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab1.py b/packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab1.py deleted file mode 100644 index ceb71f11..00000000 --- a/packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab1.py +++ /dev/null @@ -1,9 +0,0 @@ -# This sample tests the tokenizer's ability to detect inconsistent -# use of tab and spaces in a way that's ambiguous. - -def main(jsonIn): - print("a") - # This should generate an error because of inconsistent use of - # tabs and spaces. - print("b") - diff --git a/packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab2.py b/packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab2.py deleted file mode 100644 index 3adc8e5c..00000000 --- a/packages/vipeye-internal/src/tests/samples/inconsistentSpaceTab2.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the reporting of inconsistent space/tab usage -# for dedent tokens. - - -if True: - if True: - print("False") - print("True") # Should generate an error here. - - diff --git a/packages/vipeye-internal/src/tests/samples/index1.py b/packages/vipeye-internal/src/tests/samples/index1.py deleted file mode 100644 index 8e79b50d..00000000 --- a/packages/vipeye-internal/src/tests/samples/index1.py +++ /dev/null @@ -1,128 +0,0 @@ -# This sample tests the handling of __index__ magic method -# when used with the __getitem__ and __setitem__ method. - - -from typing import Generic, Literal, Self, Type, TypeVar, Any - - -class MyInt: - def __init__(self, value: int) -> None: - self.value = value - - def __index__(self) -> int: - return self.value - - -l = ["foo", "bar"] -t = ("foo", "bar") - -hex(MyInt(7)) -l[MyInt(0)] -l[MyInt(0)] = "hi" -t[MyInt(1)] - - -class MyNonInt: - def __init__(self) -> None: - pass - - -# These should generate errors -hex(MyNonInt()) -l[MyNonInt()] -l[MyNonInt()] = "hi" -t[MyNonInt()] - - -T = TypeVar("T") - - -class MyMetaclass(type): - def __getitem__(cls: Type[T], item: int) -> T: - return cls() - - -class ClassA(metaclass=MyMetaclass): - pass - - -a1 = ClassA[1] -reveal_type(a1, expected_text="ClassA") - -# This should generate an error -ClassA["1"] - - -class ClassB: - def __setitem__(self, index: int, value: "ClassB"): ... - - -class ClassC: - def __setitem__(self, index: int, value: "ClassC"): ... - - -B_or_C = TypeVar("B_or_C", ClassB, ClassC) - - -def func1(container: B_or_C): - a = container - a[1] = container - - -TD = TypeVar("TD", bound="ClassD[Any]") - - -class ClassD(Generic[TD]): - def __setitem__(self, index: int, value: TD): ... - - -def func2(container: ClassD[TD], value: TD): - container[1] = value - - -class ClassE: - def __getattr__(self, s: str) -> Any: - raise NotImplementedError() - - -e = ClassE() - -# This should generate an error -v_e = e["test"] - -# This should generate an error -e["test"] = 3 - - -class ClassF(Generic[T]): - def __getitem__(self, args: int) -> Self: ... - - def get(self, index: int) -> Self: - reveal_type(self[index], expected_text="Self@ClassF[T@ClassF]") - return self[index] - - -class ClassG: - __slots__ = ["x"] - - -def func3(g: ClassG): - reveal_type(g.x, expected_text="Unbound") - reveal_type(g.x[0], expected_text="Unknown") - - -class ClassH: - def __call__(self, *args, **kwargs) -> Self: - return self - - -class ClassI: - __getitem__ = ClassH() - - -reveal_type(ClassI()[0], expected_text="ClassH") - - -def func4(l: list[Literal["a", "b"]]): - l[0] = "a" - l[0:0] = ["a", "b"] diff --git a/packages/vipeye-internal/src/tests/samples/inferredTypes1.py b/packages/vipeye-internal/src/tests/samples/inferredTypes1.py deleted file mode 100644 index 7a5193aa..00000000 --- a/packages/vipeye-internal/src/tests/samples/inferredTypes1.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the analyzer's ability to infer types -# across execution contexts. - -from typing import Callable - - -def perform_request(build_req: Callable[[], str]) -> str: - return "purr" - - -def make_api_request(auth: str) -> str: - return "meow" - - -def func1() -> None: - resp = open("test") - auth = resp.read() - - def build_req(): - # "auth" is declared in a different execution context - # and included here in the closure. Make sure its type - # is properly inferred. - return make_api_request(auth) - - resp = perform_request(build_req) diff --git a/packages/vipeye-internal/src/tests/samples/inferredTypes2.py b/packages/vipeye-internal/src/tests/samples/inferredTypes2.py deleted file mode 100644 index e988cc92..00000000 --- a/packages/vipeye-internal/src/tests/samples/inferredTypes2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the ability of the type checker to infer -# the types of instance variables based on their assigned values. - - -class ClassA: - def __init__(self): - self.value = None - - def func(self, param: int): - reveal_type(self.value, expected_text="int | None") - - if self.value is not None: - reveal_type(self.value, expected_text="int") - self.value.bit_length() - - self.value = param diff --git a/packages/vipeye-internal/src/tests/samples/inferredTypes3.py b/packages/vipeye-internal/src/tests/samples/inferredTypes3.py deleted file mode 100644 index 23ed555d..00000000 --- a/packages/vipeye-internal/src/tests/samples/inferredTypes3.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests return type annotations for functions that -# do not return. - -from abc import ABC, abstractmethod - - -class OtherError(NotImplementedError): ... - - -class A(ABC): - def func1(self): - raise Exception("test") - - def func2(self): - raise NotImplementedError() - - def func3(self): - raise OtherError - - @abstractmethod - def func4(self): - raise Exception() - - -def func1(a: A): - reveal_type(a.func1(), expected_text="NoReturn") - - reveal_type(a.func2(), expected_text="Unknown") - - reveal_type(a.func3(), expected_text="Unknown") - - reveal_type(a.func4(), expected_text="Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/initVar1.py b/packages/vipeye-internal/src/tests/samples/initVar1.py deleted file mode 100644 index fc72ae99..00000000 --- a/packages/vipeye-internal/src/tests/samples/initVar1.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the use of the InitVar annotation. - -from dataclasses import InitVar as InitVarAlias - -from dataclasses import * - - -@dataclass -class Container: - init_var1: InitVarAlias[int] - init_var2: InitVar[int] - - not_init_var1: int - - -c = Container(1, 2, 3) -reveal_type(c.not_init_var1, expected_text="int") - -# This should generate an error -c.init_var1 - -# This should generate an error -c.init_var2 diff --git a/packages/vipeye-internal/src/tests/samples/initsubclass1.py b/packages/vipeye-internal/src/tests/samples/initsubclass1.py deleted file mode 100644 index f39eb94c..00000000 --- a/packages/vipeye-internal/src/tests/samples/initsubclass1.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests the type checker's validation -# of the __init_subclass__ method described in -# PEP 487. - -from datetime import datetime -from typing import Any, Optional, Type, TypedDict - - -class ClassA: - def __init_subclass__( - cls, *, param1: str, param2: float, param3: Optional[Any] = None - ) -> None: - super().__init_subclass__() - - -# This should generate two errors because param1 is -# the wrong type. -class ClassB(ClassA, param1=0, param2=4): - pass - - -# This should generate two errors because param2 is missing. -class ClassC(ClassA, param1="0", param3=datetime.now()): - pass - - -class ClassD(ClassA, param1="0", param2=5.0): - pass - - -class ClassE: - def __init_subclass__(cls, *, arg: int) -> None: - func1(cls, arg) - - def __new__(cls) -> "ClassE": - func1(cls, 9) - return super().__new__(cls) - - -def func1(klass: Type[ClassE], arg: int): - pass - - -class ClassF(ClassA, param1="hi", param2=3.4): - def __init_subclass__(cls, param_alt1: int): - super().__init_subclass__(param1="yo", param2=param_alt1) - - -def func2(cls): - pass - - -class ClassG: - __init_subclass__ = func2 - - -class ClassH(ClassG): - pass - - -# This should generate two errors because "a" is not present -# in the object.__init_subclass__ method. -class ClassI(a=3): - a: int - - -class ClassJ: - def __init_subclass__(cls, **kwargs: Any) -> None: - super().__init_subclass__(**kwargs) - cls.custom_attribute = 9 - - -class ClassJChild(ClassJ): - def __init__(self): - reveal_type(self.custom_attribute, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/initsubclass2.py b/packages/vipeye-internal/src/tests/samples/initsubclass2.py deleted file mode 100644 index 74837ab1..00000000 --- a/packages/vipeye-internal/src/tests/samples/initsubclass2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample verifies that a subclass of a class that supports -# __init_subclass__ provides the required initialization parameters. - - -class A: - def __init_subclass__(cls, param_a: int): - super().__init_subclass__() - - -class B(A, param_a=123): - pass - - -# This should generate two errors because param_a is missing. -class C(B): - pass diff --git a/packages/vipeye-internal/src/tests/samples/initsubclass3.py b/packages/vipeye-internal/src/tests/samples/initsubclass3.py deleted file mode 100644 index b6a1ad2d..00000000 --- a/packages/vipeye-internal/src/tests/samples/initsubclass3.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where an __init_subclass__ is overloaded. - - -from typing import overload - - -class BaseClass1: - @overload - def __init_subclass__(cls, x: str, y: str) -> None: ... - - @overload - def __init_subclass__(cls, x: int, y: int) -> None: ... - - def __init_subclass__(cls, x: int | str, y: int | str) -> None: ... - - -class Subclass1A(BaseClass1, x=3, y=3): ... - - -class Subclass1B(BaseClass1, x="", y=""): ... - - -# This should generate three errors. -class Subclass1C(BaseClass1, x=1, y=""): ... diff --git a/packages/vipeye-internal/src/tests/samples/isinstance1.py b/packages/vipeye-internal/src/tests/samples/isinstance1.py deleted file mode 100644 index cf1d7beb..00000000 --- a/packages/vipeye-internal/src/tests/samples/isinstance1.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests the use of "self.__class__" and "__class__" -# in an isinstance call. - - -class Foo: - def bar(self): - a = isinstance(object(), self.__class__) - b = isinstance(object(), __class__) diff --git a/packages/vipeye-internal/src/tests/samples/isinstance2.py b/packages/vipeye-internal/src/tests/samples/isinstance2.py deleted file mode 100644 index 14930d75..00000000 --- a/packages/vipeye-internal/src/tests/samples/isinstance2.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the case where a base class has -# an unknown type and the type is used in an -# isinstance check. - -# viper: reportUnnecessaryIsInstance=true - -from typing import TypeVar, Union - -# This should generate an error because "dummy" can't be resolved. -# The symbol Document should have an unknown type. -from dummy import Document - - -class DbModel(Document): - pass - - -def func1() -> Union[int, DbModel]: - return DbModel() - - -# This should not generate an error even though DbModel is -# derived from an unknown base class. -isinstance(func1(), int) - - -def func2(obj: object, typ: type): - return isinstance(obj, typ) - - -def func3(obj: float): - if isinstance(obj, float): - reveal_type(obj, expected_text="float") - else: - reveal_type(obj, expected_text="int") - - -T = TypeVar("T", bound=float) - - -def func4(t: type[T]): - if issubclass(t, float): - reveal_type(t, expected_text="type[float]*") - else: - reveal_type(t, expected_text="type[int]*") diff --git a/packages/vipeye-internal/src/tests/samples/isinstance3.py b/packages/vipeye-internal/src/tests/samples/isinstance3.py deleted file mode 100644 index 20f8d327..00000000 --- a/packages/vipeye-internal/src/tests/samples/isinstance3.py +++ /dev/null @@ -1,119 +0,0 @@ -# This sample tests the logic that validates the second parameter to -# an isinstance or issubclass call and ensures that it's a class or -# tuple of classes. - - -import sys -from abc import abstractmethod -from typing import ( - Annotated, - Any, - Callable, - Generic, - Sequence, - Tuple, - Type, - TypeVar, - TypedDict, - Union, -) - -if sys.version_info >= (3, 10): - from types import NoneType -else: - NoneType = type(None) - -_T = TypeVar("_T", int, str) - - -class A(Generic[_T]): - pass - - -a = A() - -if isinstance(a, A): - pass - -# This should generate an error because generic types with -# subscripts are not allowed. -if isinstance(a, A[str]): - pass - -# This should generate an error in Python 3.9 and older because -# unions are not allowed, but this error isn't currently caught. -if issubclass(A, Union[A, int]): - pass - -if issubclass(A, type(None)): - pass - -if issubclass(A, NoneType): - pass - - -class ClassA(Generic[_T]): - v1: _T - v2: Type[_T] - - @property - @abstractmethod - def _elem_type_(self) -> Union[Type[_T], Tuple[Type[_T], ...]]: - raise NotImplementedError - - def check_type(self, var: Any) -> bool: - return isinstance(var, self._elem_type_) - - def execute(self, var: Union[_T, Tuple[_T]]) -> None: - if isinstance(var, self._elem_type_): - pass - - if isinstance(var, type(self.v1)): - pass - - if isinstance(var, self.v2): - pass - - -def func1(exceptions: Sequence[type[BaseException]], exception: Exception): - return isinstance(exception, tuple(exceptions)) - - -if isinstance(a, Callable): - ... - -# This should generate an error because a subscripted Callable -# will result in a runtime exception. -if isinstance(a, Callable[[], Any]): - ... - -if isinstance(a, type(len)): - ... - - -class TD1(TypedDict): - a: int - - -# This should generate an error because TypedDict classes can't -# be used in an isinstance call. -if isinstance(a, TD1): - pass - - -TA1 = Annotated[int, ""] - -# This should generate two errors because Annotated can't be used -# in an isinstance call. -if isinstance(1, TA1): - pass - -# This should generate an error because Any can't be used -# in an isinstance call. -if isinstance(1, Any): - pass - -# This should generate an error because Literal can't be used -# in an isinstance call. -if isinstance(1, Literal[1, 2]): - pass diff --git a/packages/vipeye-internal/src/tests/samples/isinstance4.py b/packages/vipeye-internal/src/tests/samples/isinstance4.py deleted file mode 100644 index 16439148..00000000 --- a/packages/vipeye-internal/src/tests/samples/isinstance4.py +++ /dev/null @@ -1,70 +0,0 @@ -# This sample checks that isinstance and issubclass don't -# allow the second argument to be a Protocol class. - -from inspect import isfunction -from typing import Any, Callable, Protocol, Type, TypeVar, Union, runtime_checkable -from types import FunctionType, LambdaType - - -class MyProtocol1(Protocol): - pass - - -# This should generate an error because Sized is a Protocol that -# is not runtime checkable. -isinstance(4, MyProtocol1) - - -# This should generate an error because Iterable is a Protocol. -issubclass(str, (str, MyProtocol1)) - - -def func1(t: type[MyProtocol1]): - isinstance(1, t) - - -@runtime_checkable -class MyProtocol2(Protocol): - pass - - -isinstance(4, MyProtocol2) -issubclass(str, (str, MyProtocol2)) - - -class CustomClass: - def __call__(self, *args: Any): - pass - - -def get_type_of_object(object: Union[Callable[..., Any], CustomClass]): - # This would normally generate an error, but FunctionType is special. - if isinstance(object, FunctionType): - return "is function" - - if isinstance(object, LambdaType): - return "is lambda" - - if isinstance(object, Callable): - return "is callable" - - return "nothing" - - -_T1 = TypeVar("_T1", bound=CustomClass) - - -def func2(cls: Type[_T1], val: _T1): - if issubclass(cls, CustomClass): - reveal_type(cls, expected_text="type[CustomClass]*") - else: - reveal_type(cls, expected_text="Never") - - -_T2 = TypeVar("_T2") - - -def func3(x: _T2) -> Union[_T2, int]: - if callable(x) and isfunction(x): - return 1 - return x diff --git a/packages/vipeye-internal/src/tests/samples/isinstance5.py b/packages/vipeye-internal/src/tests/samples/isinstance5.py deleted file mode 100644 index c8b9bfc4..00000000 --- a/packages/vipeye-internal/src/tests/samples/isinstance5.py +++ /dev/null @@ -1,45 +0,0 @@ -# This tests error reporting for the use of data protocols in an -# issubclass call. - -from typing import Any, Protocol, runtime_checkable - -# > isinstance() can be used with both data and non-data protocols, while -# > issubclass() can be used only with non-data protocols. - - -@runtime_checkable -class DataProtocol(Protocol): - name: str - - def method1(self) -> int: ... - - -@runtime_checkable -class DataProtocol2(DataProtocol, Protocol): - def method2(self) -> int: ... - - -@runtime_checkable -class NonDataProtocol(Protocol): - def method1(self) -> int: ... - - -def func2(a: Any): - if isinstance(a, DataProtocol): - return - - if isinstance(a, NonDataProtocol): - return - - # This should generate an error because data protocols - # are not allowed with issubclass checks. - if issubclass(a, (DataProtocol, NonDataProtocol)): - return - - # This should generate an error because data protocols - # are not allowed with issubclass checks. - if issubclass(a, (DataProtocol2, NonDataProtocol)): - return - - if issubclass(a, NonDataProtocol): - return diff --git a/packages/vipeye-internal/src/tests/samples/isinstance6.py b/packages/vipeye-internal/src/tests/samples/isinstance6.py deleted file mode 100644 index e0d27fc9..00000000 --- a/packages/vipeye-internal/src/tests/samples/isinstance6.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests the detection of a runtime checkable protocol -# that unsafely overlaps a class within an isinstance or issubclass -# call. - -# > Type checkers should reject an isinstance() or issubclass() call if there -# > is an unsafe overlap between the type of the first argument and the protocol. - - -from typing import Protocol, runtime_checkable - - -@runtime_checkable -class Proto3(Protocol): - def method1(self, a: int) -> int: ... - - -class Concrete3A: - def method1(self, a: str) -> None: - pass - - -@runtime_checkable -class Proto2(Protocol): - def other(self) -> None: ... - - -class Concrete3B: - method1: int = 1 - - -def func3(): - if isinstance(Concrete3A(), Proto3): # Type error: unsafe overlap - pass - - if isinstance(Concrete3B(), (Proto3, Proto2)): # Type error: unsafe overlap - pass - - if issubclass(Concrete3A, (Proto3, Proto2)): # Type error: unsafe overlap - pass diff --git a/packages/vipeye-internal/src/tests/samples/kwargsUnpack1.py b/packages/vipeye-internal/src/tests/samples/kwargsUnpack1.py deleted file mode 100644 index e80a81c5..00000000 --- a/packages/vipeye-internal/src/tests/samples/kwargsUnpack1.py +++ /dev/null @@ -1,142 +0,0 @@ -# This sample tests the handling of Unpack[TypedDict] when used with -# a **kwargs parameter in a function signature. - -from typing import Protocol, TypedDict -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - NotRequired, - Required, - Unpack, -) - - -class TD1(TypedDict): - v1: Required[int] - v2: NotRequired[str] - - -class TD2(TD1): - v3: Required[str] - - -def func1(**kwargs: Unpack[TD2]) -> None: - v1 = kwargs["v1"] - reveal_type(v1, expected_text="int") - - # This should generate an error because v2 might not be present. - kwargs["v2"] - - if "v2" in kwargs: - v2 = kwargs["v2"] - reveal_type(v2, expected_text="str") - - v3 = kwargs["v3"] - reveal_type(v3, expected_text="str") - - -reveal_type(func1, expected_text="(**kwargs: **TD2) -> None") - - -def func2(v3: str, **kwargs: Unpack[TD1]) -> None: - pass - - -def func3(): - # This should generate an error because it is - # missing required keyword arguments. - func1() - - func1(v1=1, v2="", v3="5") - - td2 = TD2(v1=2, v3="4") - func1(**td2) - - # This should generate an error because v4 is not in TD2. - func1(v1=1, v2="", v3="5", v4=5) - - # This should generate an error because args are passed by position. - func1(1, "", "5") - - my_dict: dict[str, str] = {} - # This should generate an error because it's an untyped dict. - func1(**my_dict) - - d1 = {"v1": 2, "v3": "4", "v4": 4} - func1(**d1) - - func2(**td2) - - # This should generate an error because v1 is already specified. - func1(v1=2, **td2) - - # This should generate an error because v1 is already specified. - func2(1, **td2) - - # This should generate an error because v1 is matched to a - # named parameter and is not available for kwargs. - func2(v1=1, **td2) - - -class TDProtocol1(Protocol): - def __call__(self, *, v1: int, v3: str) -> None: ... - - -class TDProtocol2(Protocol): - def __call__(self, *, v1: int, v3: str, v2: str = "") -> None: ... - - -class TDProtocol3(Protocol): - def __call__(self, *, v1: int, v2: int, v3: str) -> None: ... - - -class TDProtocol4(Protocol): - def __call__(self, *, v1: int) -> None: ... - - -class TDProtocol5(Protocol): - def __call__(self, v1: int, v3: str) -> None: ... - - -class TDProtocol6(Protocol): - def __call__(self, **kwargs: Unpack[TD2]) -> None: ... - - -v1: TDProtocol1 = func1 -v2: TDProtocol2 = func1 - -# This should generate an error because v2 is the wrong type. -v3: TDProtocol3 = func1 - -# This should generate an error because v3 is missing. -v4: TDProtocol4 = func1 - -# This should generate an error because parameters are positional. -v5: TDProtocol5 = func1 - -v6: TDProtocol6 = func1 - - -def func4(v1: int, /, **kwargs: Unpack[TD2]) -> None: ... - - -# This should generate an error because parameter v1 overlaps -# with the TypedDict. -def func5(v1: int, **kwargs: Unpack[TD2]) -> None: ... - - -class TD3(TypedDict): - a: int - - -def func6(a: int, /, **kwargs: Unpack[TD3]): - pass - - -func6(1, a=2) - - -def func7(*, v1: int, v3: str, v2: str = "") -> None: ... - - -# This should generate an error because func7 doesn't -# accept additional keyword arguments. -v7: TDProtocol6 = func7 diff --git a/packages/vipeye-internal/src/tests/samples/kwargsUnpack2.py b/packages/vipeye-internal/src/tests/samples/kwargsUnpack2.py deleted file mode 100644 index a11f3435..00000000 --- a/packages/vipeye-internal/src/tests/samples/kwargsUnpack2.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the handling of Unpack[TypedDict] with a **kwargs -# parameter when the TypedDict is generic and specialized at the parameter -# declaration. The type argument must be substituted into the expanded -# keyword parameters (both for display and for call argument checking). - -from typing import Generic, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypedDict, - Unpack, -) - -T = TypeVar("T") - - -class TD(TypedDict, Generic[T]): - t: T - - -def func(**kwargs: Unpack[TD[int]]) -> None: - v = kwargs["t"] - reveal_type(v, expected_text="int") - - -reveal_type(func, expected_text="(**kwargs: **TD[int]) -> None") - - -def caller() -> None: - func(t=1) - - # This should generate an error because t must be an int. - func(t="bad") - - # This should generate an error because t is required. - func() diff --git a/packages/vipeye-internal/src/tests/samples/lambda1.py b/packages/vipeye-internal/src/tests/samples/lambda1.py deleted file mode 100644 index 2468a431..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda1.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests type checking for lambdas and their parameters. -from typing import Any, Callable, Iterable, TypeVar - -#------------------------------------------------------ -# Test basic lambda matching - -def needs_function(callback: Callable[[str, int], str]): - pass - -needs_function(lambda x, y:x) - -# This should generate an error because the lambda doesn't -# accept two parameters. -needs_function(lambda x:x) - - -#------------------------------------------------------ -# Test lambda matching when dest includes default parameter values - -def needs_function2(callback: Callable[[str, int], str]): - pass - -needs_function(lambda x, y:x) - - -#------------------------------------------------------ -# Test parameter rules for lambdas - -# This should generate an error because a parameter with -# no default follows a parameter with a default. -lambda2 = lambda x=1, y:y - -lambda3 = lambda x, y=5:y -lambda3(1) -lambda3(1, 2) - -lambda4 = lambda x, *y, z:y - - -#------------------------------------------------------ -# Test calling of lambdas - -lambda1 = lambda x, y:x -lambda1(1, 2) - -# This should generate an error because the lambda doesn't -# accept three parameters. -lambda1(1, 2, 3) - -lambda4(1, z=3) -lambda4(1, 3, 4, 5, 6, z=3) - -# This should generate an error because the arguments -# don't match the parameter list. -lambda4(1, 3) - -# This should generate an error because the arguments -# don't match the parameter list (no named value for z). -lambda4(1, 3, 4) - - -#------------------------------------------------------ -# Test generic parameter matching in lambdas - -_T1 = TypeVar('_T1') - -def may_need_function_generic(callback: Callable[[_T1], _T1] | None): - pass - -may_need_function_generic(lambda x: x) - - -def reduce(function: Callable[[_T1, _T1], _T1], sequence: Iterable[_T1]) -> _T1: - ... - - -a: object = reduce((lambda x, y: x * y), [1, 2, 3, 4]) - - -#------------------------------------------------------ -# Test lambdas with *args - -b1: Callable[[int, int, str], Any] = lambda _, *b: reveal_type( - b, expected_text="tuple[Unknown, ...]" -) - -b2: Callable[[str, str], Any] = lambda *b: reveal_type( - b, expected_text="tuple[Unknown, ...]" -) - -b3: Callable[[int], Any] = lambda _, *b: reveal_type( - b, expected_text="tuple[Unknown, ...]" -) diff --git a/packages/vipeye-internal/src/tests/samples/lambda10.py b/packages/vipeye-internal/src/tests/samples/lambda10.py deleted file mode 100644 index 50818c90..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda10.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the handling of immediately-called lambdas. - -# viper: strict - -from typing import Callable - -func1: Callable[[int, int], int] = lambda x, y, /: ( - lambda x, y: max( - reveal_type(x, expected_text="int"), reveal_type(y, expected_text="int") - ) - // min(x, y) -)(abs(reveal_type(x, expected_text="int")), abs(reveal_type(y, expected_text="int"))) - -v1 = func1(-2, 4) -reveal_type(v1, expected_text="int") - - -v2 = (lambda a, b: a + b)(3, 4) -reveal_type(v2, expected_text="int") - - -v3 = (lambda a, b: a + b)("foo", "bar") -reveal_type(v3, expected_text="LiteralString") - -v4 = (lambda a, b: a + b)("foo", (lambda c, d: c + d)("b", "ar")) -reveal_type(v4, expected_text="LiteralString") diff --git a/packages/vipeye-internal/src/tests/samples/lambda11.py b/packages/vipeye-internal/src/tests/samples/lambda11.py deleted file mode 100644 index 8f30ca92..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda11.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where a lambda's expected type includes -# a ParamSpec. - -from typing import Callable, Generic, TypeVar, Concatenate, ParamSpec - -T = TypeVar("T") -P = ParamSpec("P") - - -class Callback(Generic[T]): - def __init__( - self, - func: Callable[Concatenate[T, P], object], - *args: P.args, - **kwargs: P.kwargs, - ) -> None: ... - - -v1: Callback[tuple[int, int]] = Callback(lambda p: (p[1], p[0])) - - -def func1( - func: Callable[Concatenate[int, P], T], *args: P.args, **kwargs: P.kwargs -) -> T: ... - - -v2 = func1(lambda p: p) -reveal_type(v2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/lambda12.py b/packages/vipeye-internal/src/tests/samples/lambda12.py deleted file mode 100644 index e81cebee..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda12.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the case where a lambda includes one or more parameters -# that accept a default value and the the expected type does not include -# these parameters. In this case, the types of the extra parameters should -# be inferred based on the default value type. - -# viper: strict - -from typing import Callable - - -def func1() -> list[Callable[[int], int]]: - return [lambda x, i=i: i * x for i in range(5)] diff --git a/packages/vipeye-internal/src/tests/samples/lambda13.py b/packages/vipeye-internal/src/tests/samples/lambda13.py deleted file mode 100644 index 3b4086c5..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda13.py +++ /dev/null @@ -1,43 +0,0 @@ -# This sample tests the case where a lambda's expected type is a callable -# that accepts another generic callable as a parameter. - -from typing import Callable, Generic, TypeVar - -T = TypeVar("T") - - -def func1(callable: Callable[[Callable[[T], T]], T]) -> T: - return callable(lambda x: x) - - -v1 = func1(lambda a: a(0)) -reveal_type(v1, expected_text="int") - -v2 = func1(lambda a: a("")) -reveal_type(v2, expected_text="str") - - -def test1(untyped): - v1 = func1(lambda a: a(untyped)) - reveal_type(v1, expected_text="Unknown") - - -class A(Generic[T]): - def __init__(self, value: T) -> None: - self.value = value - - -def func2(callable: Callable[[type[A[T]]], A[T]]) -> T: - return callable(A).value - - -v3 = func2(lambda A: A(0)) -reveal_type(v3, expected_text="int") - -v4 = func2(lambda A: A("")) -reveal_type(v4, expected_text="str") - - -def test2(untyped): - v1 = func2(lambda A: A(untyped)) - reveal_type(v1, expected_text="Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/lambda14.py b/packages/vipeye-internal/src/tests/samples/lambda14.py deleted file mode 100644 index c238d5ae..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda14.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests type inference for a lambda that has no inference -# context but has a default argument value. - -lambda1 = lambda x="": x -reveal_type(lambda1, expected_text='(x: str = "") -> str') - -lambda2 = lambda x=None: x -reveal_type(lambda2, expected_text="(x: Unknown | None = None) -> (Unknown | None)") diff --git a/packages/vipeye-internal/src/tests/samples/lambda15.py b/packages/vipeye-internal/src/tests/samples/lambda15.py deleted file mode 100644 index 75fdc1bb..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda15.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a lambda is passed to a constructor -# where both __new__ and __init__ methods are present and have different -# types. - -# viper: strict - -from typing import Any, TypeVar, Callable - -T = TypeVar("T") - - -def identity(val: T) -> T: - return val - - -class ClassA: - def __new__(cls, *args: Any, **kwargs: Any) -> "ClassA": - return super().__new__(*args, **kwargs) - - def __init__(self, x: Callable[[float], float]) -> None: - self.x = x - - -ClassA(lambda r: identity(r) + 1) diff --git a/packages/vipeye-internal/src/tests/samples/lambda2.py b/packages/vipeye-internal/src/tests/samples/lambda2.py deleted file mode 100644 index cf9bc0c9..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda2.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample verifies that the type checker properly handles -# lambdas with position-only and keyword-only markers. - -from typing import Callable - -foo1: Callable[[int], int] = lambda x, /: x + 1 - -# This should generate an error because there are too few -# parameters provided by the lambda. -foo2: Callable[[int, int], int] = lambda x, /: x + 1 - -# This should generate an error because there are too many -# parameters provided by the lambda. -foo3: Callable[[int, int], int] = lambda x, /, y, z: x + 1 - -# This should generate an error because there is no named -# parameter y. -foo4: Callable[[int, int], int] = lambda x, *, y: x + y + 1 - -# This should generate an error because there are too few -# parameters provided by the lambda. -foo5: Callable[[int, int, int], int] = lambda x, *, y: x + y + 1 - -# This should generate an error because there are too many -# parameters provided by the lambda. -foo6: Callable[[int], int] = lambda x, *, y: x + y + 1 - -foo7: Callable[[int, str], int] = lambda *args: 1 - -# This should generate an error because there are too many -# parameters provided by the lambda. -foo8: Callable[[int, str], int] = lambda a, b, c, *args: 1 diff --git a/packages/vipeye-internal/src/tests/samples/lambda3.py b/packages/vipeye-internal/src/tests/samples/lambda3.py deleted file mode 100644 index 4765f733..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda3.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the handling of default parameter value -# expressions in a lambda. - - -from typing import Callable, Protocol - - -def test1(): - var = 1 - - lambda _=var: ... - - -def test2(): - # This should generate an error because var2 isn't defined. - lambda _=var2: ... - - -def test3(): - var = 0 - lambda var=var: ... - - -class MyCallback(Protocol): - def __call__(self, y: int, a: int = 0) -> bool: ... - - -lambda1: Callable[[int, int], bool] = lambda y, a=0: a == y -lambda2: MyCallback = lambda y, a=0: a == y - -lambda1(20) -lambda2(20) -lambda2(20, 30) diff --git a/packages/vipeye-internal/src/tests/samples/lambda4.py b/packages/vipeye-internal/src/tests/samples/lambda4.py deleted file mode 100644 index 95269e67..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda4.py +++ /dev/null @@ -1,78 +0,0 @@ -# This sample tests the case where a lambda is assigned to -# a union type that contains multiple callables. - -from typing import Callable, Protocol, TypeVar - - -U1 = Callable[[int, str], bool] | Callable[[str], bool] - - -def accepts_u1(cb: U1) -> U1: - return cb - - -def callback_1(p0: int, p1: str): - return True - - -def callback_2(p0: str): - return True - - -def callback_3(*p0: str): - return True - - -accepts_u1(lambda s: s.startswith("hello")) -accepts_u1(lambda i, s: i > 0 and s.startswith("hello")) -accepts_u1(lambda *i: True) -accepts_u1(callback_1) -accepts_u1(callback_2) -accepts_u1(callback_3) - -# This should generate an error -accepts_u1(lambda a, b, c: True) - - -class Callable1(Protocol): - def __call__(self, p0: int, p1: str) -> bool: ... - - -class Callable2(Protocol): - def __call__(self, p0: str) -> bool: ... - - -class Callable3(Protocol): - def __call__(self, *p0: str) -> bool: ... - - -class Callable4(Protocol): - def __call__(self, p0: int, p1: str, *p2: str) -> bool: ... - - -U2 = Callable1 | Callable2 | Callable3 | Callable4 - - -def accepts_u2(cb: U2) -> U2: - return cb - - -accepts_u2(lambda p0: p0.startswith("hello")) -accepts_u2(lambda p0, p1: p0 > 0 and p1.startswith("hello")) -accepts_u2(lambda *i: True) -accepts_u2(lambda p0, p1, *p2: True) -accepts_u2(callback_1) -accepts_u2(callback_2) -accepts_u2(callback_3) - - -T = TypeVar("T") - -Takes = Callable[[T], object] - -U3 = Takes[Takes[int]] | Takes[Takes[str]] - - -def accepts_u3(u: U3): - # This should generate an error. - u(lambda v: v.lower()) diff --git a/packages/vipeye-internal/src/tests/samples/lambda5.py b/packages/vipeye-internal/src/tests/samples/lambda5.py deleted file mode 100644 index e750073d..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda5.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a lambda's type is determined using -# bidirectional type inference and one or more of the parameters -# corresponds to a generic type. - -from typing import Callable, TypeVar, Generic, Any - -T = TypeVar("T") -MsgT = TypeVar("MsgT", bound="Msg[Any]") - - -class Msg(Generic[T]): - body: T - - -class Request: ... - - -def check(func: "Callable[[MsgT, int], object]") -> MsgT: ... - - -notification: Msg[Request] = check(lambda msg, foo: (msg.body, foo)) diff --git a/packages/vipeye-internal/src/tests/samples/lambda6.py b/packages/vipeye-internal/src/tests/samples/lambda6.py deleted file mode 100644 index a7d85696..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda6.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample validates that lambdas declared within a class -# body do not reference class-scoped variables within the -# lambda return expression. - - -var1 = [1, 2] - - -class A: - x1 = lambda: var1 - - var2 = [1, 2] - - # This should generate an error. - x2 = lambda: var2 diff --git a/packages/vipeye-internal/src/tests/samples/lambda7.py b/packages/vipeye-internal/src/tests/samples/lambda7.py deleted file mode 100644 index e9287e2c..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda7.py +++ /dev/null @@ -1,9 +0,0 @@ -# This sample tests the case where a lambda's expression must be -# evaluated multiple times as more type information is gathered -# in the presence of an overloaded method. - -# viper: strict - - -def func1(keys: list[str]): - filter(lambda s: s.startswith(""), keys) diff --git a/packages/vipeye-internal/src/tests/samples/lambda8.py b/packages/vipeye-internal/src/tests/samples/lambda8.py deleted file mode 100644 index ff511767..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda8.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where a lambda is passed to a generic -# Callable with two different type variables. - -from typing import Callable, Generic, TypeVar - -T = TypeVar("T") -R = TypeVar("R") - - -class A(Generic[T, R]): - def __init__(self, x: Callable[[T], R], y: T): ... - - -class B(Generic[R]): - def __init__(self, x: Callable[[T], R], y: T): ... - - -reveal_type(A(lambda x: x, 123), expected_text="A[int, int]") -reveal_type(B(lambda x: x, 123), expected_text="B[int]") diff --git a/packages/vipeye-internal/src/tests/samples/lambda9.py b/packages/vipeye-internal/src/tests/samples/lambda9.py deleted file mode 100644 index f3ab2971..00000000 --- a/packages/vipeye-internal/src/tests/samples/lambda9.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the case where a lambda's expected type is incomplete -# the first time it is evaluated. - -from typing import Callable, Generic, TypeVar, cast, overload - - -_OutT = TypeVar("_OutT") -_Out2T = TypeVar("_Out2T", bound=str) - - -class Flow(Generic[_OutT]): - @overload - def map(self, func: Callable[[_OutT], Exception], /) -> "Flow[None]": ... - - @overload - def map(self, func: Callable[[_OutT], _Out2T], /) -> "Flow[_Out2T]": ... - - def map(self, obj, /): - return cast("Flow", self) - - -class Data: ... - - -x1 = Flow[Data]().map(lambda aa: _get_date(reveal_type(aa, expected_text="Data"))) -reveal_type(x1, expected_text="Flow[str]") - -x2 = x1.map(lambda bb: reveal_type(bb, expected_text="str")) -reveal_type(x2, expected_text="Flow[str]") - -x3 = x2.map(lambda cc: "any value") -reveal_type(x3, expected_text="Flow[str]") - - -def _get_date(d: Data) -> str: ... diff --git a/packages/vipeye-internal/src/tests/samples/lazyImport1.py b/packages/vipeye-internal/src/tests/samples/lazyImport1.py deleted file mode 100644 index a936a51a..00000000 --- a/packages/vipeye-internal/src/tests/samples/lazyImport1.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the parsing of lazy import statements (PEP 810). - -# This should parse cleanly at Python 3.15. -lazy import json - -# This should parse cleanly at Python 3.15. -lazy from json import loads - -# "lazy" used as an identifier should always work. -lazy = 1 - -# "lazy" used as a parameter name should always work. -def f(lazy: int) -> int: - return lazy - -# "lazy" used as an attribute should always work. -class C: - lazy = True diff --git a/packages/vipeye-internal/src/tests/samples/list1.py b/packages/vipeye-internal/src/tests/samples/list1.py deleted file mode 100644 index 08260244..00000000 --- a/packages/vipeye-internal/src/tests/samples/list1.py +++ /dev/null @@ -1,104 +0,0 @@ -# This sample tests type inference for list expressions. - -# viper: strict, reportUnknownVariableType=false - -from typing import Any, Collection, Generic, Literal, MutableSequence, Sequence, TypeVar - - -v1 = [1, 2, 3] -reveal_type(v1, expected_text="list[int]") - -v2 = [1, 3.4, "hi"] -reveal_type(v2, expected_text="list[int | float | str]") - -v3 = [] -reveal_type(v3, expected_text="list[Unknown]") - -v4: list[object] = [] - -v5: object = [] - -v6: Sequence[float] = [3, 4, 5] - -v7: Collection[object] = [[]] - - -_T = TypeVar("_T") - - -class Baz(Generic[_T]): - def __get__(self, instance: Any, owner: Any) -> _T: ... - - def __set__(self, instance: Any, value: _T) -> None: ... - - -class Foo: ... - - -class Bar: - baz: Baz[list[Foo]] - - -v10 = Bar() -reveal_type(v10.baz, expected_text="list[Foo]") -v10.baz = [Foo()] -reveal_type(v10.baz, expected_text="list[Foo]") - -v11: list[Any] = [["hi", ["hi"], [[{}]]]] -reveal_type(v11, expected_text="list[Any]") - -v12: list[int | None] = [None] * 3 -reveal_type(v12, expected_text="list[int | None]") - -v13: list[str | None] = ["3", None] * 2 -reveal_type(v13, expected_text="list[str | None]") - -x1 = 3 -v14: list[str | None] = [None] * x1 - -x2 = [1, 2, 3] -v15: list[str | None] = [None] * sum(x2) - -v16: dict[str, list[str | None]] = {n: [None] * len(n) for n in ["a", "aa", "aaa"]} - - -ScalarKeysT = TypeVar("ScalarKeysT", bound=Literal["name", "country"]) - - -def func1(by: list[ScalarKeysT]) -> ScalarKeysT: ... - - -reveal_type(func1(["country"]), expected_type="Literal['country']") -reveal_type(func1(["name"]), expected_type="Literal['name']") -reveal_type(func1(["name", "country"]), expected_type="Literal['name', 'country']") - -# This should generate an error. -func1(["id"]) - - -def func2(thing: str | list[str | int] | list[list[str | int]]): ... - - -func2("") -func2(["", 0]) -func2([["", 0], ["", 0]]) -func2([[""]]) - - -def func3(value: _T) -> list[_T]: - to_add = [value, str(value)] - # This should generate an error. - return to_add - - -def func4(value: _T) -> list[_T]: - # This should generate an error. - return [value, str(value)] - - -def func5(): - v1: Sequence[int | str] = [1] - reveal_type(v1, expected_text="list[int]") - - v2: MutableSequence[int | str] = [1] - reveal_type(v2, expected_text="list[int | str]") diff --git a/packages/vipeye-internal/src/tests/samples/list2.py b/packages/vipeye-internal/src/tests/samples/list2.py deleted file mode 100644 index 971c03ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/list2.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that list and list comprehension type errors are -# reported up for correct overload selection. - -import random -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - LiteralString, -) - - -# The join method is overloaded with both LiteralString and str variants. -# We need to use the str overload here. -def func(x: LiteralString): - "".join([random.choice(x) for _ in range(8)]) diff --git a/packages/vipeye-internal/src/tests/samples/list3.py b/packages/vipeye-internal/src/tests/samples/list3.py deleted file mode 100644 index f179a353..00000000 --- a/packages/vipeye-internal/src/tests/samples/list3.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests list inference in a loop where the type of -# the inferred list changes each time through the loop. - - -def func1(k: str): - keys = ["a", "b", "c"] - value = [] - - while keys: - if not k: - continue - - if not k: - value = {k: value} - else: - value = [None] * int(k) + [value] - - return value diff --git a/packages/vipeye-internal/src/tests/samples/literalForLoop1.py b/packages/vipeye-internal/src/tests/samples/literalForLoop1.py deleted file mode 100644 index dc8f9493..00000000 --- a/packages/vipeye-internal/src/tests/samples/literalForLoop1.py +++ /dev/null @@ -1,167 +0,0 @@ -# This sample tests that for loops over non-empty literal list or tuple -# expressions are treated as executing at least once for definite assignment -# analysis. - -# viper: reportPossiblyUnboundVariable=true - - -def test_non_empty_list_literal(): - """Variable assigned in for loop over non-empty list literal should not be reported as possibly unbound.""" - for x in [1]: - y = 123 - # This should not generate an error because the loop executes at least once - del y - - -def test_non_empty_tuple_literal(): - """Variable assigned in for loop over non-empty tuple literal should not be reported as possibly unbound.""" - for x in (1,): - z = 456 - # This should not generate an error because the loop executes at least once - del z - - -def test_non_empty_list_multiple_elements(): - """Variable assigned in for loop over non-empty list with multiple elements.""" - for x in [1, 2, 3]: - a = "hello" - # This should not generate an error - del a - - -def test_non_empty_tuple_multiple_elements(): - """Variable assigned in for loop over non-empty tuple with multiple elements.""" - for x in (1, 2, 3): - b = "world" - # This should not generate an error - del b - - -def test_empty_list_literal(): - """Variable assigned in for loop over empty list literal should be reported as possibly unbound.""" - for x in []: - # This should generate an error because c is possibly unbound - c = 789 - del c - - -def test_empty_tuple_literal(): - """Variable assigned in for loop over empty tuple literal should be reported as possibly unbound.""" - for x in (): - # This should generate an error because d is possibly unbound - d = 999 - del d - - -def test_non_literal_iterable(): - """Variable assigned in for loop over non-literal iterable should still be reported as possibly unbound.""" - items = [1, 2, 3] - for x in items: - e = "test" - # This should generate an error because e is possibly unbound - del e - - -def test_string_literal(): - """Variable assigned in for loop over string literal should still be reported as possibly unbound (not implemented).""" - for x in "abc": - f = "string" - # This should generate an error because string literals are not yet supported - del f - - -def test_starred_expression(): - """Variable assigned in for loop over starred expression should be reported as possibly unbound.""" - empty: list[int] = [] - for x in [*empty]: - g = 1 - # This should generate an error because g is possibly unbound - del g - - -def test_list_comprehension(): - """Variable assigned in for loop over list comprehension should be reported as possibly unbound.""" - for x in [v for v in []]: - h = 1 - # This should generate an error because h is possibly unbound - del h - - -def test_all_continue_loop(): - """Test that post-loop code is reachable even when all paths in loop body end with continue.""" - for x in [1, 2, 3]: - continue - # Post-loop code should be reachable. - # x appears possibly unbound because the save/restore fallback uses the loop-header state - # which includes the pre-assignment entry path. - i = x # This should generate an error - - -def test_break_in_guaranteed_loop(): - """break exits the loop, but the body still executes at least once.""" - for x in [1, 2, 3]: - y = 1 - break - # y is definitely assigned because the loop body runs at least once before break - del y # This should not generate an error - - -def test_conditional_break_in_guaranteed_loop(): - """Conditional break — variable assigned before the condition is always assigned.""" - cond = True - for x in [1, 2, 3]: - y = 1 - if cond: - break - # y is always assigned before the conditional break check - del y # This should not generate an error - - -def test_for_else_guaranteed_no_break(): - """for...else where the guaranteed loop has no break — else always executes.""" - for x in [1, 2]: - y = 1 - else: - z = 2 - del y # This should not generate an error - del z # This should not generate an error — else runs because no break - - -def test_for_else_guaranteed_with_break(): - """for...else where guaranteed loop always breaks — else never executes.""" - for x in [1, 2]: - y = 1 - break - else: - z = 2 - del y # This should not generate an error — y assigned before break - del z # This should generate an error — else skipped due to unconditional break - - -def test_return_in_guaranteed_loop() -> int: - """return in guaranteed loop body — post-loop code is unreachable.""" - for x in [1]: - return 42 - # Post-loop code is unreachable because every iteration returns - y = 1 # unreachable, no possibly-unbound error expected - return y - - -def test_raise_in_guaranteed_loop(): - """raise in guaranteed loop body — post-loop code is unreachable.""" - for x in [1]: - raise ValueError() - # Post-loop code is unreachable because every iteration raises - y = 1 # unreachable, no possibly-unbound error expected - - -def test_nested_guaranteed_loops(): - """Nested for loops over non-empty literals — both execute at least once.""" - for x in [1]: - for y in [2]: - z = 1 - # z is definitely assigned because both loops execute at least once - del z # This should not generate an error - - - diff --git a/packages/vipeye-internal/src/tests/samples/literalString1.py b/packages/vipeye-internal/src/tests/samples/literalString1.py deleted file mode 100644 index 45a6192e..00000000 --- a/packages/vipeye-internal/src/tests/samples/literalString1.py +++ /dev/null @@ -1,92 +0,0 @@ -# This sample tests the evaluation of LiteralString as described -# in PEP 675. - -from typing import Iterable -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Literal, - LiteralString, -) - - -def func1(a: str, b: bytes, c: Literal["a"], d: Literal["a", "b"], e: Literal["a", 1]): - # This should generate an error. - v1: LiteralString = a - - # This should generate an error. - v2: LiteralString = b - - # This should generate an error. - v3: LiteralString = b"" - - v4: LiteralString = "Hello!" - - v5: LiteralString = "Hello " + "Bob" - - # This should generate an error. - v6: LiteralString = f"{a}" - - # This should generate an error. - v7: LiteralString[int] - - v8: LiteralString = c - - v9: LiteralString = d - - # This should generate an error. - v10: LiteralString = e - - -def func2(a: str): ... - - -def func3(a: LiteralString): - func2(a) - a.lower() - - _ = a + "hi" + a.capitalize() - - -def func4(a: LiteralString, parts: Iterable[LiteralString]): - v1 = "".join(parts) - reveal_type(v1, expected_text="LiteralString") - - v2 = "".join([a, a]) - reveal_type(v2, expected_text="LiteralString") - - -def func5( - a: LiteralString, b: str, parts: Iterable[tuple[LiteralString, LiteralString]] -): - v1: LiteralString = f"{a} {a}" - - v2: LiteralString = f"{a}{a}" - - v3: LiteralString = f"{'xxx'}{'xxx'}" - - # This should generate an error because "b" is not literal. - v4: LiteralString = f"{a} {b}" - - -def func6(a: LiteralString): - v1 = a.capitalize() - - v2 = a[0] - - a = "hi" - - v3: list[LiteralString] = "1 2 3".split(" ") - - -def func7(a: Literal["a", "b"], b: Literal["a", 1]): - v1: LiteralString = f"{a}" - - # This should generate an error because "b" is not a string literal. - v2: LiteralString = f"{b}" - - -def func8(a: list[LiteralString], b: list[Literal["a"]]): - # This should generate an error because of invariance rules. - v1: list[str] = a - - # This should generate an error because of invariance rules. - v2: list[LiteralString] = b diff --git a/packages/vipeye-internal/src/tests/samples/literalString2.py b/packages/vipeye-internal/src/tests/samples/literalString2.py deleted file mode 100644 index 6b3dfd3d..00000000 --- a/packages/vipeye-internal/src/tests/samples/literalString2.py +++ /dev/null @@ -1,17 +0,0 @@ -# This tests the case where LiteralString is used as a bound for a -# type variable. - -from typing import TypeVar, Generic -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - LiteralString, -) - -L = TypeVar("L", bound=LiteralString) - - -class Foo(Generic[L]): - def __init__(self, value: L) -> None: - self.value = value - - -foo = Foo("hmm") diff --git a/packages/vipeye-internal/src/tests/samples/literalString3.py b/packages/vipeye-internal/src/tests/samples/literalString3.py deleted file mode 100644 index e9c49414..00000000 --- a/packages/vipeye-internal/src/tests/samples/literalString3.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case where a LiteralString is used as the bound -# of a TypeVar. - -from typing import Generic, LiteralString, TypeVar - -T = TypeVar("T") -T_LS = TypeVar("T_LS", bound=LiteralString) - - -class ClassA(Generic[T]): - def __init__(self, val: T) -> None: ... - - -def func1(x: T) -> ClassA[T]: - return ClassA(x) - - -def func2(x: T_LS | None, default: T_LS) -> ClassA[T_LS]: - if x is None: - x = default - - reveal_type(x, expected_text="T_LS@func2") - out = func1(x) - reveal_type(out, expected_text="ClassA[T_LS@func2]") - return out diff --git a/packages/vipeye-internal/src/tests/samples/literals1.py b/packages/vipeye-internal/src/tests/samples/literals1.py deleted file mode 100644 index 44b514ce..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals1.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests type checking support for "Literal" - -from typing import Literal - -ValidResponses = Literal["a", b"b", Literal["cc", True, None]] - - -def foo(a: ValidResponses): - pass - - -foo("a") -foo(b"b") -foo("cc") -foo(True) -foo(None) - -# This should generate an error because 'b' -# isn't a valid literal value. -foo("b") - -# This should generate an error because 'cc' -# isn't a valid literal value. -foo("c") - -# This should generate an error because False -# isn't a valid literal value. -foo(False) - -# This should generate an error because 3 -# isn't a valid literal value. -foo(3) - - -# This should generate an error because floats -# cannot be used as literals. -invalidType = 3 # type: Literal[3.4] - -# This should generate an error because 2 -# is not a valid literal value. -mismatch = 2 # type: Literal[3, 4, '5'] - -a: Literal[+3] = -(-(+++3)) -b: Literal[-2] = +-+2 - -# This should generate an error because literals are -# not instantiable. -c = Literal[1]() - - -bytes1 = b"\x7f" -reveal_type(bytes1, expected_text='Literal[b"\\x7f"]') -bytes2 = b"\x20" -reveal_type(bytes2, expected_text='Literal[b" "]') -bytes3 = b'"' -reveal_type(bytes3, expected_text='Literal[b"\\""]') -bytes4 = b"'" -reveal_type(bytes4, expected_text='Literal[b"\'"]') - - -t1 = [Literal[1], Literal[2]] -reveal_type(t1, expected_text="list[type[Literal]]") - -t2 = Literal[*(1, 2)] -reveal_type(t2, expected_text="Literal") - -values = ("a", "b", "c") -t3 = Literal[values] -reveal_type(t3, expected_text="Literal") diff --git a/packages/vipeye-internal/src/tests/samples/literals2.py b/packages/vipeye-internal/src/tests/samples/literals2.py deleted file mode 100644 index 857a39ba..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests assignment of literals to declared -# types that use literals in their type arguments. - -from typing import Dict, List, Literal, Set, TypeVar - -Number = Literal["One", "Two"] - -# This should generate an error because 'Three' is not -# allowed in the Number type. -numbers_mapping: Dict[Number, int] = {"One": 1, "Two": 2, "Three": 3} - -# This should generate an error because 'Three' is not -# allowed in the Number type. -a: List[Number] = ["Three"] - -# This should generate an error because 'Three' is not -# allowed in the Number type. -b: Set[Number] = {"One", "Three"} - - -LetterGrade = Literal["A", "B", "C", "D", "F"] - -_T = TypeVar("_T") - - -def func1(x: _T) -> _T: ... - - -grade: LetterGrade = func1("A") diff --git a/packages/vipeye-internal/src/tests/samples/literals3.py b/packages/vipeye-internal/src/tests/samples/literals3.py deleted file mode 100644 index b429d95c..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals3.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests that literal enums work. - -from enum import Enum -from typing import Literal - - -class SomeEnum(Enum): - SOME_ENUM_VALUE1 = "1" - SOME_ENUM_VALUE2 = "2" - SOME_ENUM_VALUE3 = "3" - - -class Foo: - pass - - -# This should generate two errors because Foo() is not a valid -# type expression, and Foo is not an allowed literal value. -a: Literal["hi", Foo()] - -# This should generate an error because SomeEnum is not an -# allowed literal value. -b: Literal["hi", SomeEnum] - -L2 = Literal["hi", SomeEnum.SOME_ENUM_VALUE1] - - -def foo(a: int) -> L2: - if a > 3: - return "hi" - elif a > 4: - return SomeEnum.SOME_ENUM_VALUE1 - elif a > 5: - # This should generate an error because it's - # not part of the L1 literal. - return SomeEnum.SOME_ENUM_VALUE2 - else: - # This should generate an error because it's - # not part of the L1 literal. - return "bye" diff --git a/packages/vipeye-internal/src/tests/samples/literals4.py b/packages/vipeye-internal/src/tests/samples/literals4.py deleted file mode 100644 index aeb1a7c1..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals4.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests various aliases of the typing module -# when used with Literal. - -import typing -import typing as t -import typing as typ - -a: typing.Literal[True] = True -b: t.Literal["Hello"] = "Hello" -c: typ.Literal[True, "Hello"] = True diff --git a/packages/vipeye-internal/src/tests/samples/literals5.py b/packages/vipeye-internal/src/tests/samples/literals5.py deleted file mode 100644 index e7517645..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals5.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests literals that employ type aliases. - -from typing import Literal, Union - - -Numeric = Literal[1, "3.4"] - -DerivedLiteral1 = Literal["a", Numeric] - -var1: DerivedLiteral1 = "3.4" - -# This should generate an error. -var2: DerivedLiteral1 = "3.5" - - -NotNumeric = Union[Literal[1, 3], int] - -# This should generate an error because NotNumeric -# isn't a legal literal. -DerivedLiteral2: Literal[NotNumeric, 3] - - -ReadOnlyMode = Literal["r", "r+"] -WriteAndTruncateMode = Literal["w", "w+", "wt", "w+t"] -WriteNoTruncateMode = Literal["r+", "r+t"] -AppendMode = Literal["a", "a+", "at", "a+t"] - -AllModes = Literal[ReadOnlyMode, WriteAndTruncateMode, WriteNoTruncateMode, AppendMode] diff --git a/packages/vipeye-internal/src/tests/samples/literals6.py b/packages/vipeye-internal/src/tests/samples/literals6.py deleted file mode 100644 index 9f849a16..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals6.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests various illegal forms of Literal. - -from enum import Enum -from pathlib import Path -from typing import Any, Literal, TypeVar - -Wrong1 = Literal[3 + 4] - -Wrong2 = Literal["foo".replace("o", "b")] - -Wrong3 = Literal[4 + 3j] - -Wrong4 = Literal[-4 + 2j] - -Wrong5 = Literal[(1, "foo", "bar")] - -Wrong6 = Literal[{"a": "b", "c": "d"}] - -Wrong7 = Literal[Path("abcd")] -T = TypeVar("T") - -Wrong8 = Literal[T] - -Wrong9 = Literal[3.14] - -Wrong10 = Literal[Any] - -Wrong11 = Literal[...] - - -def func(): ... - - -Wrong12 = Literal[func] -some_variable = "foo" - -Wrong13 = Literal[some_variable] - - -# This should generate two errors. -var1: Literal[3 + 4] - -# This should generate two errors. -var2: Literal["foo".replace("o", "b")] - -# This should generate two errors. -var3: Literal[4 + 3j] - -# This should generate three errors. -var4: Literal[-4 + 2j] - -# This should generate an error. -var5: Literal[(1, "foo", "bar")] - -# This should generate an error. -var6: Literal[{"a": "b", "c": "d"}] - -# This should generate two errors. -var7: Literal[Path("abcd")] - -# This should generate an error. -var8: Literal[T] - -# This should generate an error. -var9: Literal[3.14] - -# This should generate an error. -var10: Literal[Any] - -# This should generate an error. -var11: Literal[...] - -# This should generate an error. -var12: Literal[func] - -# This should generate two errors. -var13: Literal[some_variable] - - -class Enum1(Enum): - A = 1 - B = 2 - - x: str - - -a = Enum1.A - -# This should generate two errors. -var14: Literal[a] - -# This should generate two errors. -var15: Literal[Enum1.x] diff --git a/packages/vipeye-internal/src/tests/samples/literals7.py b/packages/vipeye-internal/src/tests/samples/literals7.py deleted file mode 100644 index a9524260..00000000 --- a/packages/vipeye-internal/src/tests/samples/literals7.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the handling of very large integer values used in -# literals. - -from typing import Literal - -big_int: Literal[9223372036854775808] = 0x8000000000000000 - -# This should generate an error. -y1: Literal[900001231231231456487987456452132130000000000000000000000000000001] = ( - 900001231231231456487987456452132130000000000000000000000000000000 -) - -y2: Literal[900001231231231456487987456452132130000000000000000000000000000001] = ( - 900001231231231456487987456452132130000000000000000000000000000001 -) - -reveal_type( - y2, - expected_text="Literal[900001231231231456487987456452132130000000000000000000000000000001]", -) - -y3 = y2 + 1 -reveal_type( - y3, - expected_text="Literal[900001231231231456487987456452132130000000000000000000000000000002]", -) - -y4 = 0xFFFFFFFFFFF123456789456123456789456123456789456123 -reveal_type( - y4, - expected_text="Literal[1606938044258905427252460960878516708721138816242982137979171]", -) - -y5 = 0b101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 -reveal_type(y5, expected_text="Literal[886151997189943915269204706853563050]") - - -y6 = 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C8381E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665CB2C0F1CC01BD70229388839D2AF05E454504AC78B7582822846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA4571EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88CD68C8BB7C5C6424CFFFFFFFFFFFFFFFF -y7 = y6 * y6 - -y8: Literal[10] = 0b1010 -y9: Literal[10] = 0o12 diff --git a/packages/vipeye-internal/src/tests/samples/loop1.py b/packages/vipeye-internal/src/tests/samples/loop1.py deleted file mode 100644 index d0576961..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop1.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the type checker's ability to handle type -# inferences within loop constructs. - - -def func1(a: list): - pass - - -def func2(): - data = None - - for x in [2, 3]: - if not data: - data = [1, 2] - else: - reveal_type(data, expected_text="list[int]") - func1(data) - else: - # With the change to treat non-empty list literals as guaranteed to execute, - # data is definitely list[int] here (not None) because the loop executes at least once. - reveal_type(data, expected_text="list[int]") - - # This should not generate an error because data is list[int] - func1(data) - - -x = 20 + 20 - - -def func3(): - data = None - - while x: - if not data: - data = [1, 2] - else: - reveal_type(data, expected_text="list[int]") - func1(data) - else: - reveal_type(data, expected_text="list[int] | None") - - # This should generate an error because the - # type checker should be able to determine that - # data must contain None at this point. - func1(data) diff --git a/packages/vipeye-internal/src/tests/samples/loop10.py b/packages/vipeye-internal/src/tests/samples/loop10.py deleted file mode 100644 index 78c9cb6e..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop10.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the case where dependent types within -# a loop are assigned using tuples. - - -def fibonacci(): - a, b = 1, 1 - while True: - yield a - a, b = b, a + b - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/loop11.py b/packages/vipeye-internal/src/tests/samples/loop11.py deleted file mode 100644 index 4fa979b1..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop11.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests for the detection of unbound or partially-unbound -# variables within loops. - -import random - -for a in [1, 2, 3]: - # This should generate an error because b is unbound. - if b == 1: - b = 2 - - -for a in [1, 2, 3]: - if random.random() > 0.5: - c = 2 - - # This should generate an error because c is potentially unbound. - print(c) - -while True: - # This should generate an error because d is unbound. - if d == 1: - d = 2 diff --git a/packages/vipeye-internal/src/tests/samples/loop12.py b/packages/vipeye-internal/src/tests/samples/loop12.py deleted file mode 100644 index 685dda52..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop12.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the evaluation of a variable whose type is narrowed -# within a loop body. - - -class ClassA: - def non_property(self) -> int: ... - - def do_stuff(self, x: int | None): - while True: - if x is not None: - a = x - else: - a = self.non_property - - # This should generate an error because the type of "a" - # is not compatible with a "-" operator. - _ = a - 0 diff --git a/packages/vipeye-internal/src/tests/samples/loop13.py b/packages/vipeye-internal/src/tests/samples/loop13.py deleted file mode 100644 index 6bf83c99..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop13.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a loop uses tuple assignments. It verifies -# that no "unknown" values are evaluated for variables assigned in the loop. - -# viper: strict - -nums: list[int] = [1, 2, 3] -max_product, min_product = nums[0], nums[0] - -for x in nums[1:]: - candidates = max_product * x, min_product * x - min_product = min(candidates) - max_product = max(candidates) - reveal_type(candidates, expected_text="tuple[int, int]") diff --git a/packages/vipeye-internal/src/tests/samples/loop14.py b/packages/vipeye-internal/src/tests/samples/loop14.py deleted file mode 100644 index 6cfeb7ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop14.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests a loop that modifies a variable through type narrowing. - - -class State: - def confirm_dialog(self) -> "State | bool": - return False - - -state = State() -reveal_type(state, expected_text="State") - -for _ in range(1): - result = state.confirm_dialog() - if isinstance(result, State): - reveal_type(state, expected_text="State") - reveal_type(result, expected_text="State") - state = result - else: - reveal_type(state, expected_text="State") - reveal_type(result, expected_text="bool") diff --git a/packages/vipeye-internal/src/tests/samples/loop15.py b/packages/vipeye-internal/src/tests/samples/loop15.py deleted file mode 100644 index 238b28bd..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop15.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests loops that contain nested comprehensions and -# variables that depend on each other. - -# viper: strict - - -def func1(boards: list[list[list[int]]]): - for _ in [0]: - remain = [[set(line) for line in zip(*b)] for b in boards] - boards = [b for b, u in zip(boards, remain) if all(u)] - - -def func2(boards: list[list[list[int]]]): - for _ in [1]: - remain = [[set(line) for line in b] for b in boards] - boards = [b for b, u in zip(boards, remain) if all(u)] - - -def func3(boards: list[list[list[int]]]): - for _ in [1]: - remain = [[set(line) for line in (*b, *zip(*b))] for b in boards] - boards = [b for b, u in zip(boards, remain) if all(u)] diff --git a/packages/vipeye-internal/src/tests/samples/loop16.py b/packages/vipeye-internal/src/tests/samples/loop16.py deleted file mode 100644 index 4ba894e8..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop16.py +++ /dev/null @@ -1,322 +0,0 @@ -# This sample tests a complex function that contains a loop and a long -# chain of if/elif statements. - -from random import randint - - -def get_ipv4(): - try: - while 1: - ip1, ip2, ip3, ip4 = ( - randint(1, 255), - randint(1, 255), - randint(1, 255), - randint(1, 255), - ) - - if ip1 == 127: - continue - elif ip1 == 0: - continue - elif ip1 == 1: - continue - elif ip1 == 2: - continue - elif ip1 == 3: - continue - elif ip1 == 4: - continue - elif ip1 == 5: - continue - elif ip1 == 6: - continue - elif ip1 == 7: - continue - elif ip1 == 8: - continue - elif ip1 == 9: - continue - elif ip1 == 11: - continue - elif ip1 == 12: - continue - elif ip1 == 17: - continue - elif ip1 == 19: - continue - elif ip1 == 15: - continue - elif ip1 == 56: - continue - elif ip1 == 10: - continue - elif ip1 == 25: - continue - elif ip1 == 49: - continue - elif ip1 == 50: - continue - elif ip1 == 73: - continue - elif ip1 == 137: - continue - elif ip1 == 11: - continue - elif ip1 == 21: - continue - elif ip1 == 22: - continue - elif ip1 == 26: - continue - elif ip1 == 28: - continue - elif ip1 == 29: - continue - elif ip1 == 30: - continue - elif ip1 == 33: - continue - elif ip1 == 55: - continue - elif ip1 == 214: - continue - elif ip1 == 215: - continue - elif ip1 == 192 and ip2 == 168: - continue - elif ip1 == 146 and ip2 == 17: - continue - elif ip1 == 146 and ip2 == 80: - continue - elif ip1 == 146 and ip2 == 98: - continue - elif ip1 == 146 and ip2 == 154: - continue - elif ip1 == 147 and ip2 == 159: - continue - elif ip1 == 148 and ip2 == 114: - continue - elif ip1 == 150 and ip2 == 125: - continue - elif ip1 == 150 and ip2 == 133: - continue - elif ip1 == 150 and ip2 == 144: - continue - elif ip1 == 150 and ip2 == 149: - continue - elif ip1 == 150 and ip2 == 157: - continue - elif ip1 == 150 and ip2 == 184: - continue - elif ip1 == 150 and ip2 == 190: - continue - elif ip1 == 150 and ip2 == 196: - continue - elif ip1 == 152 and ip2 == 82: - continue - elif ip1 == 152 and ip2 == 229: - continue - elif ip1 == 157 and ip2 == 202: - continue - elif ip1 == 157 and ip2 == 217: - continue - elif ip1 == 161 and ip2 == 124: - continue - elif ip1 == 162 and ip2 == 32: - continue - elif ip1 == 155 and ip2 == 96: - continue - elif ip1 == 155 and ip2 == 149: - continue - elif ip1 == 155 and ip2 == 155: - continue - elif ip1 == 155 and ip2 == 178: - continue - elif ip1 == 164 and ip2 == 158: - continue - elif ip1 == 156 and ip2 == 9: - continue - elif ip1 == 167 and ip2 == 44: - continue - elif ip1 == 168 and ip2 == 68: - continue - elif ip1 == 168 and ip2 == 85: - continue - elif ip1 == 168 and ip2 == 102: - continue - elif ip1 == 203 and ip2 == 59: - continue - elif ip1 == 204 and ip2 == 34: - continue - elif ip1 == 207 and ip2 == 30: - continue - elif ip1 == 117 and ip2 == 55: - continue - elif ip1 == 117 and ip2 == 56: - continue - elif ip1 == 80 and ip2 == 235: - continue - elif ip1 == 207 and ip2 == 120: - continue - elif ip1 == 209 and ip2 == 35: - continue - elif ip1 == 64 and ip2 == 70: - continue - elif ip1 == 172 and ip2 >= 16 and ip2 < 32: - continue - elif ip1 == 100 and ip2 >= 64 and ip2 < 127: - continue - elif ip1 == 169 and ip2 > 254: - continue - elif ip1 == 198 and ip2 >= 18 and ip2 < 20: - continue - elif ip1 == 64 and ip2 >= 69 and ip2 < 227: - continue - elif ip1 == 128 and ip2 >= 35 and ip2 < 237: - continue - elif ip1 == 129 and ip2 >= 22 and ip2 < 255: - continue - elif ip1 == 130 and ip2 >= 40 and ip2 < 168: - continue - elif ip1 == 131 and ip2 >= 3 and ip2 < 251: - continue - elif ip1 == 132 and ip2 >= 3 and ip2 < 251: - continue - elif ip1 == 134 and ip2 >= 5 and ip2 < 235: - continue - elif ip1 == 136 and ip2 >= 177 and ip2 < 223: - continue - elif ip1 == 138 and ip2 >= 13 and ip2 < 194: - continue - elif ip1 == 139 and ip2 >= 31 and ip2 < 143: - continue - elif ip1 == 140 and ip2 >= 1 and ip2 < 203: - continue - elif ip1 == 143 and ip2 >= 45 and ip2 < 233: - continue - elif ip1 == 144 and ip2 >= 99 and ip2 < 253: - continue - elif ip1 == 146 and ip2 >= 165 and ip2 < 166: - continue - elif ip1 == 147 and ip2 >= 35 and ip2 < 43: - continue - elif ip1 == 147 and ip2 >= 103 and ip2 < 105: - continue - elif ip1 == 147 and ip2 >= 168 and ip2 < 170: - continue - elif ip1 == 147 and ip2 >= 198 and ip2 < 200: - continue - elif ip1 == 147 and ip2 >= 238 and ip2 < 255: - continue - elif ip1 == 150 and ip2 >= 113 and ip2 < 115: - continue - elif ip1 == 152 and ip2 >= 151 and ip2 < 155: - continue - elif ip1 == 153 and ip2 >= 21 and ip2 < 32: - continue - elif ip1 == 155 and ip2 >= 5 and ip2 < 10: - continue - elif ip1 == 155 and ip2 >= 74 and ip2 < 89: - continue - elif ip1 == 155 and ip2 >= 213 and ip2 < 222: - continue - elif ip1 == 157 and ip2 >= 150 and ip2 < 154: - continue - elif ip1 == 158 and ip2 >= 1 and ip2 < 21: - continue - elif ip1 == 158 and ip2 >= 235 and ip2 < 247: - continue - elif ip1 == 159 and ip2 >= 120 and ip2 < 121: - continue - elif ip1 == 160 and ip2 >= 132 and ip2 < 151: - continue - elif ip1 == 64 and ip2 >= 224 and ip2 < 227: - continue - elif ip1 == 162 and ip2 >= 45 and ip2 < 47: - continue - elif ip1 == 163 and ip2 >= 205 and ip2 < 207: - continue - elif ip1 == 164 and ip2 >= 45 and ip2 < 50: - continue - elif ip1 == 164 and ip2 >= 217 and ip2 < 233: - continue - elif ip1 == 207 and ip2 >= 60 and ip2 < 62: - continue - elif ip1 == 104 and ip2 >= 16 and ip2 < 31: - continue - elif ip1 == 193 and ip2 == 164: - continue - elif ip1 == 120 and ip2 >= 103 and ip2 < 108: - continue - elif ip1 == 188 and ip2 == 68: - continue - elif ip1 == 78 and ip2 == 46: - continue - elif ip1 >= 224: - continue - elif (ip1 == 178 and ip2 == 128) or (ip1 == 123 and ip2 == 59): - continue - elif ( - (ip1 == 124 and ip2 == 244) - or (ip1 == 178 and ip2 == 254) - or (ip1 == 185 and ip2 == 168) - or (ip1 == 178 and ip2 == 79) - ): - continue - elif ip1 == 192 and ip2 == 88 and ip3 == 99: - continue - elif ip1 == 240: - continue - elif ip1 == 255 and ip2 == 255 and ip3 == 255 and ip4 == 255: - continue - elif ip1 == 126: - continue - elif ip1 == 13 and ip2 == 107 and ip3 == 6 and ip4 == 152: - continue - # elif ip1 == 13 and ip2 == 107 and ip3 == 18 and ip4 == 10: - # continue - # elif ip1 == 13 and ip2 == 107 and ip3 == 128 and ip4 == 0: - # continue - # elif ip1 == 23 and ip2 == 103 and ip3 == 160 and ip4 == 0: - # continue - # elif ip1 == 40 and ip2 == 96 and ip3 == 0 and ip4 == 0: - # continue - # elif ip1 == 40 and ip2 == 104 and ip3 == 0 and ip4 == 0: - # continue - # elif ip1 == 52 and ip2 == 96 and ip3 == 0 and ip4 == 0: - # continue - # elif ip1 == 131 and ip2 == 253 and ip3 == 33 and ip4 == 215: - # continue - # elif ip1 == 132 and ip2 == 245 and ip3 == 0 and ip4 == 0: - # continue - # elif ip1 == 150 and ip2 == 171 and ip3 == 32 and ip4 == 0: - # continue - # elif ip1 == 204 and ip2 == 79 and ip3 == 197 and ip4 == 215: - # continue - # elif ip1 == 208 and ip2 == 71 and (ip3 > 120 and ip3 < 127): - # continue - # elif ip1 == 117 and ip2 == 102 and (ip3 > 128 and ip3 < 159): - # continue - # elif ip1 == 203 and ip2 == 171 and (ip3 > 192 and ip3 < 207): - # continue - # elif ip1 == 59 and (ip3 > 192 and ip3 < 255): - # continue - # elif ip1 == 163 and ip2 == 233: - # continue - # elif ip1 == 62 and ip2 <= 30: - # continue # honey pots - # elif ip1 == 207 and ip2 >= 31 and ip3 <= 120: - # continue # fbi honey pots - # elif ip1 == 65 and ip2 >= 224 and ip3 <= 226: - # continue # more honey pots - # elif ip1 == 195 and ip2 == 10: - # continue # another honeypot - # elif ip1 == 216 and (ip2 == 25 or ip2 == 94): - # continue - # elif ip1 == 212 and ip2 == 56: - # continue - - ip = f"{str(ip1)}.{str(ip2)}.{str(ip3)}.{str(ip4)}" - return ip - except: - pass diff --git a/packages/vipeye-internal/src/tests/samples/loop17.py b/packages/vipeye-internal/src/tests/samples/loop17.py deleted file mode 100644 index ef63c492..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop17.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the case where a loop involves an unannotated parameter -# and therefore an "unknown" that propagates through the loop. - - -def f(x): - e = 0 - for _ in [0]: - e += x - # After the loop, e is Unknown because the loop is guaranteed to execute - # and e += x makes e Unknown (since x is unknown). - reveal_type(e, expected_text="Unknown") - return e diff --git a/packages/vipeye-internal/src/tests/samples/loop18.py b/packages/vipeye-internal/src/tests/samples/loop18.py deleted file mode 100644 index 04100621..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop18.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests type narrowing in a loop. - -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] -from collections.abc import Generator - - -class A: - parent: Self | None - - -class B: ... - - -def foo(v: A | B | None) -> Generator[A, None, None]: - reveal_type(v) - if not isinstance(v, B): - reveal_type(v, expected_text="A | None") - while v is not None: - reveal_type(v, expected_text="A") - yield v - v = v.parent - reveal_type(v, expected_text="A | None") diff --git a/packages/vipeye-internal/src/tests/samples/loop19.py b/packages/vipeye-internal/src/tests/samples/loop19.py deleted file mode 100644 index d68b9e32..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop19.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests a loop that references instance variables. - - -class Results: - zzz: int - - -class Foo: - yyy: int - - def method1(self, results: list[Results]): - abc = None - for result in results: - if abc is not None and abc.zzz < result.zzz: - abc = result diff --git a/packages/vipeye-internal/src/tests/samples/loop2.py b/packages/vipeye-internal/src/tests/samples/loop2.py deleted file mode 100644 index 05edac95..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop2.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests a piece of code that involves lots -# of cyclical dependencies for type resolution. - - -def needs_str(a: str) -> tuple[str, str]: ... - - -def xxx(): - v1 = "" - v2 = "" - v3 = "" - - v4 = None - - _ = v1 - v3, _ = v3, v2 - v4 = v3 - - for _ in range(1): - assert v4 is not None - v1, v2 = needs_str(v4) - v3 = v1 diff --git a/packages/vipeye-internal/src/tests/samples/loop20.py b/packages/vipeye-internal/src/tests/samples/loop20.py deleted file mode 100644 index d46a66c2..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop20.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests a case where variables within multiple loops, both -# nested and sequential, depend on each other in ways that can result -# in long analysis times. - -from math import isnan -from typing import Callable - - -def linspace(start: float, stop: float, num: int = 50): - if num == 1: - yield stop - return - step = (stop - start) / (num - 1) - for i in range(num): - yield start + step * i - - -def find_zero(f: Callable[[float], float]) -> float: - x_0 = 0 - x_1 = 0 - f_x_0 = 0 - f_x_1 = 0 - while True: - if not (isnan(f_x_0)) and isnan(f_x_1): - x_tests = list(linspace(x_1, x_0, 25)) - f_x_tests = (f(x) for x in x_tests) - for x, f_x in zip(x_tests, f_x_tests): - if not (isnan(f_x)): - x_1 = x - f_x_1 = f_x - break - - elif isnan(f_x_0) and not (isnan(f_x_1)): - x_tests = list(linspace(x_0, x_1, 25)) - f_x_tests = (f(x) for x in x_tests) - for x, f_x in zip(x_tests, f_x_tests): - if not (isnan(f_x)): - x_0 = x - f_x_0 = f_x - break diff --git a/packages/vipeye-internal/src/tests/samples/loop21.py b/packages/vipeye-internal/src/tests/samples/loop21.py deleted file mode 100644 index ad8c6b0e..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop21.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests a loop where some of the variables within the loop -# depend on each other. - -# viper: strict - - -def find_min(nums: list[int]) -> int: - low = 0 - high = len(nums) - 1 - while low < high: - mid = (low + high) // 2 - if nums[mid] > nums[high]: - low = mid + 1 - elif nums[mid] < nums[high]: - high = mid - else: - high -= 1 - return nums[low] diff --git a/packages/vipeye-internal/src/tests/samples/loop22.py b/packages/vipeye-internal/src/tests/samples/loop22.py deleted file mode 100644 index 174e1d08..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop22.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests a case where a loop contains multiple conditional -# checks. - -# viper: strict - -from __future__ import annotations - - -class ListNode: - def __init__(self, val: int = 0, next: ListNode | None = None): - self.val = val - self.next = next - - -def has_cycle(head: ListNode | None) -> bool: - fast_head = head - while head and fast_head: - fast_head = fast_head.next - if fast_head: - fast_head = fast_head.next - return False diff --git a/packages/vipeye-internal/src/tests/samples/loop23.py b/packages/vipeye-internal/src/tests/samples/loop23.py deleted file mode 100644 index 6a95c0e8..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop23.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample covers a case that resulted in a crash due to infinite -# recursion within the code flow engine and type narrowing logic. - - -from typing import Any - - -def func(): - c: Any = None - - while True: - if a: # type: ignore - if c: - pass - - a = c == c.foo diff --git a/packages/vipeye-internal/src/tests/samples/loop24.py b/packages/vipeye-internal/src/tests/samples/loop24.py deleted file mode 100644 index b1dafe97..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop24.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests a loop that involves assignment of a tuple -# within a loop. - -# viper: strict - -var = 0 -while True: - if var and True: - break - else: - var, _ = var + 1, 0 diff --git a/packages/vipeye-internal/src/tests/samples/loop25.py b/packages/vipeye-internal/src/tests/samples/loop25.py deleted file mode 100644 index 403192cd..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop25.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests a series of nested loops containing variables -# with significant dependencies. - -for val1 in range(10): - cnt1 = 4 - for val2 in range(10 - val1): - cnt2 = 4 - if val2 == val1: - cnt2 -= 1 - for val3 in range(10 - val1 - val2): - cnt3 = 4 - if val3 == val1: - cnt3 -= 1 - if val3 == val2: - cnt3 -= 1 - for val4 in range(10 - val1 - val2 - val3): - cnt4 = 4 - if val4 == val1: - cnt4 -= 1 - if val4 == val2: - cnt4 -= 1 - if val4 == val3: - cnt4 -= 1 - for val5 in range(10 - val1 - val2 - val3 - val4): - cnt5 = 4 - if val5 == val1: - cnt5 -= 1 - if val5 == val2: - cnt5 -= 1 - if val5 == val3: - cnt5 -= 1 - if val5 == val4: - cnt5 -= 1 - val6 = 10 - val1 - val2 - val3 - val4 - val5 - cnt6 = 4 - if val6 == val1: - cnt6 -= 1 - if val6 == val2: - cnt6 -= 1 - if val6 == val3: - cnt6 -= 1 - if val6 == val4: - cnt6 -= 1 - if val6 == val5: - cnt6 -= 1 diff --git a/packages/vipeye-internal/src/tests/samples/loop26.py b/packages/vipeye-internal/src/tests/samples/loop26.py deleted file mode 100644 index e1298339..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop26.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests proper type narrowing within a double loop. - -# viper: strict - -from typing import Callable - - -def func(call: Callable[[], None] | None): - while True: - while True: - if call is None or call(): - break diff --git a/packages/vipeye-internal/src/tests/samples/loop27.py b/packages/vipeye-internal/src/tests/samples/loop27.py deleted file mode 100644 index f1eb72fc..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop27.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where an annotated variable in a loop -# is used as an index, an implicit argument for __getitem__. - -# viper: strict - - -def func1(nums: list[int], target: int) -> None: - var = nums[0] - while True: - mid = var - if nums[mid] == target: - return - if var: - var = mid - else: - var = mid diff --git a/packages/vipeye-internal/src/tests/samples/loop28.py b/packages/vipeye-internal/src/tests/samples/loop28.py deleted file mode 100644 index 87500b56..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop28.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests type evaluation for a nested loop that involves -# accesses to an instance variable accessed through a member access -# expression that requires narrowing. - -from concurrent import futures -from concurrent.futures import Future -from typing import Any, Dict, Optional - - -class A: - def __init__(self): - self.pending: Optional[Dict[Future[Any], int]] - self.foo: bool - - def poll(self): - assert self.pending is not None - while True: - if self.pending: - pass - - ready, _ = futures.wait(self.pending) - - for future_id in ready: - self.pending.pop(future_id) - - future_id.result() - if self.foo: - pass diff --git a/packages/vipeye-internal/src/tests/samples/loop29.py b/packages/vipeye-internal/src/tests/samples/loop29.py deleted file mode 100644 index b23eafd4..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop29.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where a variable type declaration is found -# within a loop and the variable is used within a conditional expression -# within the same loop. - -from enum import Enum - - -class MyEnum(Enum): - A = 0 - - -def func1(vals: list[MyEnum]): - for val1 in vals: - val2: MyEnum = val1 - if val2 == MyEnum.A: - pass diff --git a/packages/vipeye-internal/src/tests/samples/loop3.py b/packages/vipeye-internal/src/tests/samples/loop3.py deleted file mode 100644 index 3c510913..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop3.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests a piece of code that involves lots -# of cyclical dependencies for type resolution. - - -n: str | None = None -while True: - if n is None: - n = "" - else: - n = n + "" diff --git a/packages/vipeye-internal/src/tests/samples/loop30.py b/packages/vipeye-internal/src/tests/samples/loop30.py deleted file mode 100644 index 54b56298..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop30.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests type evaluation in a nested loop. - -a: int | None = None - -for _ in range(1): - for i in range(1): - a = i - j = a - -reveal_type(a, expected_type=int | None) diff --git a/packages/vipeye-internal/src/tests/samples/loop31.py b/packages/vipeye-internal/src/tests/samples/loop31.py deleted file mode 100644 index 9eebe2b8..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop31.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the case where an unannotated local variable -# has a dependency on itself when evaluating its effective type. - - -def func1(arg: str): ... - - -def func2(arg: int): - for _ in range(1): - loc = arg - loc = loc if loc else loc - - # This should generate an error. - func1(loc) diff --git a/packages/vipeye-internal/src/tests/samples/loop32.py b/packages/vipeye-internal/src/tests/samples/loop32.py deleted file mode 100644 index 36b97c83..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop32.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests type narrowing of instance variables in the presence -# of a double nested loop. - - -def func1(x: str | None): - assert x is not None - - for i in range(10): - for j in range(10): - x = x + "" diff --git a/packages/vipeye-internal/src/tests/samples/loop33.py b/packages/vipeye-internal/src/tests/samples/loop33.py deleted file mode 100644 index 607ef426..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop33.py +++ /dev/null @@ -1,9 +0,0 @@ -# This sample tests a nested loop containing an augmented assignment. - -count = 0 - -for x in range(1): - for y in range(1): - count += 1 - -reveal_type(count, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/loop34.py b/packages/vipeye-internal/src/tests/samples/loop34.py deleted file mode 100644 index 136da58a..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop34.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests a doubly-nested loop with a function (max) that -# uses a TypeVar. - -from typing import Any, Protocol, TypeAlias, TypeVar - -_T_contra = TypeVar("_T_contra", contravariant=True) - - -class SupportsDunderGT(Protocol[_T_contra]): - def __gt__(self, __other: _T_contra) -> bool: ... - - -class SupportsDunderLT(Protocol[_T_contra]): - def __lt__(self, __other: _T_contra) -> bool: ... - - -SupportsRichComparison: TypeAlias = SupportsDunderLT[Any] | SupportsDunderGT[Any] - -SupportsRichComparisonT = TypeVar( - "SupportsRichComparisonT", bound=SupportsRichComparison -) - - -def max( - __arg1: SupportsRichComparisonT, __arg2: SupportsRichComparisonT -) -> SupportsRichComparisonT: ... - - -a: int = 1 -while True: - while a >= 0: - a -= 1 - a = max(0, a) diff --git a/packages/vipeye-internal/src/tests/samples/loop35.py b/packages/vipeye-internal/src/tests/samples/loop35.py deleted file mode 100644 index dc80dc49..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop35.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests that code flow analysis of a list comprehension -# within a loop eliminates any Unknowns. - -# viper: strict - -lst = [1] -while True: - lst = [val for val in lst] diff --git a/packages/vipeye-internal/src/tests/samples/loop36.py b/packages/vipeye-internal/src/tests/samples/loop36.py deleted file mode 100644 index e4c45870..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop36.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests code that uses an augmented assignment to a subscript -# within a loop. - -# viper: strict - -from typing import Any - - -def func1(any: Any): - l: list[int] = any - while any: - if any: - l[0] += 0 - else: - l[0] += 0 diff --git a/packages/vipeye-internal/src/tests/samples/loop37.py b/packages/vipeye-internal/src/tests/samples/loop37.py deleted file mode 100644 index 476c63a2..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop37.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that a variable assigned in a doubly-nested loop -# eliminates any Unknowns. - -# viper: strict - - -def func(): - a_value: int = 0 - a_list: list[int] = [] - - for _ in range(1): - for _ in range(1): - a_value = a_list[a_value] diff --git a/packages/vipeye-internal/src/tests/samples/loop38.py b/packages/vipeye-internal/src/tests/samples/loop38.py deleted file mode 100644 index 5ce66a75..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop38.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests a code flow graph that includes a nested loop -# and a variable that is assigned only in the outer loop. - - -# viper: strict - - -# * Code flow graph for func1: -# Assign[step+=1] ── True[step==0] ── Assign[node=] ── Loop ┬─ Loop ┬─ Assign[step=1] ── Start -# │ ╰ Circular(Assign[step+=1]) -# ╰ FalseNever ─ False ─ Circular(Assign[node]) -def func1(nodes: list[int]): - step = 1 - while True: - for node in nodes: - if node or step == 0: - step += 1 - break - else: - return diff --git a/packages/vipeye-internal/src/tests/samples/loop39.py b/packages/vipeye-internal/src/tests/samples/loop39.py deleted file mode 100644 index c61ba99d..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop39.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests a loop where there are multiple symbols -# that depend on each other. - -# viper: strict - - -def func1() -> str | None: ... - - -s1: str | None = None -s2 = None -while True: - obj = func1() - - x = s2 - condition = obj and obj != s1 - - s1 = obj - s2 = obj diff --git a/packages/vipeye-internal/src/tests/samples/loop4.py b/packages/vipeye-internal/src/tests/samples/loop4.py deleted file mode 100644 index bdcc1af3..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop4.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests a loop with self-references. - -a: bool = False -x: int = 0 - -while len(input()) < 42: - x += 43 - - if a and a: - continue - - if a: - print("") - continue - - x += 44 diff --git a/packages/vipeye-internal/src/tests/samples/loop40.py b/packages/vipeye-internal/src/tests/samples/loop40.py deleted file mode 100644 index 1662ed1e..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop40.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample verifies that unknown types are properly eliminated from -# a loop. - -# viper: strict - - -def func1(a: int, b: str, c: str): - v1: list[tuple[str, str, str]] = [] - for _ in range(0): - if a == 0: - print(v1[-1][0]) - last = v1[-1] - v1[-1] = (b, last[1], c) diff --git a/packages/vipeye-internal/src/tests/samples/loop41.py b/packages/vipeye-internal/src/tests/samples/loop41.py deleted file mode 100644 index 21e2c883..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop41.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests a few cases that involve a loop with a conditional. These -# case regressed and were not caught by any other test cases. - -from typing import TypeVar, Any - -T = TypeVar("T") - - -def func1(x: T) -> T: ... - - -def func2(schema: bool): ... - - -def func3(v1: list[bool], v2: int | str): - for _ in v1: - if v2 in set([1, 2, 3]): - func1(v2) - - # This should generate an error. - func2(v2) - - -def func4(x: Any, b: Any): - a = x - while a < 1: - if a: - b = int(b) - else: - b = a - - if b: - # This should generate an error. - return a.x(dummy) diff --git a/packages/vipeye-internal/src/tests/samples/loop42.py b/packages/vipeye-internal/src/tests/samples/loop42.py deleted file mode 100644 index f0577977..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop42.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests a looping case involving type narrowing within -# a loop where the act of determining whether it's a supported type -# guard results in a circular dependency between variables. - -# viper: reportUnnecessaryComparison=true - - -def func1(): - a = None - b = "" - - while True: - if b != a: - a = b diff --git a/packages/vipeye-internal/src/tests/samples/loop43.py b/packages/vipeye-internal/src/tests/samples/loop43.py deleted file mode 100644 index 7bdc7a26..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop43.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the proper type narrowing of a constrained TypeVar -# within a loop. - -from typing import TypeVar - -T = TypeVar("T", str, None) - - -def func1(input_string: T) -> T: - if input_string is None: - return input_string - - for bad_char in set(input_string): - input_string = input_string.replace(bad_char, "") - - return input_string diff --git a/packages/vipeye-internal/src/tests/samples/loop44.py b/packages/vipeye-internal/src/tests/samples/loop44.py deleted file mode 100644 index 35ca9e1d..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop44.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a variable assigned within a loop -# initially appears to be unreachable (while some variable types are -# incomplete) but is later determined to be reachable. - - -def func(lines: list[str], val: list[str] | None): - for line in lines: - if val is None: - if line == "": - val = [] - continue - match = line - match.encode() diff --git a/packages/vipeye-internal/src/tests/samples/loop45.py b/packages/vipeye-internal/src/tests/samples/loop45.py deleted file mode 100644 index e7a7815b..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop45.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a match statement is used in a loop -# and the subject is potentially narrowed in the loop, therefore creating -# a circular dependency. - -from typing import Literal - - -def func1(lit: Literal["a", "b"]) -> None: - for _ in range(2): - match lit: - case "a": - v = "123" - - case "b": - v = "234" - - v.replace(",", ".") diff --git a/packages/vipeye-internal/src/tests/samples/loop46.py b/packages/vipeye-internal/src/tests/samples/loop46.py deleted file mode 100644 index b5430569..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop46.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests a doubly-nested loop with an indexed expression being -# updated each time. - - -def func1(m: list[str | int]): - while True: - if isinstance(m[0], str): - x = m[0] - y = x + "" - m[0] = y diff --git a/packages/vipeye-internal/src/tests/samples/loop47.py b/packages/vipeye-internal/src/tests/samples/loop47.py deleted file mode 100644 index 43266971..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop47.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests a case where there are dependencies between -# variables within a loop. - -a = None -b = False - -for _ in []: - if b > 0: - pass - if a: - reveal_type(a, expected_text="int") - c = int(a or 1) - a = c - c.is_integer() diff --git a/packages/vipeye-internal/src/tests/samples/loop48.py b/packages/vipeye-internal/src/tests/samples/loop48.py deleted file mode 100644 index 9bf6027a..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop48.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests a case where an instance variable is assigned within -# a loop using its own value. - -# viper: strict - - -class ClassA: - x: int | None - - def method1(self) -> None: - self.x = 0 - - for _ in range(1, 10): - self.x = reveal_type(self.x, expected_text="int") + 1 - - reveal_type(self.x, expected_text="int") - - def method2(self) -> None: - self.x = 0 - - for _ in range(1, 10): - self.x += 1 - - reveal_type(self.x, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/loop49.py b/packages/vipeye-internal/src/tests/samples/loop49.py deleted file mode 100644 index ffe050ec..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop49.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests a doubly-nested loop that was incorrectly evaluated. - -a = b = c = 0 - -while True: - if a < 0: - c += b - 1 - a = b - - while a != (d := a + 1): - b = max(b, d) - c += abs(a - d) - a = d diff --git a/packages/vipeye-internal/src/tests/samples/loop5.py b/packages/vipeye-internal/src/tests/samples/loop5.py deleted file mode 100644 index e90274c9..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop5.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests a case where a potential type alias -# ("a") is involved in a recursive type dependency -# ("a" depends on "test" which depends on "a"). - -# viper: strict - - -test = {"key": "value"} - -while True: - a = test - reveal_type(a, expected_text="dict[str, str]") - test = a.copy() - reveal_type(test, expected_text="dict[str, str]") diff --git a/packages/vipeye-internal/src/tests/samples/loop50.py b/packages/vipeye-internal/src/tests/samples/loop50.py deleted file mode 100644 index 87b92c36..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop50.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a type alias is accessed within -# a loop as both an annotation and a value expression. - -from typing import Literal - - -TA1 = Literal["a", "b"] - - -def func1(values: list): - for value in values: - x: TA1 = value["x"] - - if x not in TA1.__args__: - raise ValueError() diff --git a/packages/vipeye-internal/src/tests/samples/loop51.py b/packages/vipeye-internal/src/tests/samples/loop51.py deleted file mode 100644 index 1f3b4131..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop51.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests a case where type evaluation for a type guard -# within a loop may trigger a false positive "type depends on itself" -# error message. - -# For details, see https://github.com/microsoft/pyright/issues/9139. - -from enum import StrEnum - - -class MyEnum(StrEnum): - A = "A" - - -for _ in range(2): - x: dict[MyEnum, int] = {} - - if MyEnum.A in x: - ... - - for _ in x.values(): - ... diff --git a/packages/vipeye-internal/src/tests/samples/loop52.py b/packages/vipeye-internal/src/tests/samples/loop52.py deleted file mode 100644 index c1a4c872..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop52.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a function accesses its own decorated -# form within a loop. - -from contextlib import contextmanager - - -@contextmanager -def func1(): - yield - - for _ in (): - with func1(): - return diff --git a/packages/vipeye-internal/src/tests/samples/loop6.py b/packages/vipeye-internal/src/tests/samples/loop6.py deleted file mode 100644 index 68c6bb85..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop6.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests a difficult set of circular dependencies -# between untyped variables. - - -class ClassA: - def method1(self, param1): - return ClassA() - - def method2(self): - return {}, {} - - def method3(self, param3): - while True: - for key in param3.keys(): - foo1 = self.method1({key: None}) - var1, var2 = foo1.method2() - - if len(var1) < 2: - param3 = var2 - break - - foo2 = foo1.method1({}) - var1, var2 = foo2.method2() - else: - break diff --git a/packages/vipeye-internal/src/tests/samples/loop7.py b/packages/vipeye-internal/src/tests/samples/loop7.py deleted file mode 100644 index 26b6750d..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop7.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests a difficult set of circular dependencies -# between untyped variables. - - -from typing import Optional - - -class ClassA: - name: Optional[str] - - def method1(self): - if self.name is not None: - for _ in []: - self.name = self.name.replace("", "") diff --git a/packages/vipeye-internal/src/tests/samples/loop8.py b/packages/vipeye-internal/src/tests/samples/loop8.py deleted file mode 100644 index 818034a0..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop8.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests a difficult set of circular dependencies -# between untyped variables. - -# viper: strict - -from typing import Iterable - - -def func1(parts: Iterable[str]): - x: list[str] = [] - ns = "" - for part in parts: - if ns: - ns += "a" - else: - ns += part - x.append(ns) diff --git a/packages/vipeye-internal/src/tests/samples/loop9.py b/packages/vipeye-internal/src/tests/samples/loop9.py deleted file mode 100644 index 6548c8a1..00000000 --- a/packages/vipeye-internal/src/tests/samples/loop9.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests a difficult set of circular dependencies -# between untyped variables. - -# viper: strict - -from typing import Dict - - -class A: - pass - - -class B(A): - pass - - -def func1(v: A, s: Dict[B, A]) -> object: - if not isinstance(v, B): - return v - u = s.get(v) - while isinstance(u, B): - v = u - u = s.get(v) - x = v if u is None else u - return x diff --git a/packages/vipeye-internal/src/tests/samples/match1.py b/packages/vipeye-internal/src/tests/samples/match1.py deleted file mode 100644 index cb8dd7c4..00000000 --- a/packages/vipeye-internal/src/tests/samples/match1.py +++ /dev/null @@ -1,227 +0,0 @@ -# This sample tests basic parsing of match statements as -# described in PEP 634. - -from typing import Any - -value_obj: Any = 4 - -class Foo: - x: int - - -match (1, ): - case a1, b1 if True: - pass - - case (a2, b2): - pass - - case [a3, b3]: - pass - - case () | []: - pass - - # This should generate an error because of a missing pattern. - case : - pass - - # This should generate an error because it is an irrefutable pattern - # and is not at the end. - case (a4): - pass - - case (a5,): - pass - - case [a6,]: - pass - - case a7 as b7, c7 as d7 if True: - pass - - case (a8, b8, ) as c8 if 1 == 3: - pass - - case a9, *b8: - pass - - # This should generate an error because multiple star - # patterns in a sequence are not allowed. - case *a10, *b10: - pass - - # This should generate an error because star - # patterns cannot be used with "as". - case *a11 as b11, b12: - pass - - case value_obj.a, value_obj.b: - pass - - # This should generate an error because star - # patterns can't be used with |. - case (3 as b13) | (4 as b13) | *b13: - pass - - case *a14, b14: - pass - - case (a20, (b20,), [c20, *d20]) as e20: - pass - - case 3 | -3: - pass - - case 3.2 - 2.1j | -3.2 + 2.1j | 3j: - pass - - # This should generate an error because the grammar - # indicates that imaginary number must come second. - case 2j + 4: - pass - - # This should generate an error because the grammar - # indicates that imaginary number must come second. - case - 2j + 4: - pass - - case "hi" """hi""" | r"hi" r"""hi""": - pass - - # This should generate an error because f-strings are - # not allowed. - case "hi" f"""hi""": - pass - - # This should generate an error. - case {}: - pass - - case {"a": 3, -3 + 4j: a30, value_obj.a: b30, **c30}: - pass - - # This should generate an error because only one ** expression - # can be used. - case {"a": 3, **a31, "b": -3j, **b31}: - pass - - # This should generate an error because ** cannot be used with - # wildcard "_". - case {"a": 3, **_, "b": -3}: - pass - - case (3 as x) as y: - pass - - case int(): - pass - - case Foo(1, a40, value_obj.b as b40, c40=3|-2 + 5j|"hi" as d40, y=[e40, f40] as g40,): - pass - - # This should generate an error because positional arguments - # cannot appear after keyword arguments. - case Foo(1, a41, x=3, value_obj.b as b41, c41=3, y=[d41, e41] as f41): - pass - - # This should generate three errors because irrefutable patterns - # must appear only as the last entry in an or pattern. - case (_ as x) | x: - pass - - # This should generate an error because it's an irrefutable pattern - # but is not the last case statement. - case _: - pass - - # This should generate an error because it's an irrefutable pattern - # but is not the last case statement. - case (x): - pass - - case _ if value_obj: - pass - - # This should generate an error because or patterns must target the - # same names. - case 3 | x: - pass - - case _: - pass - - - -def func1(): - match = Foo() - - # This should be treated as an expression statement, not a match statement. - match.x - - -def func2(): - match = [3] - - # This should be treated as an expression statement, not a match statement. - match[0] - - match [0]: - case _: - pass - -def func3(): - def match(a: int): ... - - # This should be treated as a call statement. - match(0) - - match (0): - case _: - pass - -def func4(): - match 1, 2, "3": - case _: - pass - -def func5(match: Any): - # This should be treated as a list, not a match statement. - match[2:8, 2:8] = 0 - - -class Point: - def __init__(self, x: int, y: int) -> None: - self.x = x - self.y = y - -def func6(subj: Any): - match subj: - # This should generate an error because a is used twice in the same pattern. - case [a, *a]: - pass - - case ([c, d] as f) | ([d, c] as f): - pass - - # This should generate an error because h is used twice in the same pattern. - case (g, 1 as h) as h: - pass - - # This should generate an error because j is used twice in the same pattern. - case Point(x=j, y=j): - pass - -def func7(): - match +1: - case _: - pass - - match -1: - case _: - pass - - match ~1: - case _: - pass - diff --git a/packages/vipeye-internal/src/tests/samples/match2.py b/packages/vipeye-internal/src/tests/samples/match2.py deleted file mode 100644 index fefcba87..00000000 --- a/packages/vipeye-internal/src/tests/samples/match2.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests type narrowing of subject expressions for -# match statements. - - -def func1(subj: int | dict[str, str] | tuple[int] | str, cond: bool): - match subj: - case 3 | "hi": - reveal_type(subj, expected_text="Literal[3, 'hi']") - return - - case int(y) if cond: - reveal_type(subj, expected_text="int") - return - - case int(y): - reveal_type(subj, expected_text="int") - return - - case int(): - reveal_type(subj, expected_text="Never") - return - - case str(z): - reveal_type(subj, expected_text="str") - return - - reveal_type(subj, expected_text="dict[str, str] | tuple[int]") - return subj - - -# This should generate an error because there is the potential -# for fall-through if the subject expression is a str. -def func2(subj: int | str) -> str: - match subj: - case int(): - return "int" - - reveal_type(subj, expected_text="str") - - -# This should generate an error because there is the potential -# for fall-through if the guard expressions are false. -def func3(subj: int | str) -> str: - match subj: - case str() if len(subj) > 0: - return "str" - - case int() if subj < 0: - return "int" - - reveal_type(subj, expected_text="int | str") - - -def func4(subj: int | str) -> str: - match subj: - case int(): - return "int" - - case str(): - return "str" - - case _: - # This should be ignored because the pattern has already - # been exhaustively matched. - pass diff --git a/packages/vipeye-internal/src/tests/samples/match3.py b/packages/vipeye-internal/src/tests/samples/match3.py deleted file mode 100644 index 8a168634..00000000 --- a/packages/vipeye-internal/src/tests/samples/match3.py +++ /dev/null @@ -1,99 +0,0 @@ -# This sample tests narrowing of subject subexpressions in match statements. - -from typing import Literal, TypedDict - - -class TD1(TypedDict): - name: Literal["a"] - extra_value: int - - -class TD2(TypedDict): - name: Literal["b"] - other_extra_value: int - - -class TD3(TypedDict): - name: Literal["c"] - extra_value: int - - -def func1(item: TD1 | TD2): - match item["name"]: - case "d": - reveal_type(item, expected_text="Never") - case "a": - reveal_type(item, expected_text="TD1") - case "b": - reveal_type(item, expected_text="TD2") - - -def func2(item: TD1 | TD2 | TD3): - match item["name"]: - case "a" | "c": - reveal_type(item, expected_text="TD1 | TD3") - case _: - reveal_type(item, expected_text="TD2") - - -T1 = tuple[Literal[0], int] -T2 = tuple[Literal[1], str] - - -def func3(item: T1 | T2): - match item[0]: - case 0: - reveal_type(item, expected_text="tuple[Literal[0], int]") - case 1: - reveal_type(item, expected_text="tuple[Literal[1], str]") - - -def func4(a: object, b: int) -> None: - match a, b: - case (complex(), 3): - reveal_type(a, expected_text="complex") - reveal_type(b, expected_text="Literal[3]") - - -Token = ( - str - | tuple[Literal["define"], str, str] - | tuple[Literal["include"], str] - | tuple[Literal["use"], str, int, int] -) - - -def func5(token: Token): - match token: - case str(x): - reveal_type(token, expected_text="str") - case "define", _, _: - reveal_type(token, expected_text="tuple[Literal['define'], str, str]") - case "include", _: - reveal_type(token, expected_text="tuple[Literal['include'], str]") - case "use", _, _, _: - reveal_type(token, expected_text="tuple[Literal['use'], str, int, int]") - case _: - reveal_type(token, expected_text="Never") - - -def func6(a: int | str, b: int | str) -> None: - match a, b: - case (_, _): - reveal_type(a, expected_text="int | str") - reveal_type(b, expected_text="int | str") - case (x, y): - reveal_type(x, expected_text="Never") - reveal_type(y, expected_text="Never") - reveal_type(a, expected_text="Never") - reveal_type(b, expected_text="Never") - - -def func7(a: str | None, b: str | None) -> None: - match (a, b): - case (_, None): - return - case (None, _): - return - reveal_type(a, expected_text="str") - reveal_type(b, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/matchClass1.py b/packages/vipeye-internal/src/tests/samples/matchClass1.py deleted file mode 100644 index 7e2bf0f9..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass1.py +++ /dev/null @@ -1,553 +0,0 @@ -# This sample tests type checking for match statements (as -# described in PEP 634) that contain class patterns. - -from typing import ( - Any, - Generic, - Literal, - NamedTuple, - Protocol, - TypeVar, - TypedDict, - runtime_checkable, -) -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - LiteralString, -) -from dataclasses import dataclass, field - -foo = 3 - -T = TypeVar("T") - - -class ClassA: - __match_args__ = ("attr_a", "attr_b") - attr_a: int - attr_b: str - - -class ClassB(Generic[T]): - __match_args__ = ("attr_a", "attr_b") - attr_a: T - attr_b: str - - -class ClassC: ... - - -class ClassD(ClassC): ... - - -def test_unknown(value_to_match): - match value_to_match: - case ClassA(attr_a=a2) as a1: - reveal_type(a1, expected_text="ClassA") - reveal_type(a2, expected_text="int") - reveal_type(value_to_match, expected_text="ClassA") - - # This should generate an error because foo isn't instantiable. - case foo() as a3: - pass - - -def test_any(value_to_match: Any): - match value_to_match: - case list() as a1: - reveal_type(a1, expected_text="list[Unknown]") - reveal_type(value_to_match, expected_text="list[Unknown]") - - -def test_custom_type(value_to_match: ClassA | ClassB[int] | ClassB[str] | ClassC): - match value_to_match: - case int() as a1: - reveal_type(a1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case ClassA(attr_a=a4, attr_b=a5) as a3: - reveal_type(a3, expected_text="ClassA") - reveal_type(a4, expected_text="int") - reveal_type(a5, expected_text="str") - reveal_type(value_to_match, expected_text="ClassA") - reveal_type(value_to_match, expected_text="ClassA") - - case ClassB(a6, a7): - reveal_type(a6, expected_text="int | str") - reveal_type(a7, expected_text="str") - reveal_type(value_to_match, expected_text="ClassB[int] | ClassB[str]") - - case ClassD() as a2: - reveal_type(a2, expected_text="ClassD") - reveal_type(value_to_match, expected_text="ClassD") - - case ClassC() as a8: - reveal_type(a8, expected_text="ClassC") - reveal_type(value_to_match, expected_text="ClassC") - - -def test_subclass(value_to_match: ClassD): - match value_to_match: - case ClassC() as a1: - reveal_type(a1, expected_text="ClassD") - - case _ as a2: - reveal_type(a2, expected_text="Never") - - -def test_literal(value_to_match: Literal[3]): - match value_to_match: - case float() as a2: - reveal_type(a2, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case str() as a3: - reveal_type(a3, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case int() as a1: - reveal_type(a1, expected_text="Literal[3]") - reveal_type(value_to_match, expected_text="Literal[3]") - - -def test_literal2(value_to_match: Literal[0, "1", b"2"]) -> None: - match value_to_match: - case float() as a2: - reveal_type(a2, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case str() as a3: - reveal_type(a3, expected_text="Literal['1']") - reveal_type(value_to_match, expected_text="Literal['1']") - - case int() as a1: - reveal_type(a1, expected_text="Literal[0]") - reveal_type(value_to_match, expected_text="Literal[0]") - - case x: - reveal_type(x, expected_text='Literal[b"2"]') - reveal_type(value_to_match, expected_text='Literal[b"2"]') - - -def test_literal_string(value_to_match: LiteralString) -> None: - match value_to_match: - case "a" as a1: - reveal_type(value_to_match, expected_text="Literal['a']") - reveal_type(a1, expected_text="Literal['a']") - - case str() as a2: - reveal_type(value_to_match, expected_text="LiteralString") - reveal_type(a2, expected_text="LiteralString") - - case a3: - reveal_type(value_to_match, expected_text="Never") - reveal_type(a3, expected_text="Never") - - -TFloat = TypeVar("TFloat", bound=float) - - -def test_bound_typevar(value_to_match: TFloat) -> TFloat: - match value_to_match: - case int() as a1: - reveal_type(a1, expected_text="int*") - reveal_type(value_to_match, expected_text="int*") - - case float() as a2: - reveal_type(a2, expected_text="float*") - reveal_type(value_to_match, expected_text="float*") - - case str() as a3: - reveal_type(a3, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - return value_to_match - - -TInt = TypeVar("TInt", bound=int) - - -def test_union( - value_to_match: TInt | Literal[3] | float | str, -) -> TInt | Literal[3] | float | str: - match value_to_match: - case int() as a1: - reveal_type(a1, expected_text="int* | int") - reveal_type(value_to_match, expected_text="int* | int") - - case float() as a2: - reveal_type(a2, expected_text="float") - reveal_type(value_to_match, expected_text="float") - - case str() as a3: - reveal_type(a3, expected_text="str") - reveal_type(value_to_match, expected_text="str") - - return value_to_match - - -T = TypeVar("T") - - -class Point(Generic[T]): - __match_args__ = ("x", "y") - x: T - y: T - - -def func1(points: list[Point[float] | Point[complex]]): - match points: - case [] as a1: - reveal_type(a1, expected_text="list[Point[float] | Point[complex]]") - reveal_type(points, expected_text="list[Point[float] | Point[complex]]") - - case [Point(0, 0) as b1]: - reveal_type(b1, expected_text="Point[float] | Point[complex]") - reveal_type(points, expected_text="list[Point[float] | Point[complex]]") - - case [Point(c1, c2)]: - reveal_type(c1, expected_text="float | complex") - reveal_type(c2, expected_text="float | complex") - reveal_type(points, expected_text="list[Point[float] | Point[complex]]") - - case [Point(0, d1), Point(0, d2)]: - reveal_type(d1, expected_text="float | complex") - reveal_type(d2, expected_text="float | complex") - reveal_type(points, expected_text="list[Point[float] | Point[complex]]") - - case _ as e1: - reveal_type(e1, expected_text="list[Point[float] | Point[complex]]") - reveal_type(points, expected_text="list[Point[float] | Point[complex]]") - - -def func2(subj: object): - match subj: - case list() as a1: - reveal_type(a1, expected_text="list[Unknown]") - reveal_type(subj, expected_text="list[Unknown]") - - -def func3(subj: int | str | dict[str, str]): - match subj: - case int(x): - reveal_type(x, expected_text="int") - reveal_type(subj, expected_text="int") - - case str(x): - reveal_type(x, expected_text="str") - reveal_type(subj, expected_text="str") - - case dict(x): - reveal_type(x, expected_text="dict[str, str]") - reveal_type(subj, expected_text="dict[str, str]") - - -def func4(subj: object): - match subj: - case int(x): - reveal_type(x, expected_text="int") - reveal_type(subj, expected_text="int") - - case str(x): - reveal_type(x, expected_text="str") - reveal_type(subj, expected_text="str") - - -# Test the auto-generation of __match_args__ for dataclass. -@dataclass -class Dataclass1: - val1: int - val2: str = field(init=False) - val3: complex - - -@dataclass -class Dataclass2: - val1: int - val2: str - val3: float - - -def func5(subj: object): - match subj: - case Dataclass1(a, b): - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="complex") - reveal_type(subj, expected_text="Dataclass1") - - case Dataclass2(a, b, c): - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="str") - reveal_type(c, expected_text="float") - reveal_type(subj, expected_text="Dataclass2") - - -@dataclass(match_args=False) -class DataclassNoMatchArgs: - a: int - b: int - - -def func5b(subj: object): - match subj: - # This should generate an error because match_args is False. - case DataclassNoMatchArgs(1, 2): - pass - - -# Test the auto-generation of __match_args__ for named tuples. -NT1 = NamedTuple("NT1", [("val1", int), ("val2", complex)]) -NT2 = NamedTuple("NT2", [("val1", int), ("val2", str), ("val3", float)]) - - -def func6(subj: object): - match subj: - case NT1(a, b): - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="complex") - reveal_type(subj, expected_text="NT1") - - case NT2(a, b, c): - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="str") - reveal_type(c, expected_text="float") - reveal_type(subj, expected_text="NT2") - - -def func7(subj: object): - match subj: - case complex(real=a, imag=b): - reveal_type(a, expected_text="float") - reveal_type(b, expected_text="float") - - -T2 = TypeVar("T2") - - -class Parent(Generic[T]): ... - - -class Child1(Parent[T]): ... - - -class Child2(Parent[T], Generic[T, T2]): ... - - -def func8(subj: Parent[int]): - match subj: - case Child1() as a1: - reveal_type(a1, expected_text="Child1[int]") - reveal_type(subj, expected_text="Child1[int]") - - case Child2() as b1: - reveal_type(b1, expected_text="Child2[int, Unknown]") - reveal_type(subj, expected_text="Child2[int, Unknown]") - - -T3 = TypeVar("T3") - - -def func9(v: T3) -> T3 | None: - match v: - case str(): - reveal_type(v, expected_text="str*") - return v - - case _: - return None - - -T4 = TypeVar("T4", int, str) - - -def func10(v: T4) -> T4 | None: - match v: - case str(): - reveal_type(v, expected_text="str*") - return v - - case int(): - reveal_type(v, expected_text="int*") - return v - - case list(): - reveal_type(v, expected_text="Never") - return v - - case _: - return None - - -def func11(subj: Any): - match subj: - case Child1() as a1: - reveal_type(a1, expected_text="Child1[Unknown]") - reveal_type(subj, expected_text="Child1[Unknown]") - - case Child2() as b1: - reveal_type(b1, expected_text="Child2[Unknown, Unknown]") - reveal_type(subj, expected_text="Child2[Unknown, Unknown]") - - -class TD1(TypedDict): - x: int - - -def func12(subj: int, flt_cls: type[float], union_val: float | int): - match subj: - # This should generate an error because int doesn't accept two arguments. - case int(1, 2): - pass - - match subj: - # This should generate an error because float doesn't accept keyword arguments. - case float(x=1): - pass - - match subj: - case flt_cls(): - pass - - # This should generate an error because it is a union. - case union_val(): - pass - - # This should generate an error because it is a TypedDict. - case TD1(): - pass - - -def func13(subj: tuple[Literal[0]]): - match subj: - case tuple((1,)) as a: - reveal_type(subj, expected_text="Never") - reveal_type(a, expected_text="Never") - - case tuple((0, 0)) as b: - reveal_type(subj, expected_text="Never") - reveal_type(b, expected_text="Never") - - case tuple((0,)) as c: - reveal_type(subj, expected_text="tuple[Literal[0]]") - reveal_type(c, expected_text="tuple[Literal[0]]") - - case d: - reveal_type(subj, expected_text="Never") - reveal_type(d, expected_text="Never") - - -class ClassE(Generic[T]): - __match_args__ = ("x",) - x: list[T] - - -class ClassF(ClassE[T]): - pass - - -def func14(subj: ClassE[T]) -> T | None: - match subj: - case ClassF(a): - reveal_type(subj, expected_text="ClassF[T@func14]") - reveal_type(a, expected_text="list[T@func14]") - return a[0] - - -class IntPair(tuple[int, int]): - pass - - -def func15(x: IntPair | None) -> None: - match x: - case IntPair((y, z)): - reveal_type(y, expected_text="int") - reveal_type(z, expected_text="int") - - -def func16(x: str | float | bool | None): - match x: - case str(v) | bool(v) | float(v): - reveal_type(v, expected_text="str | bool | float") - reveal_type(x, expected_text="str | bool | float") - case v: - reveal_type(v, expected_text="int | None") - reveal_type(x, expected_text="int | None") - reveal_type(x, expected_text="str | bool | float | int | None") - - -def func17(x: str | float | bool | None): - match x: - case str() | float() | bool(): - reveal_type(x, expected_text="str | float | bool") - case _: - reveal_type(x, expected_text="int | None") - reveal_type(x, expected_text="str | float | bool | int | None") - - -def func18(x: str | float | bool | None): - match x: - case str(v) | float(v) | bool(v): - reveal_type(v, expected_text="str | float | bool") - reveal_type(x, expected_text="str | float | bool") - case _: - reveal_type(x, expected_text="int | None") - reveal_type(x, expected_text="str | float | bool | int | None") - - -T5 = TypeVar("T5", complex, str) - - -def func19(x: T5) -> T5: - match x: - case complex(): - return x - case str(): - return x - - reveal_type(x, expected_text="float* | int*") - return x - - -T6 = TypeVar("T6", bound=complex | str) - - -def func20(x: T6) -> T6: - match x: - case complex(): - return x - case str(): - return x - - reveal_type(x, expected_text="float* | int*") - return x - - -@runtime_checkable -class Proto1(Protocol): - x: int - - -class Proto2(Protocol): - x: int - - -def func21(subj: object): - match subj: - case Proto1(): - pass - - # This should generate an error because Proto2 isn't runtime checkable. - case Proto2(): - pass - - -class Impl1: - x: int - - -def func22(subj: Proto1 | int): - match subj: - case Proto1(): - reveal_type(subj, expected_text="Proto1") - - case _: - reveal_type(subj, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/matchClass2.py b/packages/vipeye-internal/src/tests/samples/matchClass2.py deleted file mode 100644 index 1439a3c7..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass2.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests keyword-only class pattern matching for -# dataclasses. - -from dataclasses import dataclass, field - - -@dataclass -class Point: - optional: int | None = field(default=None, kw_only=True) - x: int - y: int - - -obj = Point(1, 2) -match obj: - case Point(x, y, optional=opt): - reveal_type(x, expected_text="int") - reveal_type(y, expected_text="int") - reveal_type(opt, expected_text="int | None") - distance = (x**2 + y**2) ** 0.5 diff --git a/packages/vipeye-internal/src/tests/samples/matchClass3.py b/packages/vipeye-internal/src/tests/samples/matchClass3.py deleted file mode 100644 index eda1d4d5..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass3.py +++ /dev/null @@ -1,80 +0,0 @@ -# This sample tests class-based pattern matching when the class is -# marked final and can be discriminated based on the argument patterns. - -from typing import final, Protocol, runtime_checkable -from dataclasses import dataclass - - -class A: - title: str - - -class B: - name: str - - -class C: - name: str - - -def func1(r: A | B | C): - match r: - case object(title=_): - reveal_type(r, expected_text="A | B | C") - - case object(name=_): - reveal_type(r, expected_text="A | B | C") - - case _: - reveal_type(r, expected_text="A | B | C") - - -@final -class AFinal: - title: str - - -@final -class BFinal: - name: str - - -@final -class CFinal: - name: str - - -@final -class DFinal: - nothing: str - - -def func2(r: AFinal | BFinal | CFinal | DFinal): - match r: - case object(title=_): - reveal_type(r, expected_text="AFinal") - - case object(name=_): - reveal_type(r, expected_text="BFinal | CFinal") - - case _: - reveal_type(r, expected_text="DFinal") - - -@runtime_checkable -class ProtoE(Protocol): - __match_args__ = ("x",) - x: int - - -@dataclass -class E: - x: int - - -match E(1): - case ProtoE(x): - pass - - case y: - reveal_type(y, expected_text="Never") diff --git a/packages/vipeye-internal/src/tests/samples/matchClass4.py b/packages/vipeye-internal/src/tests/samples/matchClass4.py deleted file mode 100644 index 423a29f3..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass4.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests the case where a subject is narrowed against a -# class pattern that includes a type() or subclass thereof and -# the subject contains a type[T]. - - -class MyMeta(type): - pass - - -class A: - pass - - -class B(A, metaclass=MyMeta): - pass - - -def func1(subj: type[A]): - match subj: - case type(): - reveal_type(subj, expected_text="type[A]") - case _: - reveal_type(subj, expected_text="Never") - - -def func2(subj: type[A]): - match subj: - case MyMeta(): - reveal_type(subj, expected_text="type[A]") - case _: - reveal_type(subj, expected_text="type[A]") - - -def func3(subj: type[B]): - match subj: - case MyMeta(): - reveal_type(subj, expected_text="type[B]") - case _: - reveal_type(subj, expected_text="Never") - - -def func4(subj: type[B] | type[int]): - match subj: - case MyMeta(): - reveal_type(subj, expected_text="type[B] | type[int]") - case _: - reveal_type(subj, expected_text="type[int]") diff --git a/packages/vipeye-internal/src/tests/samples/matchClass5.py b/packages/vipeye-internal/src/tests/samples/matchClass5.py deleted file mode 100644 index c1ad5751..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass5.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests the detection of too many positional patterns. - -from dataclasses import dataclass - - -@dataclass -class A: - a: int - - -class B: - a: int - b: int - - __match_args__ = ("a", "b") - - -class C(B): ... - - -class D(int): ... - - -def func1(subj: A | B): - match subj: - # This should generate an error because A accepts only - # one positional pattern. - case A(1, 2): - pass - - case A(1): - pass - - case A(): - pass - - case B(1, 2): - pass - - # This should generate an error because B accepts only - # two positional patterns. - case B(1, 2, 3): - pass - - # This should generate an error because B accepts only - # two positional patterns. - case C(1, 2, 3): - pass - - case D(1): - pass - - # This should generate an error because D accepts only - # one positional pattern. - case D(1, 2): - pass - - case int(1): - pass - - # This should generate an error because int accepts only - # one positional pattern. - case int(1, 2): - pass diff --git a/packages/vipeye-internal/src/tests/samples/matchClass6.py b/packages/vipeye-internal/src/tests/samples/matchClass6.py deleted file mode 100644 index bbd311d7..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass6.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests the case where `Callable()` is used as a class pattern. - -from collections.abc import Callable -from typing import Any, Protocol, TypeVar - -T = TypeVar("T") - - -def func1(obj: T | Callable[..., T]) -> T | None: - match obj: - case Callable(): - reveal_type(obj, expected_text="((...) -> Unknown) | ((...) -> T@func1)") - return obj() - - -def func2(obj: T | Callable[..., T]) -> T | None: - if isinstance(obj, Callable): - reveal_type(obj, expected_text="((...) -> Unknown) | ((...) -> T@func2)") - return obj() - - -def func3(obj: type[int] | Callable[..., str]) -> int | str | None: - match obj: - case Callable(): - reveal_type(obj, expected_text="type[int] | ((...) -> str)") - return obj() - - -def func4(obj): - match obj: - case Callable(): - reveal_type(obj, expected_text="(...) -> Unknown") - return obj() - - -def func5(obj: Any): - match obj: - case Callable(): - reveal_type(obj, expected_text="(...) -> Any") - return obj() - - -def func6(obj: Callable[[], None]): - match obj: - case Callable(): - reveal_type(obj, expected_text="() -> None") - return obj() - - case x: - reveal_type(obj, expected_text="Never") - - -class CallableProto(Protocol): - def __call__(self) -> None: - pass - - -def func7(obj: CallableProto): - match obj: - case Callable(): - reveal_type(obj, expected_text="CallableProto") - return obj() - - case x: - reveal_type(obj, expected_text="Never") diff --git a/packages/vipeye-internal/src/tests/samples/matchClass7.py b/packages/vipeye-internal/src/tests/samples/matchClass7.py deleted file mode 100644 index c2f40756..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass7.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the case where a class pattern overwrites the subject -# expression. - -from dataclasses import dataclass - - -@dataclass -class DC1: - val: str - - -def func1(val: DC1): - result = val - - match result: - case DC1(result): - reveal_type(result, expected_text="str") - - -@dataclass -class DC2: - val: DC1 - - -def func2(val: DC2): - result = val - - match result.val: - case DC1(result): - reveal_type(result, expected_text="str") - - # This should generate an error because result.val - # is no longer valid at this point. - print(result.val) diff --git a/packages/vipeye-internal/src/tests/samples/matchClass8.py b/packages/vipeye-internal/src/tests/samples/matchClass8.py deleted file mode 100644 index 60dda0f9..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchClass8.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the case where a NewType is used as a class pattern. - -from typing import NewType - - -NT1 = NewType("NT1", int) - - -def accepts_widget_id(value: NT1 | int) -> None: - match value: - case NT1(): - # This should generate an error because NewType returns a function at runtime. - pass - - -NT2 = NewType("NT2", str) - - -def accepts_union(value: NT1 | NT2) -> None: - match value: - case NT1(): - # This should generate an error because NewType returns a function at runtime. - pass - - case NT2(): - # This should generate an error because NewType returns a function at runtime. - pass diff --git a/packages/vipeye-internal/src/tests/samples/matchExhaustion1.py b/packages/vipeye-internal/src/tests/samples/matchExhaustion1.py deleted file mode 100644 index a08e9e32..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchExhaustion1.py +++ /dev/null @@ -1,116 +0,0 @@ -# This sample tests the reportMatchNotExhaustive diagnostic check. - -from types import NoneType -from typing import Literal -from enum import Enum - - -def func1(subj: Literal["a", "b"], cond: bool): - # This should generate an error if reportMatchNotExhaustive is enabled. - match subj: - case "a": - pass - - case "b" if cond: - pass - - -def func2(subj: object): - # This should generate an error if reportMatchNotExhaustive is enabled. - match subj: - case int(): - pass - - -def func3(subj: object): - match subj: - case object(): - pass - - -def func4(subj: tuple[str] | tuple[int]): - match subj[0]: - case str(): - pass - - case int(): - pass - - -def func5(subj: Literal[1, 2, 3]): - # This should generate an error if reportMatchNotExhaustive is enabled. - match subj: - case 1 | 2: - pass - - -class Color(Enum): - red = 0 - green = 1 - blue = 2 - - -def func6(subj: Color): - # This should generate an error if reportMatchNotExhaustive is enabled. - match subj: - case Color.red: - pass - - case Color.green: - pass - - -class ClassA: - def method1(self) -> str: - match self: - case ClassA(): - return "" - - -def func7() -> int: - match [10]: - case [*values]: - return values[0] - - -class SingleColor(Enum): - red = 0 - - -def func8(subj: SingleColor) -> int: - match subj: - case SingleColor.red: - return 1 - - -def func9(subj: int | None): - match subj: - case NoneType(): - return 1 - case int(): - return 2 - - -def func10(subj: Color | None = None) -> list[str]: - results = [""] - for x in [""]: - match subj: - case None: - results.append(x) - case Color.red: - pass - case Color.green: - pass - case Color.blue: - pass - return results - - -def func11(subj: int | float | None): - match subj: - case float(): - reveal_type(subj, expected_text="float") - case int(): - reveal_type(subj, expected_text="int") - case NoneType(): - reveal_type(subj, expected_text="None") diff --git a/packages/vipeye-internal/src/tests/samples/matchLiteral1.py b/packages/vipeye-internal/src/tests/samples/matchLiteral1.py deleted file mode 100644 index b10e551b..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchLiteral1.py +++ /dev/null @@ -1,121 +0,0 @@ -# This sample tests type checking for match statements (as -# described in PEP 634) that contain literal patterns. - - -from typing import Literal, TypeVar - - -def test_unknown(value_to_match): - match value_to_match: - case 3 as a1, -3 as a2: - reveal_type(a1, expected_text="Unknown") - reveal_type(a2, expected_text="Unknown") - reveal_type(value_to_match, expected_text="Sequence[Unknown]") - - case 3j as b1, -3 + 5j as b2: - reveal_type(b1, expected_text="complex") - reveal_type(b2, expected_text="complex") - reveal_type(value_to_match, expected_text="Sequence[complex]") - - case "hi" as c1, None as c2: - reveal_type(c1, expected_text="Unknown") - reveal_type(c2, expected_text="None") - reveal_type(value_to_match, expected_text="Sequence[Unknown]") - - case True as d1, False as d2: - reveal_type(d1, expected_text="Unknown") - reveal_type(d2, expected_text="Unknown") - reveal_type(value_to_match, expected_text="Sequence[Unknown]") - - -def test_tuple(value_to_match: tuple[int | float | str | complex, ...]): - match value_to_match: - case (3, -3) as a1: - reveal_type( - a1, - expected_text="tuple[float | complex | Literal[3], float | complex | Literal[-3]]", - ) - reveal_type( - value_to_match, - expected_text="tuple[float | complex | Literal[3], float | complex | Literal[-3]]", - ) - - case (3j, -3 + 5j) as b1: - reveal_type( - b1, expected_text="tuple[int | float | complex, int | float | complex]" - ) - reveal_type( - value_to_match, - expected_text="tuple[int | float | complex, int | float | complex]", - ) - - -def test_union(value_to_match: int | float | str | complex | bool | None): - match value_to_match: - case (3 | -3j) as a1: - reveal_type(a1, expected_text="float | complex | bool | int") - reveal_type(value_to_match, expected_text="float | complex | bool | int") - - case (True | False | 3.4 | -3 + 3j | None) as b1: - reveal_type(b1, expected_text="int | float | complex | bool | None") - reveal_type( - value_to_match, expected_text="int | float | complex | bool | None" - ) - - case ("hi" | 3.4) as c1: - reveal_type(c1, expected_text="int | float | Literal['hi']") - reveal_type(value_to_match, expected_text="int | float | Literal['hi']") - - case ((True | "True") as d1) | ((False | "False") as d1): - reveal_type( - d1, expected_text="int | float | complex | Literal['True', 'False']" - ) - reveal_type( - value_to_match, - expected_text="int | float | complex | Literal['True', 'False']", - ) - - -def test_none(value_to_match: int | None): - match value_to_match: - case None as a1: - reveal_type(a1, expected_text="None") - - case a2: - reveal_type(a2, expected_text="int") - - -class A(str): ... - - -def test_subclass1(a: A): - match a: - case "TEST" as m: - reveal_type(m, expected_text="A") - case x: - reveal_type(x, expected_text="A") - - -def test_subclass2(subj: int): - match subj: - case 1.0e4: - reveal_type(subj, expected_text="int") - - -def test_subclass3(subj: Literal[1]): - match subj: - case 1.0: - reveal_type(subj, expected_text="Literal[1]") - - -T1 = TypeVar("T1", Literal["A"], Literal["B"]) - - -def test_constrained_typevar(subj: T1): - match subj: - case "A": - reveal_type(subj, expected_text="Literal['A']") - case "B": - reveal_type(subj, expected_text="Literal['B']") - case x: - reveal_type(x, expected_text="Never") diff --git a/packages/vipeye-internal/src/tests/samples/matchLiteral2.py b/packages/vipeye-internal/src/tests/samples/matchLiteral2.py deleted file mode 100644 index e7e65de1..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchLiteral2.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests type narrowing for a discriminated union that uses -# literal patterns to discriminate between objects with literal tags. - -from typing import Literal - - -class A: - tag: Literal["a"] - name: str - - -class B: - tag: Literal["b"] - num: int - - -class C: - tag: Literal["c"] - num: int - - -def g(d: A | B | C) -> None: - match d.tag: - case "d": - reveal_type(d.tag, expected_text="Never") - reveal_type(d, expected_text="Never") - case "a" | "c": - reveal_type(d.tag, expected_text="Literal['a', 'c']") - reveal_type(d, expected_text="A | C") - case "b": - reveal_type(d.tag, expected_text="Literal['b']") - reveal_type(d, expected_text="B") diff --git a/packages/vipeye-internal/src/tests/samples/matchMapping1.py b/packages/vipeye-internal/src/tests/samples/matchMapping1.py deleted file mode 100644 index e90ee119..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchMapping1.py +++ /dev/null @@ -1,154 +0,0 @@ -# This sample tests type checking for match statements (as -# described in PEP 634) that contain mapping patterns. - -from typing import Literal, TypedDict - -from typing_extensions import NotRequired # viper: ignore[reportMissingModuleSource] - - -def test_unknown(value_to_match): - match value_to_match: - case {"hello": a1, **a2}: - reveal_type(a1, expected_text="Unknown") - reveal_type(a2, expected_text="dict[Unknown, Unknown]") - reveal_type(value_to_match, expected_text="Unknown") - - -def test_object(value_to_match: object): - match value_to_match: - case {"hello": a1, **a2}: - reveal_type(a1, expected_text="Unknown") - reveal_type(a2, expected_text="dict[Unknown, Unknown]") - reveal_type(value_to_match, expected_text="object") - - -def test_dict(value_to_match: dict[str | int, str | int]): - match value_to_match: - case {1: a1}: - reveal_type(a1, expected_text="str | int") - reveal_type(value_to_match, expected_text="dict[str | int, str | int]") - - case {"hi": b1, "hi2": b2, **b3}: - reveal_type(b1, expected_text="str | int") - reveal_type(b2, expected_text="str | int") - reveal_type(b3, expected_text="dict[str | int, str | int]") - reveal_type(value_to_match, expected_text="dict[str | int, str | int]") - - case {None: c1}: - reveal_type(c1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - -class Movie(TypedDict): - title: str - release_year: int - gross_earnings: float - - -class MovieInfo: - field_of_interest: Literal["release_year", "gross_earnings"] - - -def test_typed_dict(value_to_match: Movie): - match value_to_match: - case {"title": a1, "release_year": a2, **a3}: - reveal_type(a1, expected_text="str") - reveal_type(a2, expected_text="int") - reveal_type(a3, expected_text="dict[str, object]") - reveal_type(value_to_match, expected_text="Movie") - - case {3: b1, "title": b2}: - reveal_type(b1, expected_text="Never") - reveal_type(b2, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case {"director": c1}: - reveal_type(c1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case {MovieInfo.field_of_interest: d1}: - reveal_type(d1, expected_text="int | float") - reveal_type(value_to_match, expected_text="Movie") - - -def test_union1(value_to_match: dict[str | int, str | int] | Movie | str): - match value_to_match: - case {3: a1}: - reveal_type(a1, expected_text="str | int") - reveal_type(value_to_match, expected_text="dict[str | int, str | int]") - - case {"gross_earnings": b1}: - reveal_type(b1, expected_text="str | int | float") - reveal_type( - value_to_match, expected_text="dict[str | int, str | int] | Movie" - ) - - -def test_union2(value_to_match: dict[int, int] | Movie | str): - match value_to_match: - case {**kw}: - reveal_type(kw, expected_text="dict[int | str, int | object]") - reveal_type(value_to_match, expected_text="dict[int, int] | Movie") - - case x: - reveal_type(x, expected_text="str") - - -class IntValue(TypedDict): - type: Literal["Int"] - int_value: int - - -class StrValue(TypedDict): - type: Literal["Str"] - str_value: str - - -class ComplexValue(TypedDict): - type: NotRequired[Literal["Complex"]] - complex_value: complex - - -def test_negative_narrowing1(value: IntValue | StrValue | ComplexValue | int) -> None: - match value: - case {"type": "Int"}: - reveal_type(value, expected_text="IntValue") - case {"type": "Str" | "Complex"}: - reveal_type(value, expected_text="StrValue | ComplexValue") - case _: - reveal_type(value, expected_text="ComplexValue | int") - - -def test_negative_narrowing2(value: StrValue | ComplexValue) -> None: - if "type" not in value: - raise - - match value: - case {"type": "Str"}: - reveal_type(value, expected_text="StrValue") - case {"type": "Complex"}: - reveal_type(value, expected_text="ComplexValue") - case _: - reveal_type(value, expected_text="Never") - - -class TD1(TypedDict): - v1: NotRequired[int] - v2: NotRequired[int] - v3: NotRequired[int] - - -def test_not_required_narrowing(subj: TD1) -> None: - match subj: - case {"v1": _}: - print(subj["v1"]) - - # This should generate an error. - print(subj["v2"]) - - case {"v2": 1, "v3": 2}: - # This should generate an error. - print(subj["v1"]) - - print(subj["v2"]) - print(subj["v3"]) diff --git a/packages/vipeye-internal/src/tests/samples/matchNamedTupleGeneric1.py b/packages/vipeye-internal/src/tests/samples/matchNamedTupleGeneric1.py deleted file mode 100644 index f52970e0..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchNamedTupleGeneric1.py +++ /dev/null @@ -1,142 +0,0 @@ -# This sample tests generic NamedTuple class pattern matching. - -from typing import Any, NamedTuple - - -class Thing[T: bool](NamedTuple): - foo: T - - -def test(value: object) -> str: - match value: - case Thing(): - reveal_type(value.foo, expected_text="bool") - return "thing" if value.foo else "" - case _: - return "" - - -def test_literal(value: Thing[bool] | object) -> str: - match value: - case Thing(foo=True): - reveal_type(value.foo, expected_text="bool") - return "thing" - case _: - return "" - - -class Animal: - pass - - -class Container[T: Animal](NamedTuple): - item: T - - -def test_nonfinal_bound(value: object) -> None: - # T's bound (Animal) is not final, so falling back to the bound is a real - # widening. An unsolved bounded parameter should surface as the bound rather - # than Unknown. - match value: - case Container(): - reveal_type(value.item, expected_text="Animal") - - -class Base[T: bool]: - pass - - -class Sub(Base[bool]): - pass - - -def test_subclass(value: Sub) -> None: - # The subject is a subclass of the bounded-generic pattern class. Matching - # `case Base()` must keep the narrowed subclass type rather than rebuilding - # it from the widened base class. - match value: - case Base(): - reveal_type(value, expected_text="Sub") - - -def f[S: bool](value: Thing[S]) -> None: - # The subject's type argument is an in-scope TypeVar. Matching must preserve - # the narrowed `S` rather than widening it to the bound `bool`. - match value: - case Thing(): - reveal_type(value.foo, expected_text="S@f") - - -def test_positional(value: object) -> None: - # Positional matching binds via __match_args__; confirm it still works for a - # generic NamedTuple whose parameter falls back to its bound. - match value: - case Thing(x): - reveal_type(x, expected_text="bool") - - -class GenericBase[U]: - pass - - -class BoundedDerived[T: bool](GenericBase[int]): - foo: T - - -def test_generic_supertype(value: GenericBase[int]) -> None: - # `BoundedDerived` has a generic supertype `GenericBase[int]`. The fallback must - # read the pattern class's own unsolved bounded parameter (so `T` resolves to its - # bound `bool`), not the supertype's unrelated `int` type argument. - match value: - case BoundedDerived(): - reveal_type(value.foo, expected_text="bool") - - -# The following cases guard against regression #11526: a subject that already -# carries a concretely-solved type argument must keep that argument after a class -# pattern match rather than being widened to the type parameter's bound. This is -# true even when the solved argument is implicitly parameterized (bare `list` is -# `list[Unknown]`, `dict` is `dict[Unknown, Unknown]`, etc.). - - -class Wrapper[A: str | list]: - data: A - - -def test_solved_bare_list(obj: Wrapper[list]) -> list: - match obj: - case Wrapper(data=data): - reveal_type(data, expected_text="list[Unknown]") - return data - - -def test_solved_bare_list_instance(obj: Wrapper[list]) -> list: - match obj: - case Wrapper(): - reveal_type(obj.data, expected_text="list[Unknown]") - return obj.data - - -def test_solved_list_any(obj: Wrapper[list[Any]]) -> list: - match obj: - case Wrapper(data=data): - reveal_type(data, expected_text="list[Any]") - return data - - -def test_solved_list_int(obj: Wrapper[list[int]]) -> list[int]: - match obj: - case Wrapper(data=data): - reveal_type(data, expected_text="list[int]") - return data - - -class MultiWrapper[A: str | dict]: - data: A - - -def test_solved_bare_dict(obj: MultiWrapper[dict]) -> dict: - match obj: - case MultiWrapper(data=data): - reveal_type(data, expected_text="dict[Unknown, Unknown]") - return data diff --git a/packages/vipeye-internal/src/tests/samples/matchSequence1.py b/packages/vipeye-internal/src/tests/samples/matchSequence1.py deleted file mode 100644 index d192feea..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchSequence1.py +++ /dev/null @@ -1,711 +0,0 @@ -# This sample tests type checking for match statements (as -# described in PEP 634) that contain sequence patterns. - -# viper: reportMissingModuleSource=false - -from enum import Enum -from typing import ( - Any, - Generic, - Iterator, - List, - Literal, - Protocol, - Reversible, - Sequence, - Tuple, - TypeVar, - Union, -) -from typing_extensions import TypeVarTuple, Unpack - -Ts = TypeVarTuple("Ts") - - -def test_unknown(value_to_match): - match value_to_match: - case []: - reveal_type(value_to_match, expected_text="Sequence[Unknown]") - case a1, a2: - reveal_type(a1, expected_text="Unknown") - reveal_type(a2, expected_text="Unknown") - - case *b1, b2: - reveal_type(b1, expected_text="list[Unknown]") - reveal_type(b2, expected_text="Unknown") - - case c1, *c2: - reveal_type(c1, expected_text="Unknown") - reveal_type(c2, expected_text="list[Unknown]") - - case d1, *d2, d3: - reveal_type(d1, expected_text="Unknown") - reveal_type(d2, expected_text="list[Unknown]") - reveal_type(d3, expected_text="Unknown") - - case 3, *e1: - reveal_type(e1, expected_text="list[Unknown]") - - case "hi", *f1: - reveal_type(f1, expected_text="list[Unknown]") - - case *g1, "hi": - reveal_type(g1, expected_text="list[Unknown]") - - -def test_any(value_to_match: Any): - match value_to_match: - case []: - reveal_type(value_to_match, expected_text="Sequence[Any]") - case [*a1]: - reveal_type(a1, expected_text="list[Any]") - case b1: - reveal_type(b1, expected_text="Any") - - -def test_reversible(value_to_match: Reversible[int]): - match value_to_match: - case [*a1]: - reveal_type(a1, expected_text="list[int]") - case b1: - reveal_type(b1, expected_text="Reversible[int]") - - -_T_co = TypeVar("_T_co", covariant=True) - - -class SeqProto(Protocol[_T_co]): - def __reversed__(self) -> Iterator[_T_co]: ... - - -def test_protocol(value_to_match: SeqProto[str]): - match value_to_match: - case [*a1]: - reveal_type(a1, expected_text="list[str]") - case b1: - reveal_type(b1, expected_text="SeqProto[str]") - - -def test_list(value_to_match: List[str]): - match value_to_match: - case a1, a2: - reveal_type(a1, expected_text="str") - reveal_type(a2, expected_text="str") - reveal_type(value_to_match, expected_text="List[str]") - - case *b1, b2: - reveal_type(b1, expected_text="list[str]") - reveal_type(b2, expected_text="str") - reveal_type(value_to_match, expected_text="List[str]") - - case c1, *c2: - reveal_type(c1, expected_text="str") - reveal_type(c2, expected_text="list[str]") - reveal_type(value_to_match, expected_text="List[str]") - - case d1, *d2, d3: - reveal_type(d1, expected_text="str") - reveal_type(d2, expected_text="list[str]") - reveal_type(d3, expected_text="str") - reveal_type(value_to_match, expected_text="List[str]") - - case 3, *e1: - reveal_type(e1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case "hi", *f1: - reveal_type(f1, expected_text="list[str]") - reveal_type(value_to_match, expected_text="List[str]") - - case *g1, "hi": - reveal_type(g1, expected_text="list[str]") - reveal_type(value_to_match, expected_text="List[str]") - - -def test_open_ended_tuple(value_to_match: Tuple[str, ...]): - match value_to_match: - case a1, a2: - reveal_type(a1, expected_text="str") - reveal_type(a2, expected_text="str") - reveal_type(value_to_match, expected_text="tuple[str, str]") - - case *b1, b2: - reveal_type(b1, expected_text="list[str]") - reveal_type(b2, expected_text="str") - reveal_type(value_to_match, expected_text="Tuple[str, ...]") - - case c1, *c2: - reveal_type(c1, expected_text="str") - reveal_type(c2, expected_text="list[str]") - reveal_type(value_to_match, expected_text="Tuple[str, ...]") - - case d1, *d2, d3: - reveal_type(d1, expected_text="str") - reveal_type(d2, expected_text="list[str]") - reveal_type(d3, expected_text="str") - reveal_type(value_to_match, expected_text="Tuple[str, ...]") - - case 3, *e1: - reveal_type(e1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case "hi", *f1: - reveal_type(f1, expected_text="list[str]") - reveal_type(value_to_match, expected_text="Tuple[str, ...]") - - case *g1, "hi": - reveal_type(g1, expected_text="list[str]") - reveal_type(value_to_match, expected_text="Tuple[str, ...]") - - -def test_definite_tuple(value_to_match: Tuple[int, str, float, complex]): - match value_to_match: - case a1, a2, a3, a4 if value_to_match[0] == 0: - reveal_type(a1, expected_text="int") - reveal_type(a2, expected_text="str") - reveal_type(a3, expected_text="float") - reveal_type(a4, expected_text="complex") - reveal_type(value_to_match, expected_text="tuple[int, str, float, complex]") - - case *b1, b2 if value_to_match[0] == 0: - reveal_type(b1, expected_text="list[int | str | float]") - reveal_type(b2, expected_text="complex") - reveal_type(value_to_match, expected_text="Tuple[int, str, float, complex]") - - case c1, *c2 if value_to_match[0] == 0: - reveal_type(c1, expected_text="int") - reveal_type(c2, expected_text="list[str | float | complex]") - reveal_type(value_to_match, expected_text="Tuple[int, str, float, complex]") - - case d1, *d2, d3 if value_to_match[0] == 0: - reveal_type(d1, expected_text="int") - reveal_type(d2, expected_text="list[str | float]") - reveal_type(d3, expected_text="complex") - reveal_type(value_to_match, expected_text="Tuple[int, str, float, complex]") - - case 3, *e1: - reveal_type(e1, expected_text="list[str | float | complex]") - reveal_type(value_to_match, expected_text="Tuple[int, str, float, complex]") - - case "hi", *f1: - reveal_type(f1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - case *g1, 3j: - reveal_type(g1, expected_text="list[int | str | float]") - reveal_type(value_to_match, expected_text="Tuple[int, str, float, complex]") - - case *h1, "hi": - reveal_type(h1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - -def test_union( - value_to_match: Union[ - Tuple[complex, complex], - Tuple[int, str, float, complex], - List[str], - Tuple[float, ...], - Any, - ], -): - match value_to_match: - case a1, a2, a3, a4 if value_to_match[0] == 0: - reveal_type(a1, expected_text="int | str | float | Any") - reveal_type(a2, expected_text="str | float | Any") - reveal_type(a3, expected_text="float | str | Any") - reveal_type(a4, expected_text="complex | str | float | Any") - reveal_type( - value_to_match, - expected_text="tuple[int, str, float, complex] | List[str] | tuple[float, float, float, float] | Sequence[Any]", - ) - - case *b1, b2 if value_to_match[0] == 0: - reveal_type( - b1, - expected_text="list[complex] | list[int | str | float] | list[str] | list[float] | list[Any]", - ) - reveal_type(b2, expected_text="complex | str | float | Any") - reveal_type( - value_to_match, - expected_text="Tuple[complex, complex] | Tuple[int, str, float, complex] | List[str] | Tuple[float, ...] | Sequence[Any]", - ) - - case c1, *c2 if value_to_match[0] == 0: - reveal_type(c1, expected_text="complex | int | str | float | Any") - reveal_type( - c2, - expected_text="list[complex] | list[str | float | complex] | list[str] | list[float] | list[Any]", - ) - reveal_type( - value_to_match, - expected_text="Tuple[complex, complex] | Tuple[int, str, float, complex] | List[str] | Tuple[float, ...] | Sequence[Any]", - ) - - case d1, *d2, d3 if value_to_match[0] == 0: - reveal_type(d1, expected_text="complex | int | str | float | Any") - reveal_type( - d2, - expected_text="list[Any] | list[str | float] | list[str] | list[float]", - ) - reveal_type(d3, expected_text="complex | str | float | Any") - reveal_type( - value_to_match, - expected_text="Tuple[complex, complex] | Tuple[int, str, float, complex] | List[str] | Tuple[float, ...] | Sequence[Any]", - ) - - case 3, e1: - reveal_type(e1, expected_text="complex | float | Any") - reveal_type( - value_to_match, - expected_text="tuple[complex, complex] | tuple[float, float] | Sequence[Any]", - ) - - case "hi", *f1: - reveal_type(f1, expected_text="list[str] | list[Any]") - reveal_type(value_to_match, expected_text="List[str] | Sequence[Any]") - - case *g1, 3j: - reveal_type( - g1, - expected_text="list[complex] | list[int | str | float] | list[float] | list[Any]", - ) - reveal_type( - value_to_match, - expected_text="tuple[complex, complex] | Tuple[int, str, float, complex] | Tuple[float, ...] | Sequence[Any]", - ) - - case *h1, "hi": - reveal_type(h1, expected_text="list[str] | list[Any]") - reveal_type(value_to_match, expected_text="List[str] | Sequence[Any]") - - -class SupportsLessThan(Protocol): - def __lt__(self, __other: Any) -> bool: ... - - def __le__(self, __other: Any) -> bool: ... - - -SupportsLessThanT = TypeVar("SupportsLessThanT", bound=SupportsLessThan) - - -def sort(seq: List[SupportsLessThanT]) -> List[SupportsLessThanT]: - match seq: - case [] | [_]: - reveal_type(seq, expected_text="List[SupportsLessThanT@sort]") - return seq - - case [x, y] if x <= y: - reveal_type(seq, expected_text="List[SupportsLessThanT@sort]") - return seq - - case [x, y]: - reveal_type(seq, expected_text="List[SupportsLessThanT@sort]") - return [y, x] - - case [x, y, z] if x <= y <= z: - reveal_type(seq, expected_text="List[SupportsLessThanT@sort]") - return seq - - case [x, y, z] if x > y > z: - reveal_type(seq, expected_text="List[SupportsLessThanT@sort]") - return [z, y, x] - - case [p, *rest]: - a = sort([x for x in rest if x <= p]) - b = sort([x for x in rest if p < x]) - reveal_type(seq, expected_text="List[SupportsLessThanT@sort]") - return a + [p] + b - return seq - - -def test_exceptions(seq: Union[str, bytes, bytearray]): - match seq: - case [x, y]: - reveal_type(x, expected_text="Never") - reveal_type(y, expected_text="Never") - return seq - - -def test_object1(seq: object): - match seq: - case (a1, a2) as a3: - reveal_type(a1, expected_text="Unknown") - reveal_type(a2, expected_text="Unknown") - reveal_type(a3, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case (*b1, b2) as b3: - reveal_type(b1, expected_text="list[Unknown]") - reveal_type(b2, expected_text="Unknown") - reveal_type(b3, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case (c1, *c2) as c3: - reveal_type(c1, expected_text="Unknown") - reveal_type(c2, expected_text="list[Unknown]") - reveal_type(c3, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case (d1, *d2, d3) as d4: - reveal_type(d1, expected_text="Unknown") - reveal_type(d2, expected_text="list[Unknown]") - reveal_type(d3, expected_text="Unknown") - reveal_type(d4, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case (3, *e1) as e2: - reveal_type(e1, expected_text="list[Unknown]") - reveal_type(e2, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case ("hi", *f1) as f2: - reveal_type(f1, expected_text="list[Unknown]") - reveal_type(f2, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case (*g1, "hi") as g2: - reveal_type(g1, expected_text="list[Unknown]") - reveal_type(g2, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case [1, "hi", True] as h1: - reveal_type(h1, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - case [1, i1] as i2: - reveal_type(i1, expected_text="Unknown") - reveal_type(i2, expected_text="Sequence[Unknown]") - reveal_type(seq, expected_text="Sequence[Unknown]") - - -def test_object2(value_to_match: object): - match value_to_match: - case [*a1]: - reveal_type(a1, expected_text="list[Unknown]") - case b1: - reveal_type(b1, expected_text="object") - - -def test_sequence(value_to_match: Sequence[Any]): - match value_to_match: - case [*a1]: - reveal_type(a1, expected_text="list[Any]") - case b1: - reveal_type(b1, expected_text="Never") - - -_T = TypeVar("_T") - - -class A(Generic[_T]): - a: _T - - -class B: ... - - -class C: ... - - -AAlias = A - -AInt = A[int] - -BOrC = B | C - - -def test_illegal_type_alias(m: object): - match m: - case AAlias(a=i): - pass - - # This should generate an error because it raises an - # exception at runtime. - case AInt(a=i): - pass - - # This should generate an error because it raises an - # exception at runtime. - case BOrC(a=i): - pass - - -def test_negative_narrowing1(subj: tuple[Literal[0]] | tuple[Literal[1]]): - match subj: - case (1, *a) | (*a): - reveal_type(subj, expected_text="tuple[Literal[1]] | tuple[Literal[0]]") - reveal_type(a, expected_text="list[Any] | list[int]") - - case b: - reveal_type(subj, expected_text="Never") - reveal_type(b, expected_text="Never") - - -def test_negative_narrowing2(subj: tuple[int, ...]): - match subj: - case (1, *a): - reveal_type(subj, expected_text="tuple[int, ...]") - reveal_type(a, expected_text="list[int]") - - case (b,): - reveal_type(subj, expected_text="tuple[int]") - reveal_type(b, expected_text="int") - - case (*c,): - reveal_type(subj, expected_text="tuple[int, ...]") - reveal_type(c, expected_text="list[int]") - - case d: - reveal_type(subj, expected_text="Never") - reveal_type(d, expected_text="Never") - - -def test_negative_narrowing3(subj: tuple[Any, Any]): - match subj: - case (a, b): - reveal_type(a, expected_text="Any") - reveal_type(b, expected_text="Any") - - case x: - reveal_type(x, expected_text="Never") - - -def test_negative_narrowing4(a: str | None, b: str | None): - match (a, b): - case (None, _) as x: - reveal_type(x, expected_text="tuple[None, str | None]") - case (_, None) as x: - reveal_type(x, expected_text="tuple[str, None]") - case (a, b) as x: - reveal_type(x, expected_text="tuple[str, str]") - - -def test_negative_narrowing5(a: str | None, b: str | None): - match (a, b): - case (None, _) | (_, None) as x: - reveal_type(x, expected_text="tuple[None, str | None] | tuple[str, None]") - case (a, b) as x: - reveal_type(x, expected_text="tuple[str, str]") - - -def test_negative_narrowing6(a: str | None, b: str | None): - match (a, b): - case (None, None) as x: - reveal_type(x, expected_text="tuple[None, None]") - reveal_type(a, expected_text="None") - reveal_type(b, expected_text="None") - case (None, _) as x if 2 > 1: - reveal_type(x, expected_text="tuple[None, str]") - reveal_type(a, expected_text="None") - reveal_type(b, expected_text="str") - case (a, b) as x: - reveal_type( - x, expected_text="tuple[str, str | None] | tuple[str | None, str]" - ) - reveal_type(a, expected_text="str | None") - reveal_type(b, expected_text="str | None") - - -def test_negative_narrowing7(a: tuple[str, str] | str): - match a: - case (_, _): - reveal_type(a, expected_text="tuple[str, str]") - case _: - reveal_type(a, expected_text="str") - - -def test_negative_narrowing8(a: str | int, b: str | int): - t = a, b - match t: - case int(), int(): - reveal_type(t, expected_text="tuple[int, int]") - case str(), int(): - reveal_type(t, expected_text="tuple[str, int]") - case int(), str(): - reveal_type(t, expected_text="tuple[int, str]") - case x, y: - reveal_type(t, expected_text="tuple[str, str]") - reveal_type(x, expected_text="str") - reveal_type(y, expected_text="str") - - -class MyEnum(Enum): - A = 1 - B = 2 - C = 3 - - -def test_tuple_with_subpattern( - subj: Literal[MyEnum.A] - | tuple[Literal[MyEnum.B], int] - | tuple[Literal[MyEnum.C], str], -): - match subj: - case MyEnum.A: - reveal_type(subj, expected_text="Literal[MyEnum.A]") - case (MyEnum.B, a): - reveal_type(subj, expected_text="tuple[Literal[MyEnum.B], int]") - reveal_type(a, expected_text="int") - case (MyEnum.C, b): - reveal_type(subj, expected_text="tuple[Literal[MyEnum.C], str]") - reveal_type(b, expected_text="str") - - -def test_unbounded_tuple1( - subj: tuple[int] | tuple[str, str] | tuple[int, Unpack[tuple[str, ...]], complex], -): - match subj: - case (x,): - reveal_type(subj, expected_text="tuple[int]") - reveal_type(x, expected_text="int") - - case (x, y): - reveal_type(subj, expected_text="tuple[str, str] | tuple[int, complex]") - reveal_type(x, expected_text="str | int") - reveal_type(y, expected_text="str | complex") - - case (x, y, z): - reveal_type(subj, expected_text="tuple[int, str, complex]") - reveal_type(x, expected_text="int") - reveal_type(y, expected_text="str") - reveal_type(z, expected_text="complex") - - -def test_unbounded_tuple_2(subj: tuple[int, str, Unpack[tuple[range, ...]]]) -> None: - match subj: - case [1, *ts1]: - reveal_type(ts1, expected_text="list[str | range]") - - case [1, "", *ts2]: - reveal_type(ts2, expected_text="list[range]") - - -def test_unbounded_tuple_3(subj: tuple[int, ...]): - match subj: - case []: - return - case x: - reveal_type(x, expected_text="tuple[int, ...]") - - -def test_unbounded_tuple_4(subj: tuple[str, ...]): - match subj: - case x, "": - reveal_type(subj, expected_text="tuple[str, Literal['']]") - case (x,): - reveal_type(subj, expected_text="tuple[str]") - case x: - reveal_type(subj, expected_text="tuple[str, ...]") - - -def test_unbounded_tuple_5(subj: tuple[int, Unpack[tuple[str, ...]]]): - match subj: - case x, *rest: - reveal_type(subj, expected_text="tuple[int, *tuple[str, ...]]") - reveal_type(x, expected_text="int") - reveal_type(rest, expected_text="list[str]") - case x: - reveal_type(x, expected_text="Never") - - -def test_unbounded_tuple_6(subj: tuple[str, ...]): - match subj: - case ("a", b, _, _): - reveal_type(b, expected_text="str") - - case ("a", b, _, _, _): - reveal_type(b, expected_text="str") - - case (_, b, _, _): - reveal_type(b, expected_text="str") - - case (_, b, _, _, _): - reveal_type(b, expected_text="str") - - case r: - reveal_type(r, expected_text="tuple[str, ...]") - - -def test_unbound_tuple_7(subj: tuple[str, Unpack[tuple[object, ...]], int]): - match subj: - case (*args,): - reveal_type(args, expected_text="list[str | object | int]") - case a: - reveal_type(a, expected_text="Never") - - match subj: - case (*args, last): - reveal_type(args, expected_text="list[str | object]") - reveal_type(last, expected_text="int") - case a: - reveal_type(a, expected_text="Never") - - match subj: - case (first, *args, last): - reveal_type(first, expected_text="str") - reveal_type(args, expected_text="list[object]") - reveal_type(last, expected_text="int") - case a: - reveal_type(a, expected_text="Never") - - match subj: - case (first, second, *args, last): - reveal_type(first, expected_text="str") - reveal_type(second, expected_text="object") - reveal_type(args, expected_text="list[object]") - reveal_type(last, expected_text="int") - case a: - reveal_type(a, expected_text="tuple[str, *tuple[object, ...], int]") - - -def test_variadic_tuple(subj: tuple[int, Unpack[Ts]]) -> tuple[Unpack[Ts]]: - match subj: - case _, *rest: - reveal_type(rest, expected_text="list[Unknown]") - return (*rest,) - - -class D: - x: float - y: float - - -def test_tuple_subexpressions(d: D): - match (d.x, d.y): - case (int(), int()): - reveal_type(d.x, expected_text="int") - reveal_type(d.y, expected_text="int") - - -def test_unpacked_variadic_regression( - subj: tuple[int] | tuple[str, str] | tuple[int, Unpack[tuple[str, ...]], int], -): - """Regression test: pattern matching should not mark the third case unreachable. - - Previously, the (x, y) pattern would remove the unpacked variadic tuple entry - and treat it as a definite match, causing the (x, y, z) pattern to be unreachable. - The fix ensures isPotentialNoMatch remains true after removal, preventing premature - elimination during negative narrowing. - """ - match subj: - case (x,): - # First case narrows to tuple[int] - reveal_type(subj, expected_text="tuple[int]") - reveal_type(x, expected_text="int") - - case (x, y): - # Second case narrows to tuple[str, str] | tuple[int, int] - # (the unpacked tuple with 0 elements in the middle) - reveal_type(subj, expected_text="tuple[str, str] | tuple[int, int]") - reveal_type(x, expected_text="str | int") - reveal_type(y, expected_text="str | int") - - case (x, y, z): - # Third case should be reachable and narrow to tuple[int, str, int] - # (the unpacked tuple with 1 element in the middle) - reveal_type(subj, expected_text="tuple[int, str, int]") - reveal_type(x, expected_text="int") - reveal_type(y, expected_text="str") - reveal_type(z, expected_text="int") - diff --git a/packages/vipeye-internal/src/tests/samples/matchSequence2.py b/packages/vipeye-internal/src/tests/samples/matchSequence2.py deleted file mode 100644 index 90ef429e..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchSequence2.py +++ /dev/null @@ -1,187 +0,0 @@ -# This sample tests pattern matching with tuple expansion when the number -# of expanded tuples grows very large. - - -class A1: - pass - - -class A2: - pass - - -class A3: - pass - - -class A4: - pass - - -class A5: - pass - - -class A6: - pass - - -class A7: - pass - - -class A8: - pass - - -class A9: - pass - - -class A10: - pass - - -class A11: - pass - - -class A12: - pass - - -class A13: - pass - - -class A14: - pass - - -class A15: - pass - - -class A16: - pass - - -class B1: - pass - - -class B2: - pass - - -class B3: - pass - - -class B4: - pass - - -class B5: - pass - - -class B6: - pass - - -class B7: - pass - - -class B8: - pass - - -class B9: - pass - - -class B10: - pass - - -class B11: - pass - - -class B12: - pass - - -class B13: - pass - - -class B14: - pass - - -class B15: - pass - - -class B16: - pass - - -type UA = ( - A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 -) - -type UB = ( - B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | B15 | B16 -) - - -def test(a: UA, b: UB) -> bool: - t = a, b - match t: - case A1(), B1(): - return True - case A2(), B2(): - return True - case A3(), B3(): - return True - case A4(), B4(): - reveal_type(t, expected_text="tuple[A4, B4]") - return True - case A5(), B5(): - return True - case A6(), B6(): - reveal_type(t, expected_text="tuple[A6, B6]") - return True - case A7(), B7(): - reveal_type(t, expected_text="tuple[A7, B7]") - return True - case A8(), B8(): - reveal_type(t, expected_text="tuple[A8, B8]") - return True - case A9(), B9(): - # The type will become less precise in this case - # because narrowing in the negative case needs - # to fall back on less-precise types. - reveal_type(t, expected_text="Sequence[A9 | B9]") - return True - case A10(), B10(): - return True - case A11(), B11(): - return True - case A12(), B12(): - return True - case A13(), B13(): - return True - case A14(), B14(): - return True - case A15(), B15(): - return True - case A16(), B16(): - return True - case _: - reveal_type(t, expected_text="Any") - raise ValueError() diff --git a/packages/vipeye-internal/src/tests/samples/matchSequenceVariadic.py b/packages/vipeye-internal/src/tests/samples/matchSequenceVariadic.py deleted file mode 100644 index aa8788f1..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchSequenceVariadic.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests pattern matching with variadic tuple types. -# From the regression report for Pyright 1.1.408. - -from typing import TypeAlias, assert_type - -Func6Input: TypeAlias = tuple[int] | tuple[str, str] | tuple[int, *tuple[str, ...], int] - - -def func6(val: Func6Input): - match val: - case (x,): - # Type may be narrowed to tuple[int]. - # E: Argument of type "tuple[int]" cannot be assigned to parameter of type "tuple[int] | tuple[str, str] | tuple[int, *tuple[str, ...], int]" - assert_type(val, Func6Input) - assert_type(val, tuple[int]) - - case (x, y): - # Type may be narrowed to tuple[str, str] | tuple[int, int]. - # E: Argument of type "tuple[str, str] | tuple[int, int]" cannot be assigned to parameter of type "tuple[int] | tuple[str, str] | tuple[int, *tuple[str, ...], int]" - assert_type(val, Func6Input) - assert_type(val, tuple[str, str] | tuple[int, int]) - - case (x, y, z): - # Type may be narrowed to tuple[int, str, int]. - # This case should be reachable! - # E: Argument of type "tuple[int, str, int]" cannot be assigned to parameter of type "tuple[int] | tuple[str, str] | tuple[int, *tuple[str, ...], int]" - assert_type(val, Func6Input) - assert_type(val, tuple[int, str, int]) - - case (w, x, y, z): - # Type may be narrowed to tuple[int, str, str, int]. - # E: Argument of type "tuple[int, str, str, int]" cannot be assigned to parameter of type "tuple[int] | tuple[str, str] | tuple[int, *tuple[str, ...], int]" - assert_type(val, Func6Input) - assert_type(val, tuple[int, str, str, int]) diff --git a/packages/vipeye-internal/src/tests/samples/matchUnnecessary1.py b/packages/vipeye-internal/src/tests/samples/matchUnnecessary1.py deleted file mode 100644 index 88eae4ba..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchUnnecessary1.py +++ /dev/null @@ -1,97 +0,0 @@ -# This sample tests the reportUnnecessaryComparison check when applied -# to match statements. - -from typing import Literal, Mapping, Sequence - -Letters = Literal["A", "B", "C"] - - -def func1(subj: Letters): - match subj: - # This should generate an error if reportUnnecessaryComparison is enabled. - case "A" | "B" | "D": - pass - case str(): - pass - # This should generate an error if reportUnnecessaryComparison is enabled. - case "C": - pass - # This should generate an error if reportUnnecessaryComparison is enabled. - case x: - print(x) - - -def func2(subj: int | dict[str, str]): - match subj: - # This should generate an error if reportUnnecessaryComparison is enabled. - case str() if subj > 4: - pass - case int() if subj > 4: - pass - case int(): - pass - # This should generate an error if reportUnnecessaryComparison is enabled. - case int(): - pass - # This should generate an error if reportUnnecessaryComparison is enabled. - case (a, b): - print(a, b) - case {"": d}: - print(d) - case dict(): - pass - # This should generate an error if reportUnnecessaryComparison is enabled. - case x: - print(x) - - -JsonValue = ( - None | bool | int | float | str | Sequence["JsonValue"] | Mapping[str, "JsonValue"] -) -JsonObject = Mapping[str, JsonValue] - - -def func3(json_object: JsonObject) -> None: - match json_object: - case { - "a": { - "b": [ - { - "c": "d", - } - ], - } - }: - pass - - -TA1 = tuple[Literal["a", "b", "c"], int] - - -def func4(vals: list[str]) -> TA1: - x: TA1 = ("c", 0) - - for val in vals: - match x[0]: - case "b": - if val.startswith("x"): - x = ("a", 1) - continue - case "c": - if val.startswith("y"): - x = ("b", 2) - continue - case _: - pass - return x - - -def func5(subj: int | str): - match subj: - case int() | str(): - pass - - # This should not generate a diagnostic becuase _ is exempted - # from the reportUnnecessaryComparison check. - case _: - pass diff --git a/packages/vipeye-internal/src/tests/samples/matchValue1.py b/packages/vipeye-internal/src/tests/samples/matchValue1.py deleted file mode 100644 index 8c3705a4..00000000 --- a/packages/vipeye-internal/src/tests/samples/matchValue1.py +++ /dev/null @@ -1,169 +0,0 @@ -# This sample tests type checking for match statements (as -# described in PEP 634) that contain value patterns. - -from dataclasses import dataclass -from enum import Enum, auto -from http import HTTPStatus -from typing import Annotated, Literal, TypeVar - -# viper: reportIncompatibleMethodOverride=false - - -def handle_reply(reply: tuple[HTTPStatus, str] | tuple[HTTPStatus]): - match reply: - case (HTTPStatus.OK as a1, a2): - reveal_type(a1, expected_text="Literal[HTTPStatus.OK]") - reveal_type(a2, expected_text="str") - - case (HTTPStatus.NOT_FOUND as d1,): - reveal_type(d1, expected_text="Literal[HTTPStatus.NOT_FOUND]") - - -class MyEnum1(Enum): - V1 = 0 - V2 = 1 - - -class MyClass: - class_var_1: "MyClass" - - def __eq__(self, object: "MyClass") -> bool: ... - - -def test_unknown(value_to_match): - match value_to_match: - case MyEnum1.V1 as a1: - reveal_type(a1, expected_text="Unknown") - reveal_type(value_to_match, expected_text="Unknown") - - -def test_enum(value_to_match: MyEnum1): - match value_to_match: - case MyEnum1.V1 as a1: - reveal_type(a1, expected_text="Literal[MyEnum1.V1]") - reveal_type(value_to_match, expected_text="Literal[MyEnum1.V1]") - case y: - reveal_type(y, expected_text="Literal[MyEnum1.V2]") - reveal_type(value_to_match, expected_text="Literal[MyEnum1.V2]") - - -def test_class_var(value_to_match: str): - match value_to_match: - case MyClass.class_var_1 as a1: - reveal_type(a1, expected_text="Never") - reveal_type(value_to_match, expected_text="Never") - - -TInt = TypeVar("TInt", bound=MyEnum1) - - -def test_union(value_to_match: TInt | MyEnum1) -> TInt | MyEnum1: - match value_to_match: - case MyEnum1.V1 as a1: - reveal_type(a1, expected_text="Literal[MyEnum1.V1]") - reveal_type(value_to_match, expected_text="Literal[MyEnum1.V1]") - - return value_to_match - - -class MyEnum2(Enum): - V1 = 0 - V2 = 1 - - -def test_multiple_enums(x: MyEnum2 | MyEnum1): - match x: - case MyEnum1.V1 | MyEnum1.V2 | MyEnum2.V1: - return - - reveal_type(x, expected_text="Literal[MyEnum2.V2]") - - -class Medal(Enum): - gold = 1 - silver = 2 - bronze = 3 - - -class Color(Enum): - red = 1 - blue = 2 - green = 3 - - -def test_enum_narrowing(m: Medal | Color | int): - match m: - case Medal.gold as a1: - reveal_type(a1, expected_text="Literal[Medal.gold]") - reveal_type(m, expected_text="Literal[Medal.gold]") - - case Medal.silver as b1: - reveal_type(b1, expected_text="Literal[Medal.silver]") - reveal_type(m, expected_text="Literal[Medal.silver]") - - case Color() as c1: - reveal_type(c1, expected_text="Color") - reveal_type(m, expected_text="Color") - - case d1: - reveal_type(d1, expected_text="int | Literal[Medal.bronze]") - reveal_type(m, expected_text="int | Literal[Medal.bronze]") - - -@dataclass -class DC1: - a: Annotated[Color, str] - - -def test_enum_narrowing_with_annotated(subj: DC1) -> None: - match subj.a: - case Color.red: - pass - case Color.blue: - pass - case x: - reveal_type(x, expected_text="Literal[Color.green]") - - -class Foo(Enum): - bar = auto() - - def __str__(self) -> str: - match self: - case Foo.bar: - return "bar" - - case x: - reveal_type(x, expected_text="Never") - - -class Numbers: - ZERO = 0.0 - ONE = 1 - INFINITY = float("inf") - - -def test_enum_narrowing_with_inf(subj: float): - match subj: - case Numbers.ONE: - reveal_type(subj, expected_text="Literal[1]") - case Numbers.INFINITY: - reveal_type(subj, expected_text="float") - case Numbers.ZERO: - reveal_type(subj, expected_text="float") - case f: - reveal_type(subj, expected_text="float") - - -@dataclass -class DC2: - a: Literal[False] - - -def test_bool_expansion(subj: bool): - match subj: - case DC2.a: - reveal_type(subj, expected_text="Literal[False]") - - case x: - reveal_type(subj, expected_text="Literal[True]") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess1.py b/packages/vipeye-internal/src/tests/samples/memberAccess1.py deleted file mode 100644 index 7e7cfb4c..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess1.py +++ /dev/null @@ -1,134 +0,0 @@ -# This sample validates that member access magic functions -# like __get__ and __set__ are handled correctly. - -from contextlib import ExitStack -from typing import ( - Any, - Awaitable, - Callable, - Concatenate, - ContextManager, - Generic, - ParamSpec, - TypeVar, - overload, -) -from functools import cached_property - -_T = TypeVar("_T") -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -class DescriptorA(Generic[_T]): - @overload - def __get__(self, instance: None, owner: Any) -> "DescriptorA[_T]": # type: ignore - ... - - @overload - def __get__(self, instance: Any, owner: Any) -> _T: ... - - -class ClassA: - bar = DescriptorA[str]() - - @classmethod - def func1(cls): - a: DescriptorA[str] = cls.bar - - -reveal_type(ClassA.bar, expected_text="DescriptorA[str]") -reveal_type(ClassA().bar, expected_text="str") - - -class ClassB: - @cached_property - def baz(self) -> int: - return 3 - - -c: cached_property[int] = ClassB.baz -d: int = ClassB().baz - - -class Factory: - def __get__(self, obj: Any, cls: type[_T]) -> _T: - return cls() - - -class ClassC: - instance: Factory - - -reveal_type(ClassC.instance, expected_text="ClassC") - - -class DescriptorD(Generic[_T]): - value: _T - - def __get__(self, instance: object | None, cls: type[object]) -> _T: ... - - def __set__(self, instance: object, value: _T) -> None: ... - - -class ClassD: - abc: DescriptorD[str] = DescriptorD() - stack: ExitStack - - def test(self, value: ContextManager[str]) -> None: - self.abc = self.stack.enter_context(value) - - -class DescriptorE: - def __get__(self, instance: "ClassE | None", owner: "type[ClassE]"): - return None - - -class MetaDescriptorE: - def __get__(self, instance: "type[ClassE] | None", owner: "MetaclassE"): - return None - - -class MetaclassE(type): - y = MetaDescriptorE() - - -class ClassE(metaclass=MetaclassE): - x = DescriptorE() - - -ClassE.x -ClassE().x -ClassE.y - - -class Decorator(Generic[_T, _P, _R]): - def __init__(self, func: Callable[Concatenate[_T, _P], Awaitable[_R]]) -> None: - self.func = func - - @overload - def __get__(self, obj: None, objtype: type[_T]) -> "Decorator[_T, _P, _R]": ... - - @overload - def __get__( - self, obj: _T, objtype: type[_T] | None - ) -> Callable[_P, Awaitable[_R]]: ... - - def __get__( - self, obj: _T | None, objtype: type[_T] | None = None - ) -> "Decorator[_T, _P, _R] | Callable[_P, Awaitable[_R]]": ... - - -class ClassF: - @Decorator - async def method1(self, a: int, *, b: str) -> str: ... - - def method2(self): - reveal_type(self.method1, expected_text="(a: int, *, b: str) -> Awaitable[str]") - - @classmethod - def method3(cls): - reveal_type( - cls.method1, - expected_text="Decorator[Self@ClassF, (a: int, *, b: str), str]", - ) diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess10.py b/packages/vipeye-internal/src/tests/samples/memberAccess10.py deleted file mode 100644 index 36b5d98c..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess10.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests the case where a metaclass defines a descriptor -# protocol (i.e. a `__get__` method), and a member is accessed through -# the class. - -from typing import Any - - -class _IntDescriptorMeta(type): - def __get__(self, instance: Any, owner: Any) -> int: - return 123 - - def __set__(self, instance: Any, value: str) -> None: - pass - - -class IntDescriptorClass(metaclass=_IntDescriptorMeta): ... - - -class X: - number_cls = IntDescriptorClass - - -reveal_type(X.number_cls, expected_text="int") -reveal_type(X().number_cls, expected_text="int") - -X.number_cls = "hi" - -X().number_cls = "hi" - -# This should generate an error -X.number_cls = 1 - -# This should generate an error -X().number_cls = 1 - - -class FlagValue: - def __init__(self, func): - self.value: bool = bool(func(None)) - - def __set__(self, instance: "Flags", value: int): - self.value = bool(value) - - -class Flags: - @FlagValue - def suppress(self): - return 2 - - -flags = Flags() - - -def func1(new: Any): - flags.suppress = new - - -def func2(new: int): - flags.suppress = new - - -def func3(new: bool): - flags.suppress = new diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess11.py b/packages/vipeye-internal/src/tests/samples/memberAccess11.py deleted file mode 100644 index 98e6b3b6..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess11.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests that methods are bound properly regardless of -# whether they are decorated. - -from typing import Callable, TypeVar - -S = TypeVar("S", bound="MyClass") - -Callback = Callable[[S, int], str] - - -def decorator1(method: Callback[S]) -> Callback[S]: - def wrapper(self: S, a: int) -> str: - return "wrapped " + method(self, a) - - return wrapper - - -class MyClass: - def __init__(self): - self.method4 = lambda x: x - - @decorator1 - def method1(self, a: int) -> str: - return "foo" - - def method2(self, a: int) -> str: - return "foo" - - method3 = decorator1(method2) - - -mc = MyClass() - -mc.method1(1) -mc.method2(1) -mc.method3(1) -mc.method4(1) diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess12.py b/packages/vipeye-internal/src/tests/samples/memberAccess12.py deleted file mode 100644 index dc85c2e1..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess12.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests a member access when the metaclass implements a descriptor -# protocol. - -from typing import Any, TypeVar, overload - - -T = TypeVar("T") - - -class MetaClass(type): - @overload - def __get__(self: type[T], instance: None, owner: Any) -> type[T]: ... - - @overload - def __get__(self: type[T], instance: object, owner: Any) -> T: ... - - def __get__(self: type[T], instance: object | None, owner: Any) -> type[T] | T: - if instance is None: - return self - return self() - - -class A(metaclass=MetaClass): ... - - -class B: - a = A - - -reveal_type(B.a, expected_text="type[A]") -reveal_type(B().a, expected_text="A") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess13.py b/packages/vipeye-internal/src/tests/samples/memberAccess13.py deleted file mode 100644 index 19fdf437..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess13.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests a member access when the member is a class -# that inherits from Any. - -from unittest.mock import Mock - - -class MockProducer: - produce: type[Mock] = Mock - - -reveal_type(MockProducer.produce, expected_text="type[Mock]") -reveal_type(MockProducer().produce, expected_text="type[Mock]") - - -reveal_type(MockProducer.produce(), expected_text="Mock") -reveal_type(MockProducer().produce(), expected_text="Mock") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess14.py b/packages/vipeye-internal/src/tests/samples/memberAccess14.py deleted file mode 100644 index af058cdb..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess14.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests the use of a generic descriptor class that -# is parameterized based on the type of the object that instantiates -# the descriptor. - - -from typing import Any, Callable, Generic, TypeVar, overload - -T = TypeVar("T") -T_contra = TypeVar("T_contra", contravariant=True) -V_co = TypeVar("V_co", covariant=True) -CachedSlotPropertyT = TypeVar( - "CachedSlotPropertyT", bound="CachedSlotProperty[Any, Any]" -) - - -class CachedSlotProperty(Generic[T_contra, V_co]): - def __init__(self, name: str, function: Callable[[T_contra], V_co]) -> None: ... - - @overload - def __get__( - self: CachedSlotPropertyT, instance: None, owner: type[T_contra] - ) -> CachedSlotPropertyT: ... - - @overload - def __get__(self, instance: T_contra, owner: Any) -> V_co: ... - - def __get__( - self: CachedSlotPropertyT, instance: T_contra | None, owner: Any - ) -> CachedSlotPropertyT | V_co: ... - - -def cached_slot_property( - name: str, -) -> Callable[[Callable[[T_contra], V_co]], CachedSlotProperty[T_contra, V_co]]: ... - - -class C(Generic[T]): - def __init__(self, data: T) -> None: ... - - @cached_slot_property("_prop") - def prop(self) -> int: ... - - -class D(C[float]): ... - - -reveal_type(C.prop, expected_text="CachedSlotProperty[C[Unknown], int]") -reveal_type(D.prop, expected_text="CachedSlotProperty[D, int]") - - -c = C("") -reveal_type(c.prop, expected_text="int") - -d = D(1) -reveal_type(d.prop, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess15.py b/packages/vipeye-internal/src/tests/samples/memberAccess15.py deleted file mode 100644 index a69cc4b3..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess15.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where an accessed member is a -# method that has a "self" or "cls" parameter with no explicit -# type annotation and an inferred type that is based on this value. - - -class A: - async def get(self): - return self - - -class B(A): - pass - - -async def run(): - val1 = await A().get() - reveal_type(val1, expected_text="A") - - val2 = await B().get() - reveal_type(val2, expected_text="B") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess16.py b/packages/vipeye-internal/src/tests/samples/memberAccess16.py deleted file mode 100644 index 27656e18..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess16.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the case where a member is accessed from a "type" -# instance or a Type[T]. - -# viper: strict - -from typing import TypeVar - -Cls = TypeVar("Cls") - - -def func(cls: type[Cls]) -> list[type[Cls]]: - return cls.__subclasses__() diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess17.py b/packages/vipeye-internal/src/tests/samples/memberAccess17.py deleted file mode 100644 index fb7514c6..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess17.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests the case where a __getattr__ method override -# differentiates based on the name of the accessed member. - -from typing import Any, overload, Literal - - -class Obj: - @overload - def __getattr__(self, name: Literal["foo"]) -> int: ... - - @overload - def __getattr__(self, name: Literal["bar"]) -> str: ... - - def __getattr__(self, name: str) -> Any: - if name == "foo": - return 1 - return "1" - - def __setattr__(self, name: str, value: str) -> None: - pass - - -obj = Obj() -b1 = obj.foo -reveal_type(b1, expected_text="int") -b2 = getattr(obj, "foo") -reveal_type(b2, expected_text="Any") - -c1 = obj.bar -reveal_type(c1, expected_text="str") -c2 = getattr(obj, "bar") -reveal_type(c2, expected_text="Any") - -# This should generate two errors. -d1 = obj.bogus - -obj.foo = "" -obj.bar = "" - -# This should generate an error. -obj.foo = 1 - -# This should generate an error. -obj.other = 1 - -# This should generate an error. -del obj.foo diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess18.py b/packages/vipeye-internal/src/tests/samples/memberAccess18.py deleted file mode 100644 index c9d5849d..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess18.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests that a descriptor returned by a __getattr__ method -# is not applied as part of a member access expression evaluation. - -from typing import Any, Generic, TypeVar - -_T = TypeVar("_T") - - -class A: - pass - - -class Descriptor: - def __get__(self, instance: object, owner: Any) -> A: - return A() - - -class CollectionThing(Generic[_T]): - thing: _T - - def __getitem__(self, key: str) -> _T: - return self.thing - - def __getattr__(self, key: str) -> _T: - return self.thing - - -c1: CollectionThing[Descriptor] = CollectionThing() - -reveal_type(c1["key"], expected_text="Descriptor") -reveal_type(c1.key, expected_text="Descriptor") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess19.py b/packages/vipeye-internal/src/tests/samples/memberAccess19.py deleted file mode 100644 index a6e5b0ac..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess19.py +++ /dev/null @@ -1,86 +0,0 @@ -# This sample tests the handling of __getattr__, __setattr__, and -# __delattr__ methods. - -from typing import Any, Literal, TypeVar, overload - -T = TypeVar("T") - - -class A: - @overload - def __getattr__(self, key: Literal["a"]) -> Literal["x"]: ... - - @overload - def __getattr__(self, key: Literal["b"]) -> Literal[4]: ... - - @overload - def __getattr__(self, key: Literal["c"]) -> Literal["y"]: ... - - @overload - def __getattr__(self: T, key: Literal["d"]) -> T: ... - - def __getattr__(self, key: Literal["a", "b", "c", "d"]) -> Any: ... - - @overload - def __setattr__(self, key: Literal["e"], val: str): ... - - @overload - def __setattr__(self, key: Literal["f"], val: int): ... - - def __setattr__(self, key: str, val: str | int): - pass - - @overload - def __delattr__(self, key: Literal["g"]): ... - - @overload - def __delattr__(self, key: Literal["h"]): ... - - def __delattr__(self, key: str): - pass - - -a = A() - -reveal_type(a.a, expected_text="Literal['x']") -reveal_type(a.b, expected_text="Literal[4]") -reveal_type(a.c, expected_text="Literal['y']") -reveal_type(a.d, expected_text="A") - -# This should generate an error. -reveal_type(a.e) - -# This should generate an error. -a.a = 4 - -a.e = "4" - -# This should generate an error. -a.e = 4 - -# This should generate an error. -a.f = "4" - -a.f = 4 - -# This should generate an error. -del a.e - -del a.g - -del a.h - - -# Test asymmetric __getattr__ and __setattr__ methods. We should not -# narrow the type on assignment in this case. -class B: - def __setattr__(self, __name: str, __value: Any) -> None: - pass - - def __getattr__(self, __attr: str) -> int: - return 10 - - -a = B() -a.test = "anything" -reveal_type(a.test, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess2.py b/packages/vipeye-internal/src/tests/samples/memberAccess2.py deleted file mode 100644 index f142e272..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess2.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample verifies that callable variables are bound -# to instances when they appear within most classes, but -# not within TypedDict or data classes. - -from typing import Callable, NamedTuple, TypedDict - - -# This class follows the normal rules where variable -# b, which is callable, acts like a class member and -# is bound to an instance by the member access operator. -class Foo1: - def __init__(self): - self.c = lambda s: s - - def a(self, s: str): - return s - - b = lambda a_inst, s: a_inst.inner_str + s - - -sample = Foo1() -a = sample.a("") -b = sample.b("") -c = sample.c("") - -d = Foo1.a(Foo1(), "") -e = Foo1.b(Foo1(), "") - - -# This class is a data class (because it derives from -# named tuple), so all variables that appear to be class -# variables are actually instance variables. -class Foo2(NamedTuple): - a: Callable[[int], int] - - -foo2 = Foo2(a=lambda a: a) -f = foo2.a(3) - - -class Foo3(TypedDict): - a: Callable[[int], int] - - -foo3 = Foo3(a=lambda a: a) -g = foo3["a"](3) diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess20.py b/packages/vipeye-internal/src/tests/samples/memberAccess20.py deleted file mode 100644 index e628cf57..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess20.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where an instance member write -# targets an instance variable with a TypeVar type. - -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class ClassA(Generic[T]): - def __init__(self, value: T) -> None: - self.value: T = value - - def set_value(self, value: int): - # This should generate an error. - self.value = value diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess21.py b/packages/vipeye-internal/src/tests/samples/memberAccess21.py deleted file mode 100644 index 416c8fb1..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess21.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the case where a member access is performed through -# an object using a field that is annotated as a ClassVar. Normally this -# is disallowed, but it is permitted if the type of the ClassVar is -# a descriptor object. - -from typing import ClassVar, Generic, TypeVar, overload, Self - -T = TypeVar("T") - - -class Descriptor(Generic[T]): - @overload - def __get__(self, instance: None, owner) -> Self: ... - - @overload - def __get__(self, instance: object, owner) -> T: ... - - def __get__(self, instance: object | None, owner) -> Self | T: ... - - def __set__(self, instance: object, value: T) -> None: ... - - def is_null(self) -> bool: ... - - -class Example: - field1: ClassVar = Descriptor[str]() - - field2: ClassVar = "" - - def reset(self) -> None: - self.field1 = "" - - # This should generate an error because field2 isn't - # a descriptor object. - self.field2 = "" diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess22.py b/packages/vipeye-internal/src/tests/samples/memberAccess22.py deleted file mode 100644 index ad9289f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess22.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a `type[T]` or `type[Self]` typevar is -# used as the base for a member access but is then used to call an -# instance method on the resulting class. - -from contextlib import contextmanager - - -class A: - @classmethod - def method1(cls) -> None: - cls.method2 - - @contextmanager - def method2(self): - yield diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess23.py b/packages/vipeye-internal/src/tests/samples/memberAccess23.py deleted file mode 100644 index 12ec6f27..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess23.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests the case where a custom metaclass has an attribute -# that holds a descriptor object and the attribute is accessed through -# a class constructed from the metaclass. The runtime has some surprising -# behavior in this case. It favors the metaclass descriptor object -# in this case even if the class has an instance attribute with the -# same name. - - -class MyMeta(type): - @property - def attr1(cls) -> int: - return 1 - - @property - def attr3(cls) -> int: - return 3 - - attr4 = "4" - - @property - def attr5(cls) -> int: - return 5 - - attr6 = 6 - - def __getattr__(self, name: str) -> complex: ... - - -class A(metaclass=MyMeta): - @property - def attr2(self) -> int: - return 2 - - @property - def attr3(self) -> int: - return 3 - - @property - def attr4(self) -> int: - return 4 - - attr5 = "5" - - -reveal_type(A.attr1, expected_text="int") -reveal_type(A().attr2, expected_text="int") -reveal_type(A.attr2, expected_text="property") -reveal_type(A().attr3, expected_text="int") -reveal_type(A.attr3, expected_text="int") -reveal_type(A.attr4, expected_text="property") -reveal_type(A.attr5, expected_text="int") -reveal_type(A.attr6, expected_text="int") -reveal_type(A.attr7, expected_text="complex") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess24.py b/packages/vipeye-internal/src/tests/samples/memberAccess24.py deleted file mode 100644 index 125fd4e2..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess24.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the case where an attribute is accessed from a -# class that derives from an unknown type or Any. - -from typing import Any, overload -from dummy import UnknownX # type: ignore - - -class Desc: - @overload - def __get__(self, instance: None, owner: Any) -> "Desc": ... - - @overload - def __get__(self, instance: object, owner: Any) -> int: ... - - def __get__(self, instance: object | None, owner: Any) -> "Desc | int": ... - - -class DerivesFromUnknown(UnknownX): - y: Desc - - -class DerivesFromAny(Any): - y: Desc - - -v1 = DerivesFromUnknown().x -reveal_type(v1, expected_text="Unknown") - -v2 = DerivesFromAny().x -reveal_type(v2, expected_text="Any") - -reveal_type(DerivesFromUnknown().y, expected_text="int") -reveal_type(DerivesFromAny().y, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess25.py b/packages/vipeye-internal/src/tests/samples/memberAccess25.py deleted file mode 100644 index 411723d7..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess25.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests for the check of a member access through a generic class -# when the type of the attribute is generic (and therefore its type is -# ambiguous). - -from typing import Generic, TypeVar - -T = TypeVar("T") - - -class ClassA(Generic[T]): - x: T - y: int - - def __init__(self, label: T | None = None) -> None: ... - - -ClassA[int].y = 1 -ClassA[int].y -del ClassA[int].y - -ClassA.y = 1 -ClassA.y -del ClassA.y - -# This should generate an error because x is generic. -ClassA[int].x = 1 - -# This should generate an error because x is generic. -ClassA[int].x - -# This should generate an error because x is generic. -del ClassA[int].x - -# This should generate an error because x is generic. -ClassA.x = 1 - -# This should generate an error because x is generic. -ClassA.x - -# This should generate an error because x is generic. -del ClassA.x - - -class ClassB(ClassA[T]): - pass - - -# This should generate an error because x is generic. -ClassB[int].x = 1 - -# This should generate an error because x is generic. -ClassB[int].x - -# This should generate an error because x is generic. -del ClassB[int].x - -# This should generate an error because x is generic. -ClassB.x = 1 - -# This should generate an error because x is generic. -ClassB.x - -# This should generate an error because x is generic. -del ClassB.x - - -class ClassC(ClassA[int]): - pass - - -ClassC.x = 1 -ClassC.x -del ClassC.x -ClassC.x -del ClassC.x diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess26.py b/packages/vipeye-internal/src/tests/samples/memberAccess26.py deleted file mode 100644 index 91f9952d..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess26.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests that type declarations for class members do not -# include method-local type variables. - -from typing import TypeVar - -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -def func(x: list[T1]): - class ClassB: - def __init__(self, val: list[T2]): - # This should generate an error because T is scoped to - # the method. - self.a1: list[T2] = val - - self.a2: list[T1] = [] - - @classmethod - def method_b(cls, val: list[T2]): - # This should generate an error because T is scoped to - # the method. - cls.b1: list[T2] = val - - cls.b2: list[T1] = [] - - def method_c(self, val: list[T2]): - # This should generate an error because T is scoped to - # the method. - self.c1: list[T2] = val - - self.c2: list[T1] = [] - - b = ClassB([]) - reveal_type(b.a1, expected_text="list[Unknown]") - reveal_type(b.b1, expected_text="list[Unknown]") - reveal_type(b.c1, expected_text="list[Unknown]") - - return b diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess27.py b/packages/vipeye-internal/src/tests/samples/memberAccess27.py deleted file mode 100644 index ce696e97..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess27.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests that members of an inner class that are parameterized -# by type variables from an outer scope are handled correctly. - -from typing import Callable, TypeVar - -T = TypeVar("T") - - -def func1(cb: Callable[[], T]) -> T: - class InnerClass: - def __init__(self) -> None: - self.result: T | None = None - - def run(self) -> None: - self.result = cb() - - reveal_type(InnerClass().result, expected_text="T@func1 | None") - - return cb() diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess28.py b/packages/vipeye-internal/src/tests/samples/memberAccess28.py deleted file mode 100644 index cd9b22e6..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess28.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where an attribute is accessed -# via a bound TypeVar. - -from dataclasses import dataclass - - -@dataclass -class DC1: - x: int - - -class GenericClass[T: DC1]: - def method1(self, t: T): - pass - - def method2(self, t: T): - # This should generate an error. - self.method1(t.x) diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess3.py b/packages/vipeye-internal/src/tests/samples/memberAccess3.py deleted file mode 100644 index c38e686a..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess3.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests instance and class variable type inference when -# the type can't be inferred from the class itself and must use -# the parent class. - - -from typing import Generic, TypeVar - - -class A: - pi = 3.1415 - - def __init__(self): - self.x = 1 - - -class B(A): - def __init__(self): - self.y = "hi" - - -class C(B): - def method1(self): - a = self.x - require_int(a) - - # This should generate an error because a should be an int - require_str(a) - - b = self.y - require_str(b) - - # This should generate an error because b should be an str - require_int(b) - - c = self.pi - require_float(c) - - # This should generate an error because c should be a float - require_int(c) - - -def require_int(val: int): - pass - - -def require_str(val: str): - pass - - -def require_float(val: float): - pass - - -_TParent = TypeVar("_TParent") -_TChild = TypeVar("_TChild") - - -class Parent(Generic[_TParent]): - member1: _TParent - - -class Child(Parent[_TChild]): - def __init__(self, val: _TChild): - self.member1 = val diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess4.py b/packages/vipeye-internal/src/tests/samples/memberAccess4.py deleted file mode 100644 index a0e241b0..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess4.py +++ /dev/null @@ -1,120 +0,0 @@ -# This sample tests the logic for validating that an explicit -# "self" or "cls" parameter type is honored when binding the -# method to an object or class. - -from typing import Callable, Protocol, TypeVar - - -class HasItemProtocol1(Protocol): - item: int - - -class Mixin1: - def do_stuff(self: HasItemProtocol1): - pass - - -class A1(Mixin1): - item = 1 - - -class B1(Mixin1): - item = "hi" - - -class C1(Mixin1): - pass - - -A1().do_stuff() - -# This should generate an error because B1 doesn't -# match the protocol. -B1().do_stuff() - -# This should generate an error because C1 doesn't -# match the protocol. -C1().do_stuff() - - -class HasItemProtocol2(Protocol): - def must_have(self) -> None: - pass - - -class Mixin2: - @classmethod - def do_stuff(cls: type[HasItemProtocol2]): - pass - - -class A2(Mixin2): - def must_have(self) -> None: - pass - - -class B2(Mixin2): - pass - - -A2.do_stuff() - -# This should generate an error because B2 doesn't -# match the protocol. -B2.do_stuff() - - -class D: - pass - - -class E: - @staticmethod - def get_or_create(context: D): - return object.__getattribute__(context, "") - - -T_F = TypeVar("T_F", bound="F") - - -class F: - @classmethod - def bar(cls: type[T_F]) -> T_F: ... - - def baz(self) -> None: - self.bar() - - -class ClassWithNewOverride: - def __new__(cls): - return object.__new__(cls) - - -def curry[First, *Rest, Result]( - function: Callable[[First, *Rest], Result], -) -> Callable[[*Rest], Callable[[First], Result]]: ... - - -class EvilProto1(Protocol): - @curry - def __call__[A, B]( - self, a: Callable[[A], B], b: Callable[[Callable[[A], B]], A] - ) -> B: ... - - -# This should generate an error and not hang. -EvilProto1.__call__ - - -# This should generate an error and not hang. -p: EvilProto1 = curry(lambda a, b: a(b(a))) - - -class G: - type TypeAlias1 = Callable[[], None] - - def __init__(self): - self.someVarNoArgs: G.TypeAlias1 - - -g_ta: G.TypeAlias1 diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess5.py b/packages/vipeye-internal/src/tests/samples/memberAccess5.py deleted file mode 100644 index c86e1de5..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess5.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the handling of unions between -# objects that provide a __get__ method and those -# that do not. - -from typing import Any - - -class IntProvider: - def __get__(self, instance: object, owner: Any) -> int: - return 0 - - -class Foo: - _int_value_declared: IntProvider | int = 3 - _int_value_inferred = 3 - - def __init__(self): - pass - - def get_int_value_1(self) -> int: - reveal_type(self._int_value_declared, expected_text="int") - return self._int_value_declared - - def get_int_value_2(self) -> int: - reveal_type(self._int_value_inferred, expected_text="int") - return self._int_value_inferred diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess6.py b/packages/vipeye-internal/src/tests/samples/memberAccess6.py deleted file mode 100644 index 03f1175b..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess6.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests member access "set" operations when the target -# member is an object that doesn't provide a __set__ method. - -# viper: strict - -from typing import Any, Generic, TypeVar, overload - - -_T = TypeVar("_T") - - -class ParentA: - pass - - -class Column(Generic[_T]): - def __init__(self, type: type[_T]) -> None: ... - - @overload - def __get__(self: "Column[_T]", instance: None, type: Any) -> "Column[_T]": ... - - @overload - def __get__(self: "Column[_T]", instance: ParentA, type: Any) -> _T: ... - - def __get__( - self, instance: ParentA | None, type: Any - ) -> _T | None | "Column[_T]": ... - - -class ChildA(ParentA): - attr1: Column[str] = Column(str) - attr2 = Column(str) - - -ChildA.attr1 -ChildA().attr1 -ChildA.attr2 -ChildA().attr2 - -foo = ChildA() - -# This should generate an error because bar is declared as containing a -# Column[str], which doesn't provide a __set__ method. -foo.attr1 = "" - -# This should generate an error because baz's inferred type is -# Column[str], which doesn't provide a __set__ method. -foo.attr2 = "" diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess7.py b/packages/vipeye-internal/src/tests/samples/memberAccess7.py deleted file mode 100644 index 7fedfe70..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess7.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the handling of a __getattr__ method that returns -# a callable. Such a method should not be bound. - -from typing import Callable, TypeVar - - -class ClassA: - def __init__(self): - return - - def __getattr__(self, key: str) -> Callable[[str], str]: - return lambda a: a - - -a = ClassA() - -a.foo("hi") - - -T = TypeVar("T") - - -class MetaClass(type): - def __getattr__(cls, key: str) -> Callable[[T], T]: - return lambda x: x - - -class ClassB(metaclass=MetaClass): - pass - - -v1 = ClassB.some_function(3) -reveal_type(v1, expected_text="int") - -v2 = ClassB.some_function("hi") -reveal_type(v2, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess8.py b/packages/vipeye-internal/src/tests/samples/memberAccess8.py deleted file mode 100644 index d26f9477..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess8.py +++ /dev/null @@ -1,68 +0,0 @@ -# This sample tests the use of a generic descriptor class. - -from typing import Any, Callable, Generic, TypeVar, overload - - -_T = TypeVar("_T") -_T_co = TypeVar("_T_co", covariant=True) - - -class Column(Generic[_T]): - def __get__(self, instance: object, type: Any) -> _T: ... - - def __set__(self, instance: object, value: _T) -> _T: ... - - def __delete__(self, instance: object) -> None: ... - - -class Foo: - bar: Column[str] = Column() - baz: Column[list[int]] = Column() - - -foo = Foo() - -v1 = foo.bar -reveal_type(v1, expected_text="str") - -foo.bar = "" -del foo.bar - - -v2 = foo.baz -reveal_type(v2, expected_text="list[int]") - -foo.baz = [1] -del foo.baz - - -class Minimal(Generic[_T, _T_co]): - def __init__(self, name: str, func: Callable[[_T], _T_co]): ... - - @overload - def __get__(self, instance: None, owner: type[_T]) -> "Minimal[_T, _T_co]": ... - - @overload - def __get__(self, instance: _T, owner: type[_T]) -> _T_co: ... - - def __get__(self, instance: _T | None, owner: type[_T]) -> Any: ... - - -def minimal_property( - name: str, -) -> Callable[[Callable[[_T], _T_co]], Minimal[_T, _T_co]]: - def decorator(func: Callable[[_T], _T_co]) -> Minimal[_T, _T_co]: - return Minimal(name, func) - - return decorator - - -class B: - @minimal_property("foo") - def foo(self) -> str: - return "hello" - - -b = B() -reveal_type(b.foo, expected_text="str") -reveal_type(B.foo, expected_text="Minimal[B, str]") diff --git a/packages/vipeye-internal/src/tests/samples/memberAccess9.py b/packages/vipeye-internal/src/tests/samples/memberAccess9.py deleted file mode 100644 index 46930b20..00000000 --- a/packages/vipeye-internal/src/tests/samples/memberAccess9.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that the presence of a __getattr__ doesn't -# mean that an __init__ method is assumed. - - -class GetAttrTest: - def __getattr__(self, name: str) -> int: ... - - -def test_get_attr() -> None: - a = GetAttrTest() diff --git a/packages/vipeye-internal/src/tests/samples/metaclass1.py b/packages/vipeye-internal/src/tests/samples/metaclass1.py deleted file mode 100644 index 5186b9c1..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass1.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests pyright's ability to use metaclasses. - -from ctypes import Array, c_uint64 -from typing import Any, TypeAlias, TypeVar - -myArray1 = (c_uint64 * 5)() - -myArray2: Array[c_uint64] = (c_uint64 * 5)() - - -T = TypeVar("T") - - -class CustomMeta(type): - def __getitem__(self, key: Any) -> "type[int]": ... - - -class Custom(metaclass=CustomMeta): ... - - -class OtherMeta(type): ... - - -# This should generate an error because the class isn't -# Generic even though it supports a metaclass with a -# __getitem__. -y1: Custom[int] - -# This should not generate an error because it is used -# as a runtime expression rather than a type annotation. -y2 = Custom[int] - -# This should generate an error. -y3: TypeAlias = Custom[int] - - -def func1(m: CustomMeta): - v1: type = m - v2: type[Any] = m - - # This should generate an error. - v3: type[Custom] = m - - -def func2(m: OtherMeta): - # This should generate an error because OtherMeta - # and the metaclass for Custom are not compatible. - v3: type[Custom] = m diff --git a/packages/vipeye-internal/src/tests/samples/metaclass10.py b/packages/vipeye-internal/src/tests/samples/metaclass10.py deleted file mode 100644 index b69eac39..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass10.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a member access expression is used -# to access an instance method on a metaclass. Binding should not be -# performed in this case. - -from enum import EnumMeta -from typing import TypeVar - -_EnumMemberT = TypeVar("_EnumMemberT") - - -class EnumMeta2(EnumMeta): - def __getitem__(cls: type[_EnumMemberT], name: str) -> _EnumMemberT: - return EnumMeta.__getitem__(cls, name) - - -class MyMeta(type): - @classmethod - def meta_method(cls) -> None: ... - - -MyMeta.meta_method() diff --git a/packages/vipeye-internal/src/tests/samples/metaclass11.py b/packages/vipeye-internal/src/tests/samples/metaclass11.py deleted file mode 100644 index 90d186cf..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass11.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample verifies that the type checker allows access -# to instance variables provided by a metaclass. - -from typing import Any - - -class MetaA(type): - var0 = 3 - - def __init__(cls, name, bases, dct): - cls.var1 = "hi" - - -class ClassA(metaclass=MetaA): - pass - - -# This should generate an error because var0 isn't -# accessible via an instance of this class. -ClassA().var0 -reveal_type(ClassA.var0, expected_text="int") -ClassA.var0 = 1 - -reveal_type(ClassA().var1, expected_text="str") -reveal_type(ClassA.var1, expected_text="str") - -ClassA.var1 = "hi" -ClassA().var1 = "hi" - - -class MetaB(type): - def __setattr__(cls, key: str, value: Any) -> None: ... - - -class ClassB(metaclass=MetaB): - var0: int - - -# This should generate an error -ClassB.var0 = "" -ClassB.var1 = "" - -ClassB().var0 = 1 - -# This should generate an error -ClassB().var0 = "" - -# This should generate an error -ClassB().var1 = "" diff --git a/packages/vipeye-internal/src/tests/samples/metaclass2.py b/packages/vipeye-internal/src/tests/samples/metaclass2.py deleted file mode 100644 index 20b9efc3..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass2.py +++ /dev/null @@ -1,52 +0,0 @@ -# This sample verifies that the type checker allows access -# to class variables provided by a metaclass. - -from enum import Enum -from typing import Mapping - - -class Fruit(Enum): - apple = 1 - orange = 2 - pear = 3 - - -def requires_fruit_mapping(a: Mapping[str, Fruit]): - pass - - -requires_fruit_mapping(Fruit.__members__) - -aaa = len(Fruit) - -for i in Fruit: - print(i) - - -class Meta(type): - inst_var1: int - - def __init__(self): - self.inst_var1 = 1 - - def method1(cls, some_param: str): - pass - - -class MyClass1(metaclass=Meta): - pass - - -MyClass1.method1("some argument") -reveal_type(MyClass1.inst_var1, expected_text="int") - - -class MyClass2(metaclass=Meta): - # This should generate an error - inst_var1 = "" - - -class MyClass3(metaclass=Meta): - def __init__(self): - # This should generate an error - self.inst_var1 = "" diff --git a/packages/vipeye-internal/src/tests/samples/metaclass3.py b/packages/vipeye-internal/src/tests/samples/metaclass3.py deleted file mode 100644 index 1062e0a2..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass3.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests the detection of metaclass conflicts. - -from typing import Protocol - - -class Meta1(type): - pass - - -class Meta2(type): - pass - - -class Base1(metaclass=Meta1): - pass - - -class Base2(metaclass=Meta2): - pass - - -# This should generate an error because the two -# metaclasses conflict. -class Base3(Base1, Base2): - pass - - -class Meta3(type): - pass - - -class SubMeta3(Meta3): - pass - - -class Base4(metaclass=Meta3): - pass - - -class Base5(metaclass=SubMeta3): - pass - - -class Base6(Base4, Base5): - pass - - -class Meta10(type): ... - - -class Base10(metaclass=Meta10): ... - - -class Proto10(Protocol): ... - - -class Meta11(type(Base10), type(Proto10)): - pass - - -class Base11(Base10, Proto10, metaclass=Meta11): ... diff --git a/packages/vipeye-internal/src/tests/samples/metaclass4.py b/packages/vipeye-internal/src/tests/samples/metaclass4.py deleted file mode 100644 index 89f78a43..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass4.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample covers the case where a metaclass (a class that derives -# from "type") is directly instantiated to create a new class, -# and that class is then used as a base class for another class. - - -class MyMeta(type): - def do_something(self, p1: str, p2: int): - pass - - -MyCustomClass = MyMeta("MyCustomClass", (object,), {}) - -reveal_type(MyCustomClass, expected_text="type[MyCustomClass]") - - -class DerivedCustomClass(MyCustomClass): - pass - - -DerivedCustomClass.do_something("hi", 3) - -# This should generate an error because the second -# argument is the wrong type. -DerivedCustomClass.do_something("hi", "no") - -instance = DerivedCustomClass() diff --git a/packages/vipeye-internal/src/tests/samples/metaclass5.py b/packages/vipeye-internal/src/tests/samples/metaclass5.py deleted file mode 100644 index c8277735..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass5.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the handling of metaclass magic methods for -# binary operators. - -# viper: reportIncompatibleMethodOverride=false - - -class MetaA(type): - def __eq__(self, a: "type[ClassA]") -> str: - return "hi" - - def __add__(self, a: "type[ClassA]") -> int: - return 0 - - -class ClassA(metaclass=MetaA): - pass - - -def func1(a: ClassA): - reveal_type(type(a), expected_text="type[ClassA]") - reveal_type(type("string1"), expected_text="type[str]") - - reveal_type(type(a) == type("hi"), expected_text="bool") - reveal_type(type("hi") == type("hi"), expected_text="bool") - reveal_type(str != str, expected_text="bool") - reveal_type(ClassA == type(a), expected_text="str") - reveal_type(ClassA != type(a), expected_text="bool") - reveal_type(type(a) == ClassA, expected_text="str") - - # This should generate an error - x = str + str - - reveal_type(ClassA + ClassA, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/metaclass6.py b/packages/vipeye-internal/src/tests/samples/metaclass6.py deleted file mode 100644 index 05fb4470..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass6.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample verifies that metaclasses can be used to satisfy -# protocols if a class type is passed. - -from enum import Enum - - -class Foo(str, Enum): - bar = "bar" - - -for member in Foo: - reveal_type(member, expected_text="Foo") - -foo_members = list(Foo) -reveal_type(foo_members, expected_text="list[Foo]") diff --git a/packages/vipeye-internal/src/tests/samples/metaclass7.py b/packages/vipeye-internal/src/tests/samples/metaclass7.py deleted file mode 100644 index 9f5cec40..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass7.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests the case where a metaclass defines a customer -# __call__ method, thus overriding the __new__ method on classes -# that are created from it. - -# viper: reportIncompatibleMethodOverride=false - - -from typing import Any, Self - - -class MetaClass1(type): - def __call__(cls, **kwargs): - return object.__new__(**kwargs) - - -class Class1(metaclass=MetaClass1): - def __new__(cls, *args, **kwargs): - raise RuntimeError("Cannot instantiate directly") - - -v1 = Class1() -reveal_type(v1, expected_text="NoReturn") - - -class MetaClass2(type): - pass - - -class Class2(metaclass=MetaClass2): - def __new__(cls, *args, **kwargs): - raise RuntimeError("Cannot instantiate directly") - - -v2 = Class2() -reveal_type(v2, expected_text="NoReturn") - - -class MetaClass3(type): - def __call__(cls, *args, **kwargs) -> Any: - return super().__call__(*args, **kwargs) - - -class Class3(metaclass=MetaClass3): - def __new__(cls, *args, **kwargs): - raise RuntimeError("You cannot instantiate BaseFactory") - - -v3 = Class3() -reveal_type(v3, expected_text="Any") - - -class MetaClass4(type): - def __call__(cls, *args, **kwargs): - return super().__call__(*args, **kwargs) - - -class Class4(metaclass=MetaClass4): - def __new__(cls, *args, **kwargs) -> Self: - return super().__new__(cls, *args, **kwargs) - - -v4 = Class4() -reveal_type(v4, expected_text="Class4") diff --git a/packages/vipeye-internal/src/tests/samples/metaclass8.py b/packages/vipeye-internal/src/tests/samples/metaclass8.py deleted file mode 100644 index 41a74cbe..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass8.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a generic class is used -# for a metaclass. - -from typing import Any, Generic, TypeVar - - -T = TypeVar("T") - - -class A(type, Generic[T]): ... - - -# This should generate an error because generic metaclasses are not allowed. -class B(Generic[T], metaclass=A[T]): ... - - -class C(metaclass=A[Any]): ... diff --git a/packages/vipeye-internal/src/tests/samples/metaclass9.py b/packages/vipeye-internal/src/tests/samples/metaclass9.py deleted file mode 100644 index 86c5d594..00000000 --- a/packages/vipeye-internal/src/tests/samples/metaclass9.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample tests the handling of metaclass keyword arguments. - -from typing import Any, TypeVar - -T = TypeVar("T") - - -class Meta1(type): - def __new__( - cls: type[T], - cls_name: str, - bases: tuple[type, ...], - attrs: dict[str, Any], - *, - param1: int, - param2: str, - param3: str = "", - ) -> T: ... - - -class Class1_1(metaclass=Meta1, param1=1, param2="", param3=""): ... - - -class Class1_2(metaclass=Meta1, param2="", param1=1): ... - - -# This should generate an error because param1 is the wrong type. -class Class1_3(metaclass=Meta1, param1="", param2=""): ... - - -# This should generate an error because param1 and param2 are missing. -class Class1_4(metaclass=Meta1): ... - - -# This should generate an error because param4 doesn't exist. -class Class1_5(metaclass=Meta1, param2="", param1=1, param4=3): ... - - -class Meta2(type): - def __new__( - cls: type[T], - cls_name: str, - bases: tuple[type, ...], - attrs: dict[str, Any], - *, - param1: int, - **kwargs: str, - ) -> T: ... - - -class Class2_1(metaclass=Meta2, param1=1, param2="", param3=""): ... - - -class Class2_2(metaclass=Meta2, param2="", param1=1, param20=""): ... - - -# This should generate an error because param1 is the wrong type. -class Class2_3(metaclass=Meta2, param1="", param2=""): ... - - -# This should generate an error because param1 is missing. -class Class2_4(metaclass=Meta2): ... - - -# This should generate an error because param4 is the wrong type. -class Class2_5(metaclass=Meta2, param2="", param1=1, param4=3): ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride1.py b/packages/vipeye-internal/src/tests/samples/methodOverride1.py deleted file mode 100644 index 9d6fdaf4..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride1.py +++ /dev/null @@ -1,546 +0,0 @@ -# This sample tests the reportIncompatibleMethodOverride -# diagnostic check. - -from typing import ( - Any, - Callable, - Generic, - Iterable, - ParamSpec, - Sequence, - TypedDict, - TypeVar, - overload, -) - -T_ParentClass = TypeVar("T_ParentClass", bound="ParentClass") - -P = ParamSpec("P") -T = TypeVar("T") -S = TypeVar("S") -U = TypeVar("U", bound=int) - - -def decorator(func: Callable[P, None]) -> Callable[P, int]: ... - - -class ParentClass: - def my_method1(self, a: int): - return 1 - - def my_method2(self, a: int, b: int): - return 1 - - def my_method3(self, a: int, b: int): - return 1 - - def my_method4(self, a: int, *b: int): - return 1 - - def my_method5(self, a: int, _b: int): - return 1 - - def my_method6(self, a: int, /, b: int): - return 1 - - def my_method7(self, a: int, /, b: int): - return 1 - - def my_method8(self, a: int, b: int): - return 1 - - def my_method9(self, a: int, b: int): - return 1 - - def my_method10(self, a: int, b: int): - return 1 - - def my_method11(self, a: int, b: int): - return 1 - - def my_method12(self, a: int | str) -> int | str: - return 1 - - def my_method13(self, a: int) -> int: - return 1 - - def my_method14(self, a: int) -> int: - return 1 - - def my_method15(self, a: int) -> int: - return 1 - - def my_method16(self, a: int) -> int: - return 1 - - def my_method17(self, a: str, b: int, c: float, d: bool) -> None: ... - - def my_method18(self, a: str, b: int, c: float, d: bool) -> None: ... - - def my_method19(self, a: str, b: int, c: float, d: bool) -> None: ... - - @classmethod - def my_method20(cls: type[T_ParentClass], a: str) -> T_ParentClass: ... - - def my_method21(self, var: int) -> None: ... - - def _protected_method1(self, a: int): - return 1 - - def __private_method1(self, a: int): - return 1 - - def my_method22(self, a: str, b: int, c: float, d: bool) -> None: ... - - def my_method23(self, a: str = "") -> None: ... - - def my_method24(self, a: str) -> None: ... - - def my_method25(self, *, a: str = "") -> None: ... - - def my_method26(self, *, a: str) -> None: ... - - def my_method27(self, a: object, /) -> None: ... - - def my_method28(self, __a: object) -> None: ... - - @classmethod - def my_method29(cls, /) -> None: ... - - @classmethod - def my_method30(cls, /) -> None: ... - - @staticmethod - def my_method31(a: "type[ParentClass]", /) -> None: ... - - @staticmethod - def my_method32(a: "type[ParentClass]", /) -> None: ... - - def my_method33(self, /) -> None: ... - - def my_method34(self, /) -> None: ... - - def my_method35(self, *, a: int) -> None: ... - - def my_method36(self, *, a: int) -> None: ... - - def my_method37(self, a: int, /) -> None: ... - - def my_method38(self, a: int, /) -> None: ... - - def my_method39(self, a: int, /) -> None: ... - - def my_method40(self, a: int, /) -> None: ... - - def my_method41(self, a: int, b: str, c: str) -> None: ... - - def my_method42(self, a: int, b: int, c: str) -> None: ... - - my_method43: Callable[..., None] - - def my_method44(self, *args: object, **kwargs: object) -> None: ... - - def my_method45(self, __i: int) -> None: ... - - def __my_method46__(self, x: int) -> None: ... - - def __my_method47__(self, x: int) -> None: ... - - def my_method48(self, /, **kwargs: object) -> None: ... - - -T_ChildClass = TypeVar("T_ChildClass", bound="ChildClass") - - -class ChildClass(ParentClass): - # This should generate an error because the type of 'a' doesn't match. - def my_method1(self, a: str): - return 1 - - # This should generate an error because it's missing a param named 'b'. - def my_method2(self, a: int): - return 1 - - # This should generate an error because the name doesn't match. - def my_method3(self, a: int, c: int): - return 1 - - # This should generate an error because the param category for 'b' - # doesn't match. - def my_method4(self, a: int, **b: int): - return 1 - - def my_method5(self, a: int, _c: int): - return 1 - - def my_method6(self, not_a: int, /, b: int): - return 1 - - # This should generate an error because c is not a position-only parameter. - def my_method7(self, a: int, /, c: int): - return 1 - - # This should generate an error because it contains too many parameters. - def my_method8(self, a: int, b: int, c: int, d: str = ""): - return 1 - - def my_method9(self, a: int, b: int, c: int = 4): - return 1 - - def my_method10(self, a: int, b: int, *args): - return 1 - - def my_method11(self, a: int, b: int, *, c: str = "", **kwargs): - return 1 - - # This should generate an error because the type of 'a' is - # narrower than the original method. - def my_method12(self, a: int) -> int: - return 1 - - def my_method13(self, a: int | str) -> int: - return 1 - - # This should generate an error because the return type is - # wider than in the original method. - def my_method14(self, a: int) -> int | str: - return 1 - - # This should generate an error because we're overriding a - # method with a variable. - my_method15: int = 3 - - # This should generate an error because we're overriding a - # method with a class. - class my_method16: - pass - - def my_method17(self, *args: object, **kwargs: object) -> None: ... - - def my_method18(self, a: str, *args: object, **kwargs: object) -> None: ... - - # This should generate an error because b param doesn't match a in name. - def my_method19(self, b: str, *args: object, **kwargs: object) -> None: ... - - @classmethod - def my_method20(cls: type[T_ChildClass], a: str) -> T_ChildClass: ... - - # This should generate an error. - @decorator - def my_method21(self, var: int) -> None: ... - - # This should generate an error. - def _protected_method1(self): - return 1 - - def __private_method1(self): - return 1 - - # This should generate an error. - def my_method22(self, a: str, b: int, c: float, d: bool, /) -> None: ... - - # This should generate an error because a is missing a default value. - def my_method23(self, a: str) -> None: ... - - def my_method24(self, a: str = "") -> None: ... - - # This should generate an error because a is missing a default value. - def my_method25(self, *, a: str) -> None: ... - - def my_method26(self, *, a: str = "") -> None: ... - - def my_method27(self, __a: object) -> None: ... - - def my_method28(self, a: object, /) -> None: ... - - # This should generate an error because it is not a classmethod. - def my_method29(self, /) -> None: ... - - # This should generate an error because it is not a classmethod. - @staticmethod - def my_method30(a: type[ParentClass], /) -> None: ... - - # This should generate an error because it is not a staticmethod. - @classmethod - def my_method31(cls, /) -> None: ... - - # This should generate an error because it is not a staticmethod. - def my_method32(self, /) -> None: ... - - # This should generate an error because it is not an instance method. - @classmethod - def my_method33(cls, /) -> None: ... - - # This should generate an error because it is not an instance method. - @staticmethod - def my_method34(a: type[ParentClass], /) -> None: ... - - def my_method35(self, **kwargs: int) -> None: ... - - # This should generate an error because the method in the parent - # class has a keyword-only parameter that is type 'int', and this - # isn't compatible with 'str'. - def my_method36(self, **kwargs: str) -> None: ... - - def my_method37(self, *args: Any) -> None: ... - - # This should generate an error because the number of position-only - # parameters doesn't match. - def my_method38(self, **kwargs: Any) -> None: ... - - def my_method39(self, *args: Any) -> None: ... - - # This should generate an error because the number of position-only - # parameters doesn't match. - def my_method40(self, **kwargs: Any) -> None: ... - - # This should generate an error because keyword parameters "a" - # and "b" are missing. - def my_method41(self, a: int, *args: str) -> None: ... - - # This should generate an error because args doesn't have the right type. - def my_method42(self, a: int, *args: int) -> None: ... - - def my_method43(self, a: int, b: str, c: str) -> None: ... - - # This should generate an error because kwargs is missing. - def my_method44(self, *object) -> None: ... - - def my_method45(self, i: int, /) -> None: ... - - def __my_method46__(self, y: int) -> None: ... - - # This should generate an error because of a type mismatch. - def __my_method47__(self, y: str) -> None: ... - - # This should generate an error because the keyword-only parameter "x: int" - # is not compatible with the base method's "**kwargs: object". - def my_method48(self, /, *, x: int = 3, **kwargs: object) -> None: ... - - -class A: - def test(self, t: Sequence[int]) -> Sequence[str]: ... - - -class GeneralizedArgument(A): - def test(self, t: Iterable[int], bbb: str = "") -> Sequence[str]: ... - - -class NarrowerArgument(A): - # This should generate error because list[int] is narrower - # than Iterable[int]. - def test(self, t: list[int]) -> Sequence[str]: ... - - -class NarrowerReturn(A): - def test(self, t: Sequence[int]) -> list[str]: ... - - -class GeneralizedReturn1(A): - # This should generate an error because Iterable[str] is - # wider than Sequence[str]. - def test(self, t: Sequence[int]) -> Iterable[str]: ... - - -class GeneralizedReturn2(A): - # This should generate an error because list[int] is - # incompatible with Sequence[str]. - def test(self, t: Sequence[int]) -> list[int]: ... - - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - - -class Base1: - def submit(self, fn: Callable[..., _T1], *args: Any, **kwargs: Any) -> list[_T1]: - return [] - - -class Base2(Base1): - def submit(self, fn: Callable[..., _T2], *args: Any, **kwargs: Any) -> list[_T2]: - return [] - - -class Foo: - pass - - -_T2A = TypeVar("_T2A", bound=Foo) -_T2B = TypeVar("_T2B", bound=Foo) - - -class ClassA(Generic[_T2A]): - def func1(self) -> _T2A | None: - return None - - @property - def prop1(self) -> _T2A | None: - return None - - @property - def prop2(self) -> _T2A | None: - return None - - @prop2.setter - def prop2(self, val: _T2A): - pass - - @prop2.deleter - def prop2(self): - pass - - @property - def prop3(self) -> _T2A | None: - return None - - @prop3.setter - def prop3(self, val: _T2A): - pass - - @property - def prop4(self) -> _T2A | None: - return None - - @prop4.deleter - def prop4(self): - pass - - @property - def prop5(self) -> int: - return 3 - - @property - def prop6(self) -> int: - return 3 - - @prop6.setter - def prop6(self, x: int) -> None: - pass - - -class ClassB(ClassA[_T2B]): - # This should generate an error because a variable - # cannot override a property. - prop1: _T2B - - def func1(self) -> _T2B | None: - return None - - @property - def prop2(self) -> _T2B: - return self.prop1 - - @prop2.setter - def prop2(self, val: _T2B): - pass - - @prop2.deleter - def prop2(self): - pass - - # This should generate an error because it is missing - # a setter (fset method). - @property - def prop3(self) -> _T2B | None: - return None - - # This should generate an error because it is missing - # a deleter (fdel method). - @property - def prop4(self) -> _T2B | None: - return None - - # This should generate an error because prop4's getter - # method isn't compatible with base class. - @property - def prop5(self) -> str: - return "hi" - - def func6(self): - self.prop6 = 1 - - -class Base3: - def case(self, value: Any) -> Iterable[Any]: - return [] - - -class Derived3(Base3): - @overload - def case(self, value: int) -> Iterable[int]: ... - - @overload - def case(self, value: float) -> Iterable[float]: ... - - def case(self, value: Any) -> Iterable[Any]: - return [] - - -class Base4: - def a(self) -> int: ... - - -class Base5: - def a(self) -> int: ... - - -class C(Base4, Base5): - # This should generate two error if reportIncompatibleMethodOverride - # is enabled. - def a(self) -> float: ... - - -class MyObject(TypedDict): - values: list[str] - - -class Base6(Generic["T"]): - def method1(self, v: int) -> None: ... - - def method2(self, v: T) -> None: ... - - def method3(self, v: T) -> None: ... - - def method4(self, v: S) -> S: ... - - def method5(self, v: S) -> S: ... - - -class Derived6(Base6[int], Generic["T"]): - # This should generate an error. - def method1(self, v: T): ... - - # This should generate an error. - def method2(self, v: T) -> None: ... - - def method3(self, v: int) -> None: ... - - def method4(self, v: T) -> T: ... - - def method5(self, v: S) -> S: ... - - -class Base7(Generic[T]): - def method1(self, x: T) -> T: - return x - - -class Derived7_1(Base7[T]): - # This should generate an error. - def method1(self, x: S) -> S: - return x - - -class Derived7_2(Base7[int]): - def method1(self, x: U) -> U: - return x - - -class Base8[T]: - def method1(self, x: T) -> T: ... - - -class Derived8[T](Base8[T]): - # This should generate an error. - def method1[U: str](self, x: U) -> U: ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride2.py b/packages/vipeye-internal/src/tests/samples/methodOverride2.py deleted file mode 100644 index a557a44a..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride2.py +++ /dev/null @@ -1,94 +0,0 @@ -# This sample tests the reportIncompatibleMethodOverride -# diagnostic check. - - -from typing import Any, Generic, ParamSpec, Self, TypeVar - - -class Base1: - def f1(self, *, kwarg0: int) -> None: ... - - def f2(self, *, kwarg0: int) -> None: ... - - def f3(self, *, kwarg0: int) -> None: ... - - def f4(self, *, kwarg0: int) -> None: ... - - def g1(self, a: int, /, b: str, *, kwarg0: int) -> None: ... - - def g2(self, a: int, /, b: str, *, kwarg0: int) -> None: ... - - def g3(self, a: int, /, b: str, *, kwarg0: int) -> None: ... - - def g4(self, a: int, /, b: str, *, kwarg0: int) -> None: ... - - def g5(self, a: int, /, b: str, *, kwarg0: int) -> None: ... - - def g6(self, a: int, /, b: str, *, kwarg0: int) -> None: ... - - def h1(self, a: int, *args: int) -> None: ... - - -class Derived1(Base1): - def f1(self, arg0: int = 0, *, kwarg0: int, kwarg1: int = 0) -> None: ... - - # This should generate an error because of a positional parameter mismatch. - def f2(self, arg0: int, *, kwarg0: int, kwarg1: int = 0) -> None: ... - - # This should generate an error because of a missing kwarg1. - def f3(self, arg0: int = 0, *, kwarg0: int, kwarg1: int) -> None: ... - - # This should generate an error because kwarg0 is the wrong type. - def f4(self, arg0: int = 0, *kwarg0: str) -> None: ... - - def g1(self, xxx: int, /, b: str, *, kwarg0: int) -> None: ... - - def g2(self, __a: int, b: str, *, kwarg0: int) -> None: ... - - # This should generate an error because of a name mismatch between b and c. - def g3(self, __a: int, c: str, *, kwarg0: int) -> None: ... - - # This should generate an error because of a type mismatch for b. - def g4(self, __a: int, b: int, *, kwarg0: int) -> None: ... - - def g5(self, __a: int, b: str = "hi", *, kwarg0: int) -> None: ... - - def g6(self, __a: int, b: str, c: str = "hi", *, kwarg0: int) -> None: ... - - -P = ParamSpec("P") -R = TypeVar("R") - - -class Base2(Generic[P, R]): - def method1(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - def method2(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -class Derived2(Base2[P, R]): - def method1(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - def method2(self, *args: Any, **kwargs: Any) -> R: ... - - -T = TypeVar("T") - - -class Base3: - def method1(self, x: Self) -> Self: ... - - def method2(self, x: Self) -> Self: ... - - def method3(self, x: Self) -> Self: ... - - -class Derived3(Generic[T], Base3): - # This should generate an error. - def method1(self, x: "Derived3[T]") -> "Derived3[T]": ... - - # This should generate an error. - def method2(self, x: "Derived3[int]") -> "Derived3[int]": ... - - # This should generate an error. - def method3(self, x: Self) -> Self: ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride3.py b/packages/vipeye-internal/src/tests/samples/methodOverride3.py deleted file mode 100644 index fa809c66..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride3.py +++ /dev/null @@ -1,199 +0,0 @@ -# This sample tests incompatible method overrides for multiple inheritance. -# This functionality is controlled by the reportIncompatibleMethodOverride -# diagnostic rule. - - -from typing import Generic, Iterable, ParamSpec, TypeVar, overload - - -class A1: - def func1(self, a: int) -> str: ... - - -class A2: - def func1(self, a: int, b: int = 3) -> str: ... - - -# This should generate an error because func1 is incompatible. -class ASub(A1, A2): ... - - -class B1: - def func1(self) -> int: ... - - -class B2: - def func1(self) -> float: ... - - -class BSub(B1, B2): ... - - -class C1: - def func1(self) -> float: ... - - -class C2: - def func1(self) -> int: ... - - -# This should generate an error because func1 is incompatible. -class CSub(C1, C2): ... - - -class D1: - def func1(self, a: int) -> None: ... - - -class D2: - def func1(self, b: int) -> None: ... - - -# This should generate an error because func1 is incompatible. -class DSub(D1, D2): ... - - -_T_E = TypeVar("_T_E") - - -class E1(Generic[_T_E]): - def func1(self, a: _T_E) -> None: ... - - -class E2(Generic[_T_E]): - def func1(self, a: _T_E) -> None: ... - - -class ESub(E1[int], E2[int]): ... - - -_T_F = TypeVar("_T_F") - - -class F1(Generic[_T_F]): - def do_stuff(self) -> Iterable[_T_F]: ... - - -class F2(F1[_T_F]): - def do_stuff(self) -> Iterable[_T_F]: ... - - -class F3(F1[_T_F]): ... - - -class FSub1(F3[int], F2[int]): - pass - - -class FSub2(F3[int], F1[int]): - pass - - -class FSub3(F2[int], F1[int]): - pass - - -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -class G1(Generic[_P, _R]): - def f(self, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... - - def g(self) -> _R: ... - - -class G2(G1[_P, _R]): - # This should generate an error because f is missing ParamSpec parameters. - def f(self) -> _R: ... - - def g(self, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... - - -class G3(G1[[], _R]): - def f(self) -> _R: ... - - def g(self) -> _R: ... - - -class G4(G1[[int, int], str]): - def f(self, a: int, b: int, /) -> str: ... - - def g(self) -> str: ... - - -class G5(G1[[], str]): - # This should generate an error because the specialized - # signature of f in the base class has no positional parameters. - def f(self, a: int, b: int) -> str: ... - - def g(self) -> str: ... - - -class H1: - @property - def prop1(self) -> int: - return 3 - - @property - def prop2(self) -> int: - return 3 - - @prop2.setter - def prop2(self, val: int) -> None: - pass - - @property - def prop3(self) -> int: - return 3 - - @prop3.setter - def prop3(self, val: int) -> None: - pass - - -class H2: - @property - def prop1(self) -> str: - return "" - - @property - def prop2(self) -> int: - return 3 - - @property - def prop3(self) -> int: - return 3 - - @prop3.setter - def prop3(self, val: str) -> None: - pass - - -# This should generate three errors: prop1, prop2 and prop3. -class H(H2, H1): ... - - -class I1: - @overload - def func1(self, x: int) -> int: ... - - @overload - def func1(self, x: str) -> str: ... - - def func1(self, x: int | str) -> int | str: - return x - - -class I2: - @overload - def func1(self, x: int) -> int: ... - - @overload - def func1(self, x: str) -> str: ... - - def func1(self, x: int | str) -> int | str: - return x - - -class I(I1, I2): ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride4.py b/packages/vipeye-internal/src/tests/samples/methodOverride4.py deleted file mode 100644 index 5392596f..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride4.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests the handling of methods that combine TypeVars -# from a class and local method TypeVars in an override. - -# viper: strict - -from abc import abstractmethod -from typing import Callable, Generic, TypeVar - -_TSource = TypeVar("_TSource") -_TResult = TypeVar("_TResult") - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") -_T3 = TypeVar("_T3") - - -class BaseA(Generic[_TSource]): - @abstractmethod - def method1( - self, mapper: Callable[[_TSource, _T1], _TResult], other: "BaseA[_T1]" - ) -> "BaseA[_TResult]": - raise NotImplementedError - - -class SubclassA1(BaseA[_TSource]): - def method1( - self, mapper: Callable[[_TSource, _T2], _TResult], other: BaseA[_T2] - ) -> BaseA[_TResult]: - return SubclassA2() - - -class SubclassA2(BaseA[_TSource]): - def method1( - self, mapper: Callable[[_TSource, _T3], _TResult], other: BaseA[_T3] - ) -> BaseA[_TResult]: - return SubclassA2() - - -class BaseB: - def f(self, v: str) -> str: ... - - -class SubclassB1(BaseB): - def f[T](self, v: T) -> T: ... - - -class BaseC: - def method1[T: BaseC](self, x: T) -> T: ... - - -class SubclassC(BaseC): - # This should generate an error because of the upper bound. - def method1[T: SubclassC](self, x: T) -> T: ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride5.py b/packages/vipeye-internal/src/tests/samples/methodOverride5.py deleted file mode 100644 index f95aadd4..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride5.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests an edge case where a base method uses an unpacked -# tuple or a specialized TypeVarTuple and is overridden by a method -# that supplies specific arguments. - -# viper: strict - -from typing import Generic, TypeVarTuple - -Ts = TypeVarTuple("Ts") - - -class Parent(Generic[*Ts]): - def method_1(self, *args: *Ts) -> None: ... - - def method_2(self, *args: *tuple[*Ts]) -> None: ... - - -class Child(Parent[int]): - def method_1(self, arg1: int) -> None: ... - - def method_2(self, arg1: int) -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride6.py b/packages/vipeye-internal/src/tests/samples/methodOverride6.py deleted file mode 100644 index 20b2bdbf..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride6.py +++ /dev/null @@ -1,240 +0,0 @@ -# This sample tests the case where a method is overriding an overloaded method. - -from typing import Any, Generic, Literal, TypeVar, overload - -_T = TypeVar("_T") - - -class Parent1(Generic[_T]): - @overload - def m1(self, x: Literal[True]) -> int: ... - - @overload - def m1(self, x: Literal[False]) -> float: ... - - @overload - def m1(self, x: _T) -> _T: ... - - def m1(self, x: bool | _T) -> int | float | _T: - return x - - -class Child1_1(Parent1[str]): - @overload - def m1(self, x: bool) -> int: ... - - @overload - def m1(self, x: str) -> str: ... - - def m1(self, x: bool | str) -> int | str: - return x - - -class Child1_2(Parent1[str]): - def m1(self, x: Any) -> Any: - return x - - -class Child1_3(Parent1[str]): - @overload - def m1(self, x: bool) -> int: ... - - @overload - def m1(self, x: str) -> str: ... - - def m1(self, x: bool | str) -> int | float | str: - return x - - -class Child1_4(Parent1[str]): - @overload - def m1(self, x: str) -> str: ... - - @overload - def m1(self, x: bool) -> int: ... - - # This should generate an error because the overloads are - # in the wrong order. - def m1(self, x: bool | str) -> int | float | str: - return x - - -class Child1_5(Parent1[str]): - @overload - def m1(self, x: Literal[True]) -> int: ... - - @overload - def m1(self, x: Literal[False]) -> float: ... - - @overload - def m1(self, x: bytes) -> bytes: ... - - # This should generate an error because the overloads are - # in the wrong order. - def m1(self, x: bool | bytes) -> int | float | bytes: - return x - - -class Child1_6(Parent1[bytes]): - @overload - def m1(self, x: Literal[True]) -> int: ... - - @overload - def m1(self, x: Literal[False]) -> float: ... - - @overload - def m1(self, x: bytes) -> bytes: ... - - def m1(self, x: bool | bytes) -> int | float | bytes: - return x - - -class Parent2(Generic[_T]): - @overload - def method1(self: "Parent2[int]", x: list[int]) -> list[int]: ... - - @overload - def method1(self, x: str) -> dict[str, str]: ... - - def method1(self, x: Any) -> Any: ... - - @overload - def method2(self: "Parent2[int]", x: list[int]) -> list[int]: ... - - @overload - def method2(self, x: str) -> dict[str, str]: ... - - @overload - def method2(self, x: int) -> int: ... - - def method2(self, x: Any) -> Any: ... - - @overload - @classmethod - def method3(cls: "type[Parent2[int]]", x: list[int]) -> list[int]: ... - - @overload - @classmethod - def method3(cls, x: str) -> dict[str, str]: ... - - @classmethod - def method3(cls, x: Any) -> Any: ... - - @overload - @classmethod - def method4(cls: "type[Parent2[int]]", x: list[int]) -> list[int]: ... - - @overload - @classmethod - def method4(cls, x: str) -> dict[str, str]: ... - - @overload - @classmethod - def method4(cls, x: int) -> int: ... - - @classmethod - def method4(cls, x: Any) -> Any: ... - - -class Child2_1(Parent2[str]): - def method1(self, x: str) -> dict[str, str]: ... - - -class Child2_2(Parent2[str]): - @overload - def method2(self, x: str) -> dict[str, str]: ... - - @overload - def method2(self, x: int) -> int: ... - - def method2(self, x: Any) -> Any: ... - - -class Child2_3(Parent2[str]): - @classmethod - def method3(cls, x: str) -> dict[str, str]: ... - - -class Child2_4(Parent2[str]): - @overload - @classmethod - def method4(cls, x: str) -> dict[str, str]: ... - - @overload - @classmethod - def method4(cls, x: int) -> int: ... - - @classmethod - def method4(cls, x: Any) -> Any: ... - - -class Parent3: - @overload - def method(self, x: int) -> int: ... - - @overload - def method(self, x: str) -> str: ... - - def method(self, x: int | str) -> int | str: - return x - - -class Child3_1(Parent3): - @overload - def method(self, x: int) -> int: ... - - @overload - def method(self, x: str) -> str: ... - - @overload - def method(self, x: list[float]) -> list[float]: ... - - def method(self, x: int | str | list[float]) -> int | str | list[float]: - return x - - -class Parent4(Generic[_T]): - @overload - def m1(self: "Parent4[int]", a: None) -> float: ... - - @overload - def m1(self: "Parent4[int]", a: int) -> float: ... - - @overload - def m1(self: "Parent4[float]", a: None) -> str: ... - - def m1(self, a: int | None = None) -> float | str: - raise NotImplementedError - - -class Child4_1(Parent4[int]): - @overload - def function(self: Parent4[int], a: None) -> float: ... - - @overload - def function(self: Parent4[int], a: int) -> float: ... - - def function(self, a: int | None = None) -> float: - return 0.0 - - -class Parent5: - @overload - def m1(self, x: int) -> int: ... - - @overload - def m1(self, x: str) -> str: ... - - def m1(self, x: int | str) -> int | str: ... - - -class Parent5_1(Parent5): - @overload - def m1(self, x: bytes) -> bytes: ... - - @overload - def m1(self, x: str) -> str: ... - - # This should generate an error because the overloads are - # incompatible - def m1(self, x: bytes | str) -> bytes | str: ... diff --git a/packages/vipeye-internal/src/tests/samples/methodOverride7.py b/packages/vipeye-internal/src/tests/samples/methodOverride7.py deleted file mode 100644 index 5f663912..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverride7.py +++ /dev/null @@ -1,116 +0,0 @@ -# This sample tests that overriding a class-level callable variable -# (which is not a method) with a method in a subclass is allowed. When -# the base member is a plain callable attribute rather than a method, -# the override method's "self" parameter is bound when accessed on an -# instance, so the signatures are compared as plain (bound) callables. - -from collections.abc import Callable -from typing import override - - -class A: - hello: Callable[[], None] = lambda: print("hello") - - cb: Callable[[int], None] = lambda x: print(x) - - ret: Callable[[], int] = lambda: 0 - - -class B(A): - @override - def hello(self) -> None: - print("hi") - - @override - def cb(self, value: int) -> None: - print(value) - - @override - def ret(self) -> int: - return 0 - - -class C(A): - # This should generate an error because the bound override adds a - # required positional parameter (arity mismatch). - @override - def hello(self, extra: int) -> None: - print("hi") - - -class D(A): - # This should generate an error because the bound override's first - # real parameter type (str) is incompatible with the base callable's - # parameter type (int). - @override - def cb(self, value: str) -> None: - print(value) - - -class E(A): - # This should generate an error because the bound override's return - # type (str) is incompatible with the base callable's return type (int). - @override - def ret(self) -> str: - return "" - - -from typing import overload - - -class F(A): - # This should generate an error because the bound override is an - # overloaded method whose first real parameter type (str) is incompatible - # with the base callable's parameter type (int). The static normalization - # of each bound overload ensures the first parameter is not skipped as - # "self". - @overload - def cb(self, value: str) -> None: ... - @overload - def cb(self, value: str, extra: int) -> None: ... - @override - def cb(self, value: str, extra: int = 0) -> None: - print(value) - - -# The following classes verify that inheriting a callable variable and a -# real method with the same name from two different base classes (a "diamond" -# of sorts) does not produce a spurious reportIncompatibleMethodOverride. Both -# inheritance orders are exercised. - - -class Mixin: - def hello(self) -> None: ... - - -class DiamondAB(A, Mixin): - pass - - -class DiamondBA(Mixin, A): - pass - - -# Parametered diamond: one base supplies a callable variable with a parameter -# and a sibling base supplies a method with a matching parameter. This is the -# load-bearing case for the multiple-inheritance bind-before-compare handling: -# without binding the method's "self", the comparison would see an extra -# positional parameter and emit a spurious error. Both inheritance orders are -# exercised and should produce no error. - - -class CallableVarBase: - cb: Callable[[int], None] = lambda x: print(x) - - -class MethodBase: - def cb(self, value: int) -> None: - print(value) - - -class DiamondParamVM(CallableVarBase, MethodBase): - pass - - -class DiamondParamMV(MethodBase, CallableVarBase): - pass diff --git a/packages/vipeye-internal/src/tests/samples/methodOverrideCallable1.py b/packages/vipeye-internal/src/tests/samples/methodOverrideCallable1.py deleted file mode 100644 index 864fba6a..00000000 --- a/packages/vipeye-internal/src/tests/samples/methodOverrideCallable1.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests overriding a Callable class attribute with an instance method. - -from collections.abc import Callable -from typing import override - - -class A: - hello: Callable[[], None] = lambda: print("hello") - - -class B(A): - @override - def hello(self) -> None: - print("hi") - - -b = B() -b.hello() diff --git a/packages/vipeye-internal/src/tests/samples/methods1.py b/packages/vipeye-internal/src/tests/samples/methods1.py deleted file mode 100644 index 4c24e9ba..00000000 --- a/packages/vipeye-internal/src/tests/samples/methods1.py +++ /dev/null @@ -1,115 +0,0 @@ -# This sample tests that instance methods, regardless of how they're -# defined or decorated, act like instance methods. - -from typing import Any, Callable, ClassVar, Concatenate, Generic, ParamSpec, TypeVar - -P = ParamSpec("P") -R = TypeVar("R") - - -def func1(self) -> None: - print("func1", f"{self=}") - - -def deco1(x: Callable[P, R]) -> Callable[P, R]: - return x - - -def deco2( - func: Callable[P, Any], -) -> Callable[[Callable[..., Any]], Callable[Concatenate["ClassA", P], None]]: - return lambda f: f # type: ignore - - -class Deco3(Generic[P, R]): - def __init__(self, func: Callable[P, R]): - self.func = func - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: - print("Deco3.__call__:", f"{self=}") - return self.func(*args, **kwargs) - - -class Deco4: - def __init__(self, func: Callable[..., Any]): - self.func = func - - def __call__(self) -> None: - print("Deco4.__call__:", f"{self=}") - - -class CallableA: - def __call__(self) -> None: - print("CallableA.__call__:", f"{self=}") - - -class DummyClass: - def __init__(self, a: str, b: float) -> None: - pass - - -def dummyFunc(a: str, b: float) -> None: - pass - - -class ClassA: - a: ClassVar[Callable[[Any], None]] = lambda self: None - - b1 = lambda self: None - b2: ClassVar = lambda self: None - - c1 = func1 - c2: ClassVar = func1 - - d1: CallableA = CallableA() - d2: ClassVar[CallableA] = CallableA() - - e1 = deco1(func1) - e2: ClassVar = deco1(func1) - - @deco1 - def f1(self) -> None: - print("f1:", f"{self=}") - - @Deco3 - def g1(self) -> None: - print("g1:", f"{self=}") - - @Deco4 - def h1(self) -> None: - print("h1:", f"{self=}") - - @deco2(DummyClass) - def i1(self, a: str, b: float) -> None: - print("i1:", f"{self=}") - - @deco2(dummyFunc) - def j1(self, a: str, b: float) -> None: - print("j1:", f"{self=}") - - -a = ClassA() - -a.a() - -a.b1() -a.b2() - -a.c1() -a.c2() - -a.d1() -a.d2() - -a.e1() -a.e2() - -a.f1() - -a.g1(a) - -a.h1() - -a.i1("", 0) - -a.j1("", 0) diff --git a/packages/vipeye-internal/src/tests/samples/missingSuper1.py b/packages/vipeye-internal/src/tests/samples/missingSuper1.py deleted file mode 100644 index cd45717d..00000000 --- a/packages/vipeye-internal/src/tests/samples/missingSuper1.py +++ /dev/null @@ -1,73 +0,0 @@ -# This sample tests the reportMissingSuperCall diagnostic check. - -from typing import final - - -class ParentA: - pass - - -class ParentB: - # This should generate an error because it's missing a super().__init__ call. - def __init__(self): - pass - - -class ParentBPrime(ParentB): - pass - - -class ParentC: - pass - - -@final -class ParentD: - def __init__(self): - pass - - def __init_subclass__(cls) -> None: - pass - - -class ChildA(ParentA, ParentB): - # This should generate an error. - def __init__(self): - pass - - # This should generate an error. - def __init_subclass__(cls) -> None: - pass - - -class ChildB(ParentA, ParentB): - def __init__(self): - super().__init__() - - -class ChildC1(ParentA, ParentB): - def __init__(self): - ParentB.__init__(self) - - -class ChildC2(ParentA, ParentB): - def __init__(self): - ParentA.__init__(self) - ParentB.__init__(self) - - -class ChildCPrime(ParentA, ParentBPrime, ParentC): - def __init__(self): - super(ParentBPrime).__init__() - - -class ChildD(ParentC): - # This should generate an error. - def __init__(self): - pass - - -@final -class ChildE(ParentC): - def __init__(self): - pass diff --git a/packages/vipeye-internal/src/tests/samples/missingTypeArg1.py b/packages/vipeye-internal/src/tests/samples/missingTypeArg1.py deleted file mode 100644 index 685a7f16..00000000 --- a/packages/vipeye-internal/src/tests/samples/missingTypeArg1.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample tests the reportMissingTypeArgument diagnostic rule. - -import collections -from typing import Generic, TypeVar - - -_T1 = TypeVar("_T1") - - -class Class1(Generic[_T1]): - pass - - -# This should generate an error when reportMissingTypeArgument is enabled. -class Class2(Class1): - pass - - -# This should generate an error when reportMissingTypeArgument is enabled. -_T2 = TypeVar("_T2", bound=Class1) - - -# This should generate an error when reportMissingTypeArgument is enabled. -var1: Class1 | None = None - - -GenericTypeAlias = Class1[_T1] | int - - -# This should generate an error when reportMissingTypeArgument is enabled. -var2: GenericTypeAlias | None = None - - -class Class3(Generic[_T1, _T2]): - pass - - -# This should generate an error regardless of whether reportMissingTypeArgument -# is enabled because this class requires two type arguments and this will -# generate a runtime exception. -a = Class3[int] - - -# This should generate an error when reportMissingTypeArgument is enabled. -def func1() -> collections.deque: ... - - -def func2(obj: object): - if isinstance(obj, Class1): - pass - if isinstance(obj, Class1 | Class2): - pass - - -class ClassA: - @staticmethod - def method1(data: int | str | dict[str, str]): - if isinstance(data, dict | str): - return data diff --git a/packages/vipeye-internal/src/tests/samples/module1.py b/packages/vipeye-internal/src/tests/samples/module1.py deleted file mode 100644 index d2ecb2ac..00000000 --- a/packages/vipeye-internal/src/tests/samples/module1.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that a module is treated as though it's derived -# from 'object' from the perspective of the type checker. - -import typing - - -def func1(a: object): - pass - - -func1(typing) - -dir(typing) diff --git a/packages/vipeye-internal/src/tests/samples/module2.py b/packages/vipeye-internal/src/tests/samples/module2.py deleted file mode 100644 index 2c87a96c..00000000 --- a/packages/vipeye-internal/src/tests/samples/module2.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests that a module is assignable -# to the built-in type "ModuleType". - -import typing -import importlib -from typing import Protocol -from types import ModuleType - -importlib.reload(typing) - - -def func1(a: ModuleType): - pass - - -func1(typing) - - -v1 = [importlib] -reveal_type(v1, expected_text="list[ModuleType]") - -v2 = {importlib: typing} -reveal_type(v2, expected_text="dict[ModuleType, ModuleType]") - -v3 = (importlib, typing) -reveal_type(v3, expected_text="tuple[ModuleType, ModuleType]") - - -class ModuleProto(Protocol): - def reload(self, module: ModuleType) -> ModuleType: ... - - -v4: ModuleProto = importlib -reveal_type(v4, expected_text='Module("importlib")') - -v5: tuple[ModuleProto] = (importlib,) -reveal_type(v5, expected_text='tuple[Module("importlib")]') - -v6: list[ModuleProto] = [importlib] -reveal_type(v6, expected_text="list[ModuleProto]") diff --git a/packages/vipeye-internal/src/tests/samples/module3.py b/packages/vipeye-internal/src/tests/samples/module3.py deleted file mode 100644 index 818d8d0c..00000000 --- a/packages/vipeye-internal/src/tests/samples/module3.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests accesses to standard attributes of a module. - -import datetime - -reveal_type(datetime.__name__, expected_text="str") -reveal_type(datetime.__loader__, expected_text="Any") -reveal_type(datetime.__package__, expected_text="str | None") -reveal_type(datetime.__spec__, expected_text="Any") -reveal_type(datetime.__path__, expected_text="MutableSequence[str]") -reveal_type(datetime.__file__, expected_text="str") -reveal_type(datetime.__cached__, expected_text="str") -reveal_type(datetime.__dict__, expected_text="dict[str, Any]") -reveal_type(datetime.__annotations__, expected_text="dict[str, Any]") -reveal_type(datetime.__builtins__, expected_text="Any") -reveal_type(datetime.__doc__, expected_text="str | None") diff --git a/packages/vipeye-internal/src/tests/samples/mro1.py b/packages/vipeye-internal/src/tests/samples/mro1.py deleted file mode 100644 index 8d23bc78..00000000 --- a/packages/vipeye-internal/src/tests/samples/mro1.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the type checker's ability to -# detect a bad MRO. - - -class A: - pass - - -class B(A): - pass - - -# This should generate an error because a valid -# MRO linearization isn't possible. -class C(A, B): - pass diff --git a/packages/vipeye-internal/src/tests/samples/mro2.py b/packages/vipeye-internal/src/tests/samples/mro2.py deleted file mode 100644 index 4ddb78f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/mro2.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests the type checker's handling -# of proper method resolution order (MRO). - -# viper: reportIncompatibleMethodOverride=false - - -class A: - def foo(self, v1: str): - return None - - def bar(self): - return None - - -class B(A): - def foo(self, v1: float): - return None - - -class C(A): - def foo(self, v1: A): - return None - - def bar(self, v1: float): - return None - - -class D(B, C): - pass - - -a = A() -a.foo("hello") - -b = B() -b.foo(3) - -c = C() -c.foo(a) - -d = D() -d.foo(3) - -# This should generate an error because -# the bar method from class C should be -# selected before the bar method from A. -d.bar() diff --git a/packages/vipeye-internal/src/tests/samples/mro3.py b/packages/vipeye-internal/src/tests/samples/mro3.py deleted file mode 100644 index 69425684..00000000 --- a/packages/vipeye-internal/src/tests/samples/mro3.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests a more complicated class hierarchy to ensure -# that the MRO calculation does not detect a conflict. - - -class Object: - pass - - -class QualifiedObject(Object): - pass - - -class DerivableObject(QualifiedObject): - pass - - -class SubclassableObject(Object): - pass - - -class InheritingObject(DerivableObject, SubclassableObject): - pass - - -class Source(QualifiedObject, SubclassableObject): - pass - - -class ObjectType(InheritingObject, Source): - pass diff --git a/packages/vipeye-internal/src/tests/samples/mro4.py b/packages/vipeye-internal/src/tests/samples/mro4.py deleted file mode 100644 index 224dc720..00000000 --- a/packages/vipeye-internal/src/tests/samples/mro4.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the special-case handling of Generic in a class -# hierarchy. The Generic class implementation in CPython has a method -# called __mro_entries__ that elides the Generic base class in cases -# where one or more subsequent base classes are specialized generic classes. - -from typing import Generic, TypeVar - -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -class Foo1(Generic[T1]): ... - - -class Foo2(Generic[T1]): ... - - -class Bar1(Generic[T1, T2], Foo1[T1], Foo2[T2]): ... - - -class Bar2(Generic[T1, T2], Foo1, Foo2[T2]): ... - - -# This should generate an error because a consistent MRO cannot be found. -class Bar3(Generic[T1, T2], Foo1, Foo2): ... diff --git a/packages/vipeye-internal/src/tests/samples/nameBinding1.py b/packages/vipeye-internal/src/tests/samples/nameBinding1.py deleted file mode 100644 index cb93aa4c..00000000 --- a/packages/vipeye-internal/src/tests/samples/nameBinding1.py +++ /dev/null @@ -1,48 +0,0 @@ -# Tests the type checker's handling of global and nonlocal keywords. - -global a - -a = 3 -f = 3 - -# This should generate an error because nonlocal bindings aren't -# allowed at the module level. -nonlocal b - - -def func1(): - global a - - -def func2(): - global c - - -def func3(): - a = 3 - # This should generate an error because a is assigned locally - # before its name binding is declared. - global a - - d = 3 - h = 3 - - def func3_1(): - nonlocal d - - h = 5 - - # This should generate an error because h is assigned - # locally before its name binding is declared. - nonlocal h - - global e - - # This should generate an error because f is not available - # in a nonlocal scope. - nonlocal f - - nonlocal g - - e = 4 - g = 10 diff --git a/packages/vipeye-internal/src/tests/samples/nameBinding2.py b/packages/vipeye-internal/src/tests/samples/nameBinding2.py deleted file mode 100644 index 2d3e2af9..00000000 --- a/packages/vipeye-internal/src/tests/samples/nameBinding2.py +++ /dev/null @@ -1,9 +0,0 @@ -# This test covers the case where a nonlocal reference -# is made to a symbol that doesn't exist in an outer -# scope but is then assigned to. - - -class Test: - def test(self): - nonlocal missing_symbol - missing_symbol = 4 diff --git a/packages/vipeye-internal/src/tests/samples/nameBinding3.py b/packages/vipeye-internal/src/tests/samples/nameBinding3.py deleted file mode 100644 index ef284456..00000000 --- a/packages/vipeye-internal/src/tests/samples/nameBinding3.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests nonlocal and global bindings -# with declared types. - -foo: int = 23 -baz: int = 23 - - -def func(): - foo: str = "Hi" - baz: str = "Hi" - - def func_1(): - global foo - - # This should generate an error because - # the global "foo" is typed as a str. - foo = "25" - - global bar - - bar: str = "Hi" - - nonlocal baz - - # This should generate an error because the - # nonlocal "baz" is typed as str. - baz = 25 - - func_1() - - -func() - -# This should generate an error because the -# type of "bar" is defined in func_1. -bar = 24 diff --git a/packages/vipeye-internal/src/tests/samples/nameBinding4.py b/packages/vipeye-internal/src/tests/samples/nameBinding4.py deleted file mode 100644 index 2aeb2d71..00000000 --- a/packages/vipeye-internal/src/tests/samples/nameBinding4.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the case where a symbol is imported within an -# inner scope but the target symbol has global binding. - - -def func1(): - global Enum - from enum import Enum - - -reveal_type(Enum, expected_text="type[Enum]") diff --git a/packages/vipeye-internal/src/tests/samples/nameBinding5.py b/packages/vipeye-internal/src/tests/samples/nameBinding5.py deleted file mode 100644 index 98f534b2..00000000 --- a/packages/vipeye-internal/src/tests/samples/nameBinding5.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests that unassigned variables within a class body -# are resolved to the global scope. - -a = 0 -b = 0 -c = 0 -d = 0 - - -def func_a() -> None: - a = "a" - - class A: - reveal_type(a, expected_text="Literal['a']") - - -def func_b() -> None: - b = "a" - - class A: - reveal_type(b, expected_text="int") - b = "b" - reveal_type(b, expected_text="str") - - reveal_type(b, expected_text="Literal['a']") - - -def func_c() -> None: - c = "a" - - class A: - nonlocal c - reveal_type(c, expected_text="Literal['a']") - c = 0 - - reveal_type(c, expected_text="int") - - -def func_d() -> None: - d = "a" - - class A: - global d - reveal_type(d, expected_text="int") - d = "b" - - reveal_type(d, expected_text="Literal['a']") - - -reveal_type(a, expected_text="Literal[0]") -reveal_type(b, expected_text="Literal[0]") -reveal_type(c, expected_text="Literal[0]") -reveal_type(d, expected_text="Literal[0]") diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple1.py b/packages/vipeye-internal/src/tests/samples/namedTuple1.py deleted file mode 100644 index df601a7e..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple1.py +++ /dev/null @@ -1,110 +0,0 @@ -# This sample tests the type checker's handling of named tuples. - -from collections import namedtuple -from typing import Final, NamedTuple - -NamedTuple1 = namedtuple("NamedTuple1", "field1 field2") -NamedTuple1(1, 2) -NamedTuple1(field2=1, field1=2) - -# This should generate an error because there -# is no field called field3. -NamedTuple1(field1=1, field2=3, field3=2) - -# This should generate an error because there -# should be two parameters. -NamedTuple1(1) - -# This should generate an error because there -# should be two parameters. -NamedTuple1(1, 2, 3) - -s1: tuple[float, float] = NamedTuple1(3, 4) - -# This should generate an error because there are not enough entries. -s2: tuple[float, float, float] = NamedTuple1(3, 4) - -NamedTuple2 = namedtuple("NamedTuple2", "field1, field2") -NamedTuple2.__new__.__defaults__ = ([],) -NamedTuple2() -NamedTuple2(1) - -NamedTuple2(field1=1, field2=3) - -# This should generate an error because there -# should be two or fewer parameters. -NamedTuple2(1, 2, 3) - -Field1: Final = "field1" -Field2: Final = "field2" - -NamedTuple3 = NamedTuple( - "NamedTuple3", - [ - (Field1, "str"), # 'str' should be treated as forward reference - (Field2, int), - ], -) -NamedTuple3("hello", 2) - -# This should generate an error because of a -# type mismatch. -NamedTuple3("1", "2") - -# This should generate an error because of a -# type mismatch. -NamedTuple3(field2=1, field1=2) - -t1: tuple[str, float] = NamedTuple3("hello", 2) - -# This should generate an error because the types are incompatible. -t2: tuple[float, float] = NamedTuple3("hello", 2) - -# This should generate an error because the lengths are incompatible. -t3: tuple[str, float, str] = NamedTuple3("hello", 2) - -t4: NamedTuple = NamedTuple3("hello", 2) - -NamedTuple4 = namedtuple("NamedTuple4", "field1 field2 field3", defaults=(1, 2)) - -# This should generate an error (too few params) -NamedTuple4() -NamedTuple4(1) -NamedTuple4(1, 2, 3) -# This should generate an error (too many params) -NamedTuple4(1, 2, 3, 4) - -NamedTuple5 = namedtuple( - "NamedTuple5", "field1 field2 field3", defaults=(1, 2, 3, 4, 5) -) -NamedTuple5() - -NamedTuple6 = namedtuple("NamedTuple6", "field1 field2 field3", defaults=[1, 2]) -NamedTuple6() - - -def func1(dyn_str: str): - NamedTuple7 = namedtuple("NamedTuple7", dyn_str) - - n = NamedTuple7() - a, b = n - reveal_type(a, expected_text="Any") - reveal_type(b, expected_text="Any") - - -def func2(): - NamedTuple8 = namedtuple("NamedTuple8", ("a", "b", "c")) - n1 = NamedTuple8(a=1, b=2, c=3) - - a, b, c = n1 - reveal_type(a, expected_text="Unknown") - reveal_type(b, expected_text="Unknown") - reveal_type(c, expected_text="Unknown") - - # This should generate an error. - n2 = NamedTuple8(a=1, b=2) - - -# This should generate an error because NamedTuple isn't allowed in isinstance. -if isinstance(1, NamedTuple): - pass diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple10.py b/packages/vipeye-internal/src/tests/samples/namedTuple10.py deleted file mode 100644 index a402d6b6..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple10.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests that a subclass of a named tuple doesn't override -# a read-only entry in the parent class. - -from typing import NamedTuple - - -class Point(NamedTuple): - x: int - y: int - - def f(self): - pass - - -class BadPointWithName(Point): - name: str - - # This should generate an error. - x: int - - def f(self): - pass diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple11.py b/packages/vipeye-internal/src/tests/samples/namedTuple11.py deleted file mode 100644 index 1a5faa34..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple11.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests that named tuple field names beginning with -# an underscore is flagged as an error. - -from collections import namedtuple -from typing import NamedTuple - -# This should generate an error because a field name starting with an -# underscore isn't allowed. -NT1 = namedtuple("NT1", ["_oops"]) - -# This should generate an error because a field name starting with an -# underscore isn't allowed. -NT2 = namedtuple("NT2", "a, b, _oops") - - -class NT3(NamedTuple): - # This should generate an error because a field name starting with an - # underscore isn't allowed. - _oops: int - - -NT4 = namedtuple("NT4", "a, b, _c", rename=True) diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple2.py b/packages/vipeye-internal/src/tests/samples/namedTuple2.py deleted file mode 100644 index b5b06cda..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple2.py +++ /dev/null @@ -1,56 +0,0 @@ -# This test validates that NamedTuple instances can be destructured -# and indexed to get to their constituent element types. - -from typing import NamedTuple - - -class MyDataClass(NamedTuple): - entry_1: str - entry_2: int - - -nt1 = MyDataClass("yes", 1) - -(a1, a2) = nt1 -a1_1: str = a1 -a2_1: int = a2 - -# These should generate an error because a1 and a2 are -# the wrong types. -a1_2: int = a1 -a2_2: str = a2 - - -b1 = nt1[0] -b2 = nt1[1] -b1_1: str = b1 -b2_1: int = b2 - -# These should generate an error because a1 and a2 are -# the wrong types. -b1_2: int = b1 -b2_2: str = b2 - - -MyNT = NamedTuple("MyNT", [("hi", int), ("bye", str)]) - -nt2 = MyNT(3, "yo") - -(c1, c2) = nt2 -c1_2: int = c1 -c2_2: str = c2 - -# These should generate an error because a1 and a2 are -# the wrong types. -c1_1: str = c1 -c2_1: int = c2 - -d1 = nt2[0] -d2 = nt2[1] -d1_2: int = d1 -d2_2: str = d2 - -# These should generate an error because a1 and a2 are -# the wrong types. -d1_1: str = d1 -d2_1: int = d2 diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple3.py b/packages/vipeye-internal/src/tests/samples/namedTuple3.py deleted file mode 100644 index f5afd328..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple3.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests that an attempt to use multiple inheritance -# with a NamedTuple will result in an error. - -from typing import Generic, NamedTuple, TypeVar - - -# This should generate an error. -class A(NamedTuple, object): - x: int - - -T = TypeVar("T") - - -class B(NamedTuple, Generic[T]): - x: int diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple4.py b/packages/vipeye-internal/src/tests/samples/namedTuple4.py deleted file mode 100644 index 2f6c7a3d..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple4.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a class derives from a named tuple. -# The synthesized __new__ method should be able to handle this. - -from collections import namedtuple -from typing import NamedTuple - - -Class1 = namedtuple("Class1", "name") - - -class Class2(Class1): - some_class_member = 1 - - -reveal_type(Class2(name="a"), expected_text="Class2") - -Class3 = NamedTuple("Class3", [("name", str)]) - - -class Class4(Class3): - some_class_member = 1 - - -reveal_type(Class4(name="a"), expected_text="Class4") diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple5.py b/packages/vipeye-internal/src/tests/samples/namedTuple5.py deleted file mode 100644 index a3d6ffb0..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple5.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a NamedTuple object is referenced -# through a `self` parameter. - -from typing import NamedTuple - - -class Fruit(NamedTuple): - name: str - cost: float - - def new_cost(self, new_cost: float): - my_name, my_cost = self - reveal_type(my_name, expected_text="str") - reveal_type(my_cost, expected_text="float") - return Fruit(my_name, new_cost) diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple6.py b/packages/vipeye-internal/src/tests/samples/namedTuple6.py deleted file mode 100644 index d30861f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple6.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests that writes to named attributes within a named -# tuple class are flagged as errors. - -from collections import namedtuple -from typing import NamedTuple - - -class NT1(NamedTuple): - val1: str - val2: int - - -nt1 = NT1("x", 0) - -# This should generate an error. -nt1.val1 = "" - -# This should generate an error. -nt1[0] = "" - -# This should generate an error. -del nt1.val1 - -# This should generate an error. -del nt1[0] - -NT2 = NamedTuple("NT2", [("val1", str), ("val2", int)]) - -nt2 = NT2("x", 0) - -# This should generate an error. -nt2.val2 = 3 - -NT3 = namedtuple("NT3", ["val1", "val2"]) - -nt3 = NT3("x", 0) - -# This should generate an error. -nt3.val1 = "" diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple7.py b/packages/vipeye-internal/src/tests/samples/namedTuple7.py deleted file mode 100644 index 96337680..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple7.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the handling of NamedTuple classes with generics, -# which is supported in Python 3.11 and newer. - -from typing import Generic, NamedTuple, TypeVar - - -_T1 = TypeVar("_T1") - - -class NT1(NamedTuple, Generic[_T1]): - a: _T1 - b: int - c: list[_T1] - - -reveal_type(NT1(3, 4, []), expected_text="NT1[int]") -reveal_type(NT1(3.4, 4, [1, 2]), expected_text="NT1[float]") -reveal_type(NT1(3.4, 4, [2j]), expected_text="NT1[complex]") - - -class NT2(NT1[str]): ... - - -reveal_type(NT2("", 4, []), expected_text="NT2") - -# This should generate an error. -NT2(1, 4, []) diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple8.py b/packages/vipeye-internal/src/tests/samples/namedTuple8.py deleted file mode 100644 index 8f59415e..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple8.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where a NamedTuple class is generic. - -from typing import AnyStr, Generic, NamedTuple - - -class GenericNT(NamedTuple, Generic[AnyStr]): - scheme: AnyStr - - -class SpecializedNT(GenericNT[str]): - def geturl(self) -> str: ... - - -def func(x: SpecializedNT): - reveal_type(x.__iter__, expected_text="() -> Iterator[str]") - reveal_type(list(x), expected_text="list[str]") diff --git a/packages/vipeye-internal/src/tests/samples/namedTuple9.py b/packages/vipeye-internal/src/tests/samples/namedTuple9.py deleted file mode 100644 index fb18d1c2..00000000 --- a/packages/vipeye-internal/src/tests/samples/namedTuple9.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the detection of keywords in a named tuple -# definition and support for the "rename" parameter. - - -from collections import namedtuple -from typing import NamedTuple - - -# This should generate an error because "def" is a keyword. -NT1 = namedtuple("NT1", ["abc", "def"]) - -# This should generate an error because "class" is a keyword. -NT2 = namedtuple("NT2", ["abc", "class"], rename=False) - -NT3 = namedtuple("NT3", ["abc", "def"], rename=True) - -v3 = NT3(abc=0, _1=0) - -# This should generate an error because "def" is a keyword. -NT4 = NamedTuple("NT4", [("abc", int), ("def", int)]) - - -# These are soft keywords, so they shouldn't generate an error. -NT5 = namedtuple("NT5", ["type", "match"]) diff --git a/packages/vipeye-internal/src/tests/samples/never1.py b/packages/vipeye-internal/src/tests/samples/never1.py deleted file mode 100644 index 469fa21f..00000000 --- a/packages/vipeye-internal/src/tests/samples/never1.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the handling of the "Never" type, -# ensuring that it's treated as the same as NoReturn. - -from typing import NoReturn, TypeVar, Generic -from typing_extensions import Never # viper: ignore[reportMissingModuleSource] - -T = TypeVar("T") - - -class ClassA(Generic[T]): ... - - -def func1(val: ClassA[Never]): - # This should generate an error because - # the type parameter for ClassA is invariant. - x: ClassA[object] = val - - -def assert_never1(val: Never) -> NoReturn: - raise Exception("Should never get here") - - -def assert_never2(val: NoReturn) -> NoReturn: - raise Exception("Should never get here") - - -# This should generate an error because Never doesn't accept type arguments. -def assert_never3(val: Never[int]): ... - - -# This should generate an error because NoReturn doesn't accept type arguments. -def assert_never4(val: NoReturn[int]): ... - - -def func2(val: str | int) -> str: - if isinstance(val, (str, int)): - return "str or int" - else: - assert_never1(val) - - -def func3(val: str | int) -> str: - if isinstance(val, (str, int)): - return "str or int" - else: - assert_never2(val) - - -def func4(): - # This should generate an error because of the missing argument. - assert_never1() - - -reveal_type(assert_never1, expected_text="(val: Never) -> NoReturn") - -# This should generate an error. -assert_never1(1) diff --git a/packages/vipeye-internal/src/tests/samples/never2.py b/packages/vipeye-internal/src/tests/samples/never2.py deleted file mode 100644 index 93437bdd..00000000 --- a/packages/vipeye-internal/src/tests/samples/never2.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample validates that Never is treated as a bottom type for -# covariant type arguments. - -from typing import Generic, Never, TypeVar - -U = TypeVar("U") - -T_co = TypeVar("T_co", covariant=True) -T_contra = TypeVar("T_contra", contravariant=True) -T = TypeVar("T") - - -class ClassA(Generic[T_co]): - pass - - -def func1(x: U) -> ClassA[U]: - return ClassA[Never]() - - -class ClassB(Generic[T]): - pass - - -def func2(x: U) -> ClassB[U]: - # This should generate an error because T is invariant. - return ClassB[Never]() - - -class ClassC(Generic[T_contra]): - def __init__(self, x: T_contra): ... - - -def func3(x: U) -> U | ClassC[Never]: - return ClassC(x) diff --git a/packages/vipeye-internal/src/tests/samples/newType1.py b/packages/vipeye-internal/src/tests/samples/newType1.py deleted file mode 100644 index b9f06913..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType1.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests the type handler's handling of the -# built-in NewType function. - -from abc import ABC, abstractmethod -from typing import Any, NewType, TypeVar, TypedDict - -MyString = NewType("MyString", "str") - - -def must_take_string(p1: str): - pass - - -must_take_string(MyString("hello")) - - -def must_take_my_string(p1: MyString): - pass - - -must_take_my_string(MyString("hello")) - -# This should generate an error because 'hello' -# isn't a valid MyString. -must_take_my_string("hello") - - -_T = TypeVar("_T") - - -def func1(x: type[_T]) -> type[_T]: - return x - - -MyString2 = NewType("MyString2", func1(str)) - -# This should generate an error because NewType requires two arguments. -NewTypeBad1 = NewType() - -# This should generate an error because NewType requires two arguments. -NewTypeBad2 = NewType("NewTypeBad2") - -# This should generate an error because NewType requires two arguments. -NewTypeBad3 = NewType("NewTypeBad3", int, int) - -# This should generate an error because the first argument must be a string literal. -NewTypeBad4 = NewType(int, int) - -args = ("Hi", int) -# This should generate an error because two positional args are needed. -NewTypeBad5 = NewType(*args) - -# This should generate an error because type cannot be Any. -NewTypeBad6 = NewType("NewTypeBad6", Any) - - -class TD1(TypedDict): - x: int - - -# This should generate an error because type cannot be a TypedDict. -NewTypeBad7 = NewType("NewTypeBad7", TD1) - -NewTypeGood8 = NewType("NewTypeGood8", MyString) - -# This should generate an error because the name doesn't match. -NewTypeBad9 = NewType("NewTypeBad9Not", int) - - -def func2(x: MyString): - # This should generate two errors because isinstance can't be used - # with a NewType and it violates the isinstance siganture. - if isinstance(x, MyString): - pass - - # This should generate two errors because issubclass can't be used - # with a NewType and it violates the issubclass signature. - if issubclass(type(x), (MyString, int)): - pass - - -class AbstractBase(ABC): - @abstractmethod - def method1(self, /) -> int: ... - - -class DerivedBase(AbstractBase): - def method1(self, /) -> int: - return 0 - - -NewDerived = NewType("NewDerived", AbstractBase) -new_derived = NewDerived(DerivedBase()) diff --git a/packages/vipeye-internal/src/tests/samples/newType2.py b/packages/vipeye-internal/src/tests/samples/newType2.py deleted file mode 100644 index 27e99a47..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType2.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the special-case handle of the multi-parameter -# form of the built-in "type" call. - -# viper: strict - -X1 = type("X1", (object,), {}) -X2 = type("X2", (object,), {}) - - -class A(X1): ... - - -class B(X2, A): ... - - -# This should generate two errors (one for `__new__` and one for `__init__`) -# because the first arg is not a string. -X3 = type(34, (object,)) - -# This should generate two errors (one for `__new__` and one for `__init__`) -# because the second arg is not a tuple of class types. -X4 = type("X4", 34) - -# This should generate two errors (one for `__new__` and one for `__init__`) -# because the second arg is not a tuple of class types. -X5 = type("X5", (3,)) - - -X6 = type("", tuple({str}), {}) -X7 = type("", (float, str), {}) - - -class Meta1(type): ... - - -X8 = Meta1("X8", (list,), {}) -reveal_type(X8, expected_text="type[X8]") -reveal_type(type(X8), expected_text="type[type[X8]]") diff --git a/packages/vipeye-internal/src/tests/samples/newType3.py b/packages/vipeye-internal/src/tests/samples/newType3.py deleted file mode 100644 index 15a60a2a..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType3.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests that the type checker is properly synthesizing -# a constructor for a NewType. - -from typing import NewType - - -UserId = NewType("UserId", int) - -# This should generate an error because the constructor -# requires a single int. -var1 = UserId() - -var2 = UserId(2) - -# This should generate an error because the constructor -# requires a single int. -var3 = UserId("2") - -# This should generate an error because the constructor -# requires a single int. -var4 = UserId(2, 3) - - -def require_user_id(a: UserId): ... - - -require_user_id(var2) - -# this should generate an error. -require_user_id(2) - -var5 = 4 + var2 -var6 = var2 * 2 diff --git a/packages/vipeye-internal/src/tests/samples/newType4.py b/packages/vipeye-internal/src/tests/samples/newType4.py deleted file mode 100644 index 583aa740..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType4.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests some error conditions for NewType usage. - -from typing import Annotated, Literal, NewType, Sized, Union - - -# This should generate an error. -A = NewType("A", Union[int, str]) - -# This should generate an error. -B = NewType("B", Literal[1]) - -# This should generate an error. -C = NewType("B", Sized) - -# This should generate an error. -D = NewType("A", int | str) - -AnnotatedInt = Annotated[int, ""] -# This should generate an error. -E = NewType("E", AnnotatedInt) diff --git a/packages/vipeye-internal/src/tests/samples/newType5.py b/packages/vipeye-internal/src/tests/samples/newType5.py deleted file mode 100644 index 6d98e447..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType5.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where an Any type is passed as the second -# argument to NewType. - -from typing import Any, NewType - -# This should generate an error. -A = NewType("A", Any) - - -def func(x: A) -> A: - x() - x(1, 2, 3) - - y: list[int] = [x, x()] - - return x diff --git a/packages/vipeye-internal/src/tests/samples/newType6.py b/packages/vipeye-internal/src/tests/samples/newType6.py deleted file mode 100644 index e4a65d44..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType6.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample ensures that types created with NewType are treated -# as though they're final and cannot be subclassed. The runtime -# enforces this. - -from typing import NewType - - -MyStr = NewType("MyStr", str) - - -# This should generate an error. -class A(MyStr): ... diff --git a/packages/vipeye-internal/src/tests/samples/newType7.py b/packages/vipeye-internal/src/tests/samples/newType7.py deleted file mode 100644 index 2de94f24..00000000 --- a/packages/vipeye-internal/src/tests/samples/newType7.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that classes created with NewType are treated -# as though they're functions at runtime. - -from typing import NewType - -MyStr = NewType("MyStr", str) - -# This should generate an error. -v1: type = MyStr - -# This should generate an error. -MyStr.capitalize - -MyStr.__name__ # OK - diff --git a/packages/vipeye-internal/src/tests/samples/newTypeIsLiteral1.py b/packages/vipeye-internal/src/tests/samples/newTypeIsLiteral1.py deleted file mode 100644 index e6c9c537..00000000 --- a/packages/vipeye-internal/src/tests/samples/newTypeIsLiteral1.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests `is` comparisons involving NewType instances. - -from types import EllipsisType, NoneType -from typing import NewType, reveal_type - -Apple = NewType("Apple", NoneType) -Apricot = NewType("Apricot", Apple) -Banana = NewType("Banana", bool) -Plantain = NewType("Plantain", Banana) -Cherry = NewType("Cherry", int) -Dragonfruit = NewType("Dragonfruit", EllipsisType) -Elderberry = NewType("Elderberry", Dragonfruit) - -# NewTypes over a non-singleton base that is merely compatible with the -# singleton (object accepts both None and ...). The negative branch must stay -# reachable rather than collapsing to Never. -Fig = NewType("Fig", object) -Guava = NewType("Guava", object) - - -def f(a: Apple, aa: Apricot, b: Banana, bb: Plantain, c: Cherry, d: Dragonfruit, dd: Elderberry) -> None: - if a is None: - reveal_type(a, expected_text="Apple") - - if aa is None: - reveal_type(aa, expected_text="Apricot") - - if b is True: - reveal_type(b, expected_text="Banana") - - if bb is True: - reveal_type(bb, expected_text="Plantain") - - if c is False: - reveal_type(c, expected_text="Cherry") - - if d is ...: - reveal_type(d, expected_text="Dragonfruit") - - if dd is ...: - reveal_type(dd, expected_text="Elderberry") - - -def g(o: Fig, e: Guava) -> None: - # A NewType over a non-singleton base (object) is not identity-equal to the - # singleton, so the negative branch must keep the NewType and stay reachable - # rather than collapsing to Never (a regression caught under reportUnreachable). - if o is not None: - reveal_type(o, expected_text="Fig") - - if e is not ...: - reveal_type(e, expected_text="Guava") - - -f( - Apple(None), - Apricot(Apple(None)), - Banana(True), - Plantain(Banana(True)), - Cherry(False), - Dragonfruit(...), - Elderberry(Dragonfruit(...)), -) - -g(Fig(object()), Guava(object())) diff --git a/packages/vipeye-internal/src/tests/samples/noTypeCheck1.py b/packages/vipeye-internal/src/tests/samples/noTypeCheck1.py deleted file mode 100644 index f82ea703..00000000 --- a/packages/vipeye-internal/src/tests/samples/noTypeCheck1.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the handling of the @no_type_check decorator. - - -from typing import no_type_check - - -@no_type_check -class A: - # This should generate an error because no_type_check has - # no effect when applied to a class. - x: int = "" - - -@no_type_check -def func1(a: int, b: int(), *args, c: int = 3) -> dummy: - x: int = "" - - -reveal_type( - func1, - expected_text="(a: Unknown, b: Unknown, *args: Unknown, c: Unknown = 3) -> Unknown", -) - - -# This should generate an error. -func1() - -func1("", "", c="") diff --git a/packages/vipeye-internal/src/tests/samples/none1.py b/packages/vipeye-internal/src/tests/samples/none1.py deleted file mode 100644 index 39383983..00000000 --- a/packages/vipeye-internal/src/tests/samples/none1.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests properties of the special NoneType. - -from typing import Hashable, Iterable - -a: Hashable = None - -# This should generate an error because None isn't iterable. -b: Iterable = None - -c = None -c.__class__ -c.__doc__ - - -def func1(a: int | None): - a.__class__ - a.__doc__ - - -def func2(x: type[None]): ... - - -func2(None.__class__) -func2(type(None)) - -reveal_type(type(None).__name__, expected_text="str") - -_ = type(None) == type(None) - -None.__eq__(0) diff --git a/packages/vipeye-internal/src/tests/samples/none2.py b/packages/vipeye-internal/src/tests/samples/none2.py deleted file mode 100644 index a92ad85b..00000000 --- a/packages/vipeye-internal/src/tests/samples/none2.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample checks that type[None] is handled correctly. - - -def func1(a: type[None]) -> type[str] | type[None]: - reveal_type(a, expected_text="type[None]") - - # This should generate an error because None is - # not compatible with Type[None]. - return None - - -val1 = func1(type(None)) - -if val1 is not None: - reveal_type(val1, expected_text="type[str] | type[None]") - -# This should generate an error because None isn't -# assignable to Type[None]. -val2 = func1(None) - -val3: type[object] = type(None) - -val4 = type(None)() -reveal_type(val4, expected_text="None") diff --git a/packages/vipeye-internal/src/tests/samples/noreturn1.py b/packages/vipeye-internal/src/tests/samples/noreturn1.py deleted file mode 100644 index bc5ffd77..00000000 --- a/packages/vipeye-internal/src/tests/samples/noreturn1.py +++ /dev/null @@ -1,92 +0,0 @@ -# This sample tests the type checker's handling of the NoReturn annotation type. - -from typing import Callable, NoReturn, overload - - -# This should generate an error because the function -# implicitly returns None. -def func1() -> NoReturn: - pass - - -def func2(x: bool) -> NoReturn: - if x: - # This should generate an error because the function - # explicitly returns a value. - return 4 - - raise Exception() - - -def func3() -> NoReturn: - raise Exception() - - -def func4(x: bool) -> str: - if x: - return "hello" - else: - func3() - - -def func5(x: bool) -> NoReturn: - if x: - # This should generate an error because the function - # explicitly yields a value. - yield 4 - - raise Exception() - - -x1: Callable[[bool], bool] = func2 - - -async def func6() -> NoReturn: ... - - -async def func7() -> NoReturn: - await func6() - - -class A: - def __new__(cls) -> NoReturn: ... - - -def func8() -> NoReturn: - A() - - -class C: - def __call__(self) -> NoReturn: ... - - -def func10() -> NoReturn: - C()() - - -@overload -def func11() -> NoReturn: ... - - -@overload -def func11(x: int) -> None: ... - - -def func11(x: int = 0) -> NoReturn | None: ... - - -def func12() -> NoReturn: - func11() - - -def func13() -> NoReturn: - # This should generate an error. - func11(0) - - -def func14(x: int) -> NoReturn: ... - - -def func15(): - # This should generate an error. - return func14() diff --git a/packages/vipeye-internal/src/tests/samples/noreturn2.py b/packages/vipeye-internal/src/tests/samples/noreturn2.py deleted file mode 100644 index ddf46897..00000000 --- a/packages/vipeye-internal/src/tests/samples/noreturn2.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests that the NoReturn logic is able to handle -# union types in call expressions. - -from typing import NoReturn - - -def func1() -> NoReturn: - raise TypeError - - -class B: - def always_noreturn(self) -> NoReturn: - func1() - - def sometimes_noreturn(self) -> NoReturn: - raise TypeError - - -class C: - def always_noreturn(self) -> NoReturn: - func1() - - def sometimes_noreturn(self) -> int: - return 0 - - -class A: - def __init__(self): - # Note the union type declaration here. - self._B_or_C: B | C = B() - - def m3(self) -> NoReturn: - self._B_or_C.always_noreturn() - - def m4(self) -> int: - x = self._B_or_C.sometimes_noreturn() - return x diff --git a/packages/vipeye-internal/src/tests/samples/noreturn3.py b/packages/vipeye-internal/src/tests/samples/noreturn3.py deleted file mode 100644 index 5b84e504..00000000 --- a/packages/vipeye-internal/src/tests/samples/noreturn3.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a local NoReturn call depends -# on the inferred type of a local variable. - -from typing import NoReturn - - -class MyClass: - def no_return(self) -> NoReturn: ... - - -def client_code() -> NoReturn: - instance = MyClass() - instance.no_return() diff --git a/packages/vipeye-internal/src/tests/samples/noreturn4.py b/packages/vipeye-internal/src/tests/samples/noreturn4.py deleted file mode 100644 index cbf79156..00000000 --- a/packages/vipeye-internal/src/tests/samples/noreturn4.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample verifies that a `NoReturn` type can be assigned -# to any other type. - -from typing import Callable, NoReturn, TypeVar - - -_T = TypeVar("_T", int, str) - - -def func1(x: Callable[[NoReturn], None]): ... - - -def func2(x: int) -> NoReturn: ... - - -def func3(x: _T) -> _T: - return x - - -def func4(x: NoReturn): - v1: object = x - v2: int = x - v3: str | int = x - v4: None = x - v5: Callable[[int, str], str] = x - func1(func2) - func3(x) diff --git a/packages/vipeye-internal/src/tests/samples/operator1.py b/packages/vipeye-internal/src/tests/samples/operator1.py deleted file mode 100644 index 383df18e..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator1.py +++ /dev/null @@ -1,119 +0,0 @@ -# This sample tests the type checker's ability to check -# custom operator overrides. - -# viper: reportIncompatibleMethodOverride=false - -from typing import NoReturn, Self - - -class A: - def __eq__(self, Foo): - return "equal" - - -class B: - def __ne__(self, Bar): - return self - - def __lt__(self, Bar): - return "string" - - def __gt__(self, Bar): - return "string" - - def __ge__(self, Bar): - return "string" - - def __le__(self, Bar): - return "string" - - -def needs_a_string(val: str): - pass - - -def needs_a_string_or_bool(val: bool | str): - pass - - -def test(): - a = A() - needs_a_string(a == a) - - # This should generate an error because there - # is no __ne__ operator defined, so a bool - # value will result. - needs_a_string(a != a) - - if True: - a = B() - - # At this point, a should be of type Union[Foo, Bar], - # so the == operator should return either a str or - # a bool. - needs_a_string_or_bool(a == a) - - # This should generate an error. - needs_a_string(a == a) - - # This should generate an error. - needs_a_string_or_bool(a != a) - - b = B() - needs_a_string(b < b) - needs_a_string(b > b) - needs_a_string(b <= b) - needs_a_string(b >= b) - - -class C: - def __getattr__(self, name: str, /): - if name == "__add__": - return lambda _: 0 - - -a = C() -a.__add__ - -# This should generate an error because __getattr__ is not used -# when looking up operator overload methods. -b = a + 0 - - -class D: - def __init__(self): - self.__add__ = lambda x: x - - -d = D() - -# This should generate an error because __add__ is not a class variable. -_ = d + d - - -class E: - __slots__ = ("__add__",) - - def __init__(self): - self.__add__ = lambda x: x - - -e = E() - -_ = e + e - - -class F: - def __add__(self, other: object) -> NoReturn: ... - - -f = F() + "" -reveal_type(f, expected_text="NoReturn") - - -class G: - def __add__(self, other: int) -> Self: - return self - - def method1(self) -> Self: - return self + 0 diff --git a/packages/vipeye-internal/src/tests/samples/operator10.py b/packages/vipeye-internal/src/tests/samples/operator10.py deleted file mode 100644 index 016ab534..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator10.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where an operator (__or__) cannot be -# properly evaluated when using bidirectional type inference but -# can be without. - -from typing import Iterable - - -def func(a: set[int], b: set[str]): - x1: Iterable[int | str] = a | a - - x2: set[int] = a | a - - # This should generate an error - x3: set[int | str] = a | a - - x4: set[int | str] = a | b diff --git a/packages/vipeye-internal/src/tests/samples/operator11.py b/packages/vipeye-internal/src/tests/samples/operator11.py deleted file mode 100644 index ead436ec..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator11.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the case where an operator overload method is -# defined as a callable protocol object. - -from typing import Protocol - - -class ComparisonOp(Protocol): - def __call__(self, other: object, /) -> bool: ... - - -class Number: - __lt__: ComparisonOp - __le__: ComparisonOp - __gt__: ComparisonOp - __ge__: ComparisonOp - - -n1 = Number() -n2 = Number() - -v1 = n1 < n2 -v2 = n1 >= n2 -v2 = n1 > n2 diff --git a/packages/vipeye-internal/src/tests/samples/operator12.py b/packages/vipeye-internal/src/tests/samples/operator12.py deleted file mode 100644 index 35812d50..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator12.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the handling of operators when used with constrained -# type variables. - -from typing import Generic, TypeVar - -T = TypeVar("T", int, float) - - -class A(Generic[T]): - def __init__(self, x: T): - self.x: T = x - - def __neg__(self) -> "A[T]": - return A[T](x=-self.x) diff --git a/packages/vipeye-internal/src/tests/samples/operator2.py b/packages/vipeye-internal/src/tests/samples/operator2.py deleted file mode 100644 index 322d991b..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator2.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the type checker's handling of chained -# comparison operators. - -from datetime import datetime - - -def requires_bool(val: bool): - pass - - -date1 = datetime.now() -date2 = datetime.now() -date3 = datetime.now() - -foo1 = date1 < date2 <= date3 -requires_bool(foo1) - -int1 = 3 -foo2 = 2 < int1 < 5 -requires_bool(foo2) - -# This should generate an error because -# int and datetime cannot be compared. -foo3 = date1 < date2 < 3 - -foo4 = (date1 < date2) < 3 - -foo5 = "1" == "1" in "1" - -foo6 = "1" in "1" == "1" diff --git a/packages/vipeye-internal/src/tests/samples/operator3.py b/packages/vipeye-internal/src/tests/samples/operator3.py deleted file mode 100644 index 07c58341..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator3.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the handling of the "or" and "and" operators -# when used with bidirectional type inference. - - -from typing import Any, TypeVar, overload - -_T = TypeVar("_T", bound=str) - - -@overload -def func1(cmd: _T) -> _T: ... - - -@overload -def func1(cmd: bytes) -> None: ... - - -def func1(cmd: Any) -> Any: ... - - -def func2(x: bool): - y = x or func1("") - reveal_type(y, expected_text="str | Literal[True]") - - -def func3(x: list[str]): - y = x or [] - reveal_type(y, expected_text="list[str]") - - -def func4(x: set[str]): - y = x or [] - reveal_type(y, expected_text="set[str] | list[Any]") - - -def identity(v: _T) -> _T: - return v - - -def func5(x: int): - v = x and identity("") - reveal_type(v, expected_text="str | Literal[0]") diff --git a/packages/vipeye-internal/src/tests/samples/operator4.py b/packages/vipeye-internal/src/tests/samples/operator4.py deleted file mode 100644 index 0f31ee54..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator4.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests operator overloads for matrix multiply operations. - - -class A: - pass - - -class B: - def __rmul__(self, a: A): - pass - - def __rmatmul__(self, a: A): - pass - - def __matmul__(self, a: A): - pass - - -a, b = A(), B() - -v1 = a @ b -v2 = b @ a diff --git a/packages/vipeye-internal/src/tests/samples/operator5.py b/packages/vipeye-internal/src/tests/samples/operator5.py deleted file mode 100644 index 2e895206..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator5.py +++ /dev/null @@ -1,5 +0,0 @@ -# This sample tests the parsing of the deprecated <> operator. - -# This should generate a single error, not a cascade of errors. -if 3 <> 5: - print("OK") diff --git a/packages/vipeye-internal/src/tests/samples/operator6.py b/packages/vipeye-internal/src/tests/samples/operator6.py deleted file mode 100644 index eb07d2ce..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator6.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests whether metaclasses that support operator -# magic methods work correctly. - -import ctypes - -v1 = ctypes.POINTER(ctypes.c_bool) * 3 -reveal_type(v1, expected_text="type[Array[_Pointer[c_bool]]]") - -v2 = 3 * ctypes.POINTER(ctypes.c_bool) -reveal_type(v2, expected_text="type[Array[_Pointer[c_bool]]]") diff --git a/packages/vipeye-internal/src/tests/samples/operator7.py b/packages/vipeye-internal/src/tests/samples/operator7.py deleted file mode 100644 index f88239a4..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator7.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the handling of binary operators when used with -# generic types. - -from typing import TypeVar - -_TInt = TypeVar("_TInt", bound=int) - - -def func1(n: _TInt) -> _TInt: - x = n + 1 - reveal_type(x, expected_text="int") - - # This should generate an error. - return x - - -_TIntOrStr = TypeVar("_TIntOrStr", int, str) - - -def func2(n: _TIntOrStr) -> _TIntOrStr: - x = n + n - reveal_type(x, expected_text="int* | str*") - - return x diff --git a/packages/vipeye-internal/src/tests/samples/operator8.py b/packages/vipeye-internal/src/tests/samples/operator8.py deleted file mode 100644 index 39901ce5..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator8.py +++ /dev/null @@ -1,261 +0,0 @@ -# This sample tests various "literal math" binary and unary operations that -# are applied when all operands are literal types with the same associated -# class. - -from functools import reduce -from typing import Iterable, Literal, TypeVar - -TLiteral = TypeVar("TLiteral", bound=Literal[0, 1, 2]) - - -def func1(a: Literal[1, 2], b: Literal[0, 4], c: Literal[3, 4]): - c1 = a * b + c - reveal_type(c1, expected_text="Literal[3, 4, 7, 8, 11, 12]") - - c2 = a // 0 - reveal_type(c2, expected_text="int") - - c3 = a % 0 - reveal_type(c3, expected_text="int") - - c4 = ((a * 1000) % 39) // c - reveal_type(c4, expected_text="Literal[8, 6, 3, 2]") - - c5 = a + True - reveal_type(c5, expected_text="int") - - c1 -= 5 - reveal_type(c1, expected_text="Literal[-2, -1, 2, 3, 6, 7]") - - c1 = -c1 - reveal_type(c1, expected_text="Literal[2, 1, -2, -3, -6, -7]") - - c1 = +c1 - reveal_type(c1, expected_text="Literal[2, 1, -2, -3, -6, -7]") - - c1 = ~c1 - reveal_type(c1, expected_text="Literal[-3, -2, 1, 2, 5, 6]") - - # Verify bitwise invert for a large int literal that doesn't fit in JS 32-bit - reveal_type(~2147483648, expected_text="Literal[-2147483649]") - - c1 = (-5 & 1) ^ (4 | 2) - reveal_type(c1, expected_text="Literal[7]") - - c1 = 1 << 128 - reveal_type(c1, expected_text="Literal[340282366920938463463374607431768211456]") - - c1 = 2**10 - reveal_type(c1, expected_text="Literal[1024]") - - c1 = (-1) ** 10 - reveal_type(c1, expected_text="Literal[1]") - - c1 = (2 - 3) ** 100001 - reveal_type(c1, expected_text="Literal[-1]") - - c1 = 2**100 - reveal_type(c1, expected_text="Literal[1267650600228229401496703205376]") - - c6 = 1 - for _ in range(100): - c6 += a - reveal_type(c6, expected_text="int") - - c7 = -10 // 8 - reveal_type(c7, expected_text="Literal[-2]") - - c8 = 10 // -6 - reveal_type(c8, expected_text="Literal[-2]") - - c9 = 0 // -6 - reveal_type(c9, expected_text="Literal[0]") - - c10 = 0 // 6 - reveal_type(c10, expected_text="Literal[0]") - - c11 = -6 // 6 - reveal_type(c11, expected_text="Literal[-1]") - - c12 = 6 // -6 - reveal_type(c12, expected_text="Literal[-1]") - - c13 = 6 // -3 - reveal_type(c13, expected_text="Literal[-2]") - - c14 = 256 // -16 - reveal_type(c14, expected_text="Literal[-16]") - - c20 = 1 << -1 - reveal_type(c20, expected_text="int") - - c21 = 1 >> -1 - reveal_type(c21, expected_text="int") - - c30 = -129 % 16 - reveal_type(c30, expected_text="Literal[15]") - - c31 = -129 % 32 - reveal_type(c31, expected_text="Literal[31]") - - c32 = -129 % 100 - reveal_type(c32, expected_text="Literal[71]") - - c33 = 256 % -32678 - reveal_type(c33, expected_text="Literal[-32422]") - - c34 = 256 % -129 - reveal_type(c34, expected_text="Literal[-2]") - - c35 = 0 % -1 - reveal_type(c35, expected_text="Literal[0]") - - c36 = -1 % -1 - reveal_type(c36, expected_text="Literal[0]") - - c37 = 1 % 1 - reveal_type(c37, expected_text="Literal[0]") - - c38 = -2 % 1 - reveal_type(c38, expected_text="Literal[0]") - - c39 = 4 % -2 - reveal_type(c39, expected_text="Literal[0]") - - -def func2(cond: bool): - c1 = "Hi " + ("Steve" if cond else "Amy") - reveal_type(c1, expected_text="Literal['Hi Steve', 'Hi Amy']") - - -def func3(cond: bool): - c1 = b"Hi " + (b"Steve" if cond else b"Amy") - reveal_type(c1, expected_text='Literal[b"Hi Steve", b"Hi Amy"]') - - -def func4(a: Literal[True], b: Literal[False]): - c1 = a and b - reveal_type(c1, expected_text="Literal[False]") - - c2 = a and a - reveal_type(c2, expected_text="Literal[True]") - - c3 = a or b - reveal_type(c3, expected_text="Literal[True]") - - c4 = not a - reveal_type(c4, expected_text="Literal[False]") - - c5 = not b - reveal_type(c5, expected_text="Literal[True]") - - c6 = not b and not a - reveal_type(c6, expected_text="Literal[False]") - - c7 = not b or not a - reveal_type(c7, expected_text="Literal[True]") - - c8 = b - reveal_type(c8, expected_text="Literal[False]") - while True: - c8 = not c8 - reveal_type(c8, expected_text="bool") - - -mode = Literal[ - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "z", - "y", - "z", -] - - -def func5( - a: mode, b: mode, c: mode, d: mode, e: mode, f: mode, g: mode, h: mode, i: mode -): - # Make sure this degenerate case falls back to "LiteralString". - reveal_type(a + b + c + d + e + f + g + h + i, expected_text="LiteralString") - - -def func6(x: Literal[1, 3, 5, 7, 11, 13]): - y = x - y *= x - - reveal_type( - y, - expected_text="Literal[1, 3, 5, 7, 11, 13, 9, 15, 21, 33, 39, 25, 35, 55, 65, 49, 77, 91, 121, 143, 169]", - ) - - y *= x - reveal_type(y, expected_text="int") - - -def func7(values: Iterable[str]) -> tuple[str, int]: - return reduce( - lambda x, value: (x[0] + value, x[1] + 1), - values, - ("", 0), - ) - - -def func8(values: Iterable[float]) -> float: - total, num_of_values = reduce( - lambda total_and_count, value: ( - total_and_count[0] + value, - total_and_count[1] + 1, - ), - values, - (0, 0), - ) - return total / num_of_values - - -def func9(a: int) -> None: - b = 0 - reveal_type(b, expected_text="Literal[0]") - - def inner1() -> None: - nonlocal b - b += 1 - reveal_type(b, expected_text="int") - b = b + 1 - - def inner2() -> None: - nonlocal b - b = b + 1 - reveal_type(b, expected_text="int") - - inner1() - inner2() - - -def func10(a: TLiteral) -> TLiteral: - # This should generate an error. - return -a - - -def func11(a: TLiteral, b: TLiteral) -> TLiteral: - # This should generate an error. - return a + b diff --git a/packages/vipeye-internal/src/tests/samples/operator9.py b/packages/vipeye-internal/src/tests/samples/operator9.py deleted file mode 100644 index ba639a3e..00000000 --- a/packages/vipeye-internal/src/tests/samples/operator9.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests bidirectional type inference for | operators. This -# should apply only to TypedDict types. - -from typing import Literal, TypeVar, Generic, Callable - -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -class S(Generic[T1]): - def __or__(self, other: "S[T2]") -> "S[T1 | T2]": ... - - -def to(x: Callable[..., T1]) -> "S[T1]": ... - - -x1 = to(int) | to(float) - - -def func1(f: set[Literal["A", "B"]]): - v1: set[Literal["A", "B"]] = f | f - - v2 = " ".join({"A"} | {"B"}) diff --git a/packages/vipeye-internal/src/tests/samples/optional1.py b/packages/vipeye-internal/src/tests/samples/optional1.py deleted file mode 100644 index 118ed7bf..00000000 --- a/packages/vipeye-internal/src/tests/samples/optional1.py +++ /dev/null @@ -1,87 +0,0 @@ -# This sample tests use of "Optional" types. - -from typing import Any, Optional - - -# An opaque condition to make variables Optional after `if`. -def cond() -> bool: ... - - -class Foo: - def __init__(self): - self.value = 3 - - def do_stuff(self): - pass - - def __enter__(self): - return 3 - - def __exit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -a = None -if cond(): - a = Foo() - -# If "reportOptionalMemberAccess" is enabled, -# this should generate an error. -a.value = 3 - - -def foo(): - pass - - -b = None -if cond(): - b = foo - -# If "reportOptionalCall" is enabled, -# this should generate an error. -b() - - -c = None -if cond(): - c = [3, 4, 5] - -# If "reportOptionalSubscript" is enabled, -# this should generate an error. -c[2] - - -# If "reportOptionalIterable" is enabled, -# this should generate an error. -for val in c: - pass - -# If "reportOptionalContextManager" is enabled, -# this should generate an error. -cm = None -if cond(): - cm = Foo() -with cm as val: - pass - -e = None -if cond(): - e = 4 - -# If "reportOptionalOperand" is enabled, -# this should generate an error. -v1 = e + 4 - -# If "reportOptionalOperand" is enabled, -# this should generate an error. -v2 = e < 5 - -# If "reportOptionalOperand" is enabled, -# this should generate an error. -v3 = ~e diff --git a/packages/vipeye-internal/src/tests/samples/optional2.py b/packages/vipeye-internal/src/tests/samples/optional2.py deleted file mode 100644 index 0a8d552e..00000000 --- a/packages/vipeye-internal/src/tests/samples/optional2.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample verifies that the reportOptionalOperand diagnostic -# isn't generated when the RHS operand accepts None. - -# viper: reportIncompatibleMethodOverride=false - -from typing import Optional - - -class Cmp: - def __eq__(self, other: "Optional[Cmp]") -> bool: ... - - def __lt__(self, other: "Optional[Cmp]") -> bool: ... - - def __gt__(self, other: "Cmp") -> bool: ... - - -def valid(value: Optional[Cmp], needed: Cmp): - x = value > needed - y = value == needed - - # This should generate an error if reportOptionalOperand is enabled. - z = value < needed diff --git a/packages/vipeye-internal/src/tests/samples/overload1.py b/packages/vipeye-internal/src/tests/samples/overload1.py deleted file mode 100644 index fab26bfa..00000000 --- a/packages/vipeye-internal/src/tests/samples/overload1.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample verifies that the type checker doesn't use the -# final function that omits the @overload decorator when matching -# a caller against an overloaded function. - -from typing import TypeVar, overload - -T = TypeVar("T") - - -@overload -def mouse_event(x1: int, y1: int) -> int: ... - - -@overload -def mouse_event(x1: int, y1: int, x2: int, y2: int) -> tuple[int, int]: ... - - -def mouse_event( - x1: int, y1: int, x2: int | None = None, y2: int | None = None -) -> int | tuple[int, int]: - return 1 - - -# This should generate an error because it doesn't match either -# of the @overload versions, even though it does match the -# version of the function that omits the @overload. -t = mouse_event(1, 2, 3) diff --git a/packages/vipeye-internal/src/tests/samples/overload2.py b/packages/vipeye-internal/src/tests/samples/overload2.py deleted file mode 100644 index dce67ec3..00000000 --- a/packages/vipeye-internal/src/tests/samples/overload2.py +++ /dev/null @@ -1,91 +0,0 @@ -# This sample verifies that a lone overload is reported -# as an error. - -from typing import Any, Callable, ParamSpec, Protocol, TypeVar, overload - -T = TypeVar("T") -P = ParamSpec("P") - - -# This should generate an error because there is only one overload. -@overload -def func1() -> None: ... - - -def func1() -> None: ... - - -# This should generate an error because there is only one overload. -@overload -def func2(a: int) -> None: ... - - -def func2(a: int) -> None: - pass - - -class ClassA: - # This should generate an error because there is no implementation. - @overload - def func3(self) -> None: ... - - @overload - def func3(self, a: int) -> None: ... - - -class ClassB(Protocol): - # An implementation should not be required in a protocol class. - @overload - def func4(self) -> None: ... - - @overload - def func4(self, name: str) -> str: ... - - -def deco1( - _origin: Callable[P, T], -) -> Callable[[Callable[..., Any]], Callable[P, T]]: ... - - -@overload -def func5(v: int) -> int: ... - - -@overload -def func5(v: str) -> str: ... - - -def func5(v: int | str) -> int | str: ... - - -@deco1(func5) -def func6(*args: Any, **kwargs: Any) -> Any: ... - - -@overload -def deco2() -> Callable[[Callable[P, T]], Callable[P, T | None]]: ... - - -@overload -def deco2( - x: Callable[[], T], -) -> Callable[[Callable[P, T]], Callable[P, T]]: ... - - -def deco2( - x: Callable[[], T | None] = lambda: None, -) -> Callable[[Callable[P, T]], Callable[P, T | None]]: ... - - -@deco2(x=dict) -def func7() -> dict[str, str]: - return {} - - -class ClassC[T]: - def __init__(self, _: T): ... - def __call__(self, a) -> T: ... - - -@ClassC(print) -def func8(a: int) -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/overload3.py b/packages/vipeye-internal/src/tests/samples/overload3.py deleted file mode 100644 index 055eaa10..00000000 --- a/packages/vipeye-internal/src/tests/samples/overload3.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests the reporting of inconsistent use of @classmethod -# and @staticmethod in overloads. - -from typing import Any, overload - - -class A: - @overload - # This should emit an error because @staticmethod is used inconsistently. - def method1(self, x: int) -> int: ... - - @overload - @staticmethod - def method1(x: str) -> str: ... - - def method1(*args: Any, **kwargs: Any) -> Any: - return - - @overload - @classmethod - # This should emit an error because @classmethod is used inconsistently. - def method2(cls, x: str) -> str: ... - - @overload - def method2(self, x: int) -> int: ... - - def method2(*args: Any, **kwargs: Any) -> Any: - return - - @overload - # This should emit an error because @staticmethod is used inconsistently. - def method3(self, x: str) -> str: ... - - @overload - def method3(self, x: int) -> int: ... - - @staticmethod - def method3(*args: Any, **kwargs: Any) -> Any: - return diff --git a/packages/vipeye-internal/src/tests/samples/overload4.py b/packages/vipeye-internal/src/tests/samples/overload4.py deleted file mode 100644 index cc842a62..00000000 --- a/packages/vipeye-internal/src/tests/samples/overload4.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests a complex overload case that was causing a hang -# in pyright's logic. - -from typing import Callable, overload - - -@overload -def func1[K, VI, VO](d: dict[K, VI], func: Callable[[VI], VO]) -> dict[K, VO]: ... - - -@overload -def func1[K, VI, VO](d: VI, func: Callable[[VI], VO]) -> VO: ... - - -def func1[K, VI, VO]( - d: dict[K, VI] | VI, func: Callable[[VI], VO] -) -> dict[K, VO] | VO: ... diff --git a/packages/vipeye-internal/src/tests/samples/overload5.py b/packages/vipeye-internal/src/tests/samples/overload5.py deleted file mode 100644 index b6faa721..00000000 --- a/packages/vipeye-internal/src/tests/samples/overload5.py +++ /dev/null @@ -1,60 +0,0 @@ -# This sample tests for proper usage of @final and @override within -# an overload definition. - -from typing import Any, Protocol, final, overload, override - - -class ABase: - def method2(self, x: int | str) -> int | str: ... - - -class A(ABase): - @final - @overload - # This should generate an error. - def method1(self, x: int) -> int: ... - - @final - @overload - # This should generate an error. - def method1(self, x: str) -> str: ... - - @final - def method1(self, x: int | str) -> int | str: ... - - @override - @overload - # This should generate an error. - def method2(self, x: int) -> int: ... - - @override - @overload - # This should generate an error. - def method2(self, x: str) -> str: ... - - @override - def method2(self, x: int | str) -> int | str: ... - - -class BBase(Protocol): - def method2(self, x: Any) -> Any: ... - - -class B(BBase, Protocol): - @final - @overload - def method1(self, x: int) -> int: ... - - @final - @overload - # This should generate an error. - def method1(self, x: str) -> str: ... - - @override - @overload - def method2(self, x: int) -> int: ... - - @override - @overload - # This should generate an error. - def method2(self, x: str) -> str: ... diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall1.py b/packages/vipeye-internal/src/tests/samples/overloadCall1.py deleted file mode 100644 index cbddb049..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall1.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests the type checker's handling of the overload decorator. - -from typing import overload -from datetime import datetime, timezone, timedelta - - -@overload -def func1(ts: int) -> datetime: ... - - -@overload -def func1(ts: None) -> None: ... - - -@overload -def func1(ts: complex): ... - - -def func1(ts: int | complex | None) -> datetime | None: - return ( - None - if not isinstance(ts, int) - else (datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(milliseconds=ts)) - ) - - -reveal_type(func1(2418049), expected_text="datetime") -reveal_type(func1(None), expected_text="None") -reveal_type(func1(3j), expected_text="Unknown") - - -@overload -def func2(x: int) -> int: ... - - -@overload -def func2(x: float) -> float: ... - - -def func2(x): - return x - - -reveal_type(func2(abs(0.0)), expected_text="float") diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall10.py b/packages/vipeye-internal/src/tests/samples/overloadCall10.py deleted file mode 100644 index c1115630..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall10.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests that overload matching for partially-overlapping overload -# signatures considers the "expected type" when using bidirectional type -# inference. - -from typing import Any, Generic, LiteralString, TypeVar, overload - - -T = TypeVar("T") - - -class A(Generic[T]): - @overload - def func1(self: "A[bool]", x: "A[bool]") -> list[LiteralString]: ... - - @overload - def func1(self, x: "A[str]") -> list[str]: ... - - def func1(self, x: "A[Any]") -> list[str] | list[LiteralString]: - return [] - - -def func2(a: A[bool], b: A[str]): - v1: list[LiteralString] = a.func1(a) - - # This should generate an error. - v2: list[str] = a.func1(a) - - # This should generate an error. - v3: list[LiteralString] = b.func1(b) - v4: list[str] = b.func1(b) diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall2.py b/packages/vipeye-internal/src/tests/samples/overloadCall2.py deleted file mode 100644 index 41886c79..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall2.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample verifies that overloads work in -# conjunction with async methods. - -from typing import overload - - -@overload -async def func(x: int) -> int: ... - - -@overload -async def func(x: str) -> str: ... - - -async def func(x) -> int | str: - if isinstance(x, int): - return 32 - else: - return "that" - - -async def test_function(): - v1 = await func("2") - reveal_type(v1, expected_text="str") - - v2 = await func(2) - reveal_type(v2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall3.py b/packages/vipeye-internal/src/tests/samples/overloadCall3.py deleted file mode 100644 index 37878c3f..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall3.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where an implementation of an overload uses -# a decorator that turns it into a non-function type. - -from functools import lru_cache -from typing import AnyStr, overload - - -@overload -def func1(url: str) -> str: ... - - -@overload -def func1(url: bytes) -> bytes: ... - - -@lru_cache() -def func1(url: AnyStr) -> str | bytes: ... - - -reveal_type(func1(""), expected_text="str") -reveal_type(func1(b""), expected_text="bytes") diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall4.py b/packages/vipeye-internal/src/tests/samples/overloadCall4.py deleted file mode 100644 index 1f1ed998..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall4.py +++ /dev/null @@ -1,284 +0,0 @@ -# This sample tests the expansion of argument types during overload matching. - - -from enum import Enum -from typing import AnyStr, Literal, TypeVar, overload - - -class A: ... - - -class B: ... - - -class C: ... - - -_T1 = TypeVar("_T1", bound=B) - - -@overload -def overloaded1(x: A) -> str: ... - - -@overload -def overloaded1(x: _T1) -> _T1: ... - - -def overloaded1(x: A | B) -> str | B: ... - - -def func1(a: A | B, b: A | B | C): - v1 = overloaded1(a) - reveal_type(v1, expected_text="str | B") - - # This should generate an error because C is not allowed - # for the first argument. - v2 = overloaded1(b) - - -class LargeEnum(Enum): - x00 = 0 - x01 = 0 - x02 = 0 - x03 = 0 - x04 = 0 - x05 = 0 - x06 = 0 - x07 = 0 - x08 = 0 - x09 = 0 - x10 = 0 - x11 = 0 - x12 = 0 - x13 = 0 - x14 = 0 - x15 = 0 - x16 = 0 - x17 = 0 - x18 = 0 - x19 = 0 - x20 = 0 - x21 = 0 - x22 = 0 - x23 = 0 - x24 = 0 - x25 = 0 - x26 = 0 - x27 = 0 - x28 = 0 - x29 = 0 - x30 = 0 - x31 = 0 - x32 = 0 - x33 = 0 - x34 = 0 - x35 = 0 - x36 = 0 - x37 = 0 - x38 = 0 - x39 = 0 - x40 = 0 - x41 = 0 - x42 = 0 - x43 = 0 - x44 = 0 - x45 = 0 - x46 = 0 - x47 = 0 - x48 = 0 - x49 = 0 - x50 = 0 - x51 = 0 - x52 = 0 - x53 = 0 - x54 = 0 - x55 = 0 - x56 = 0 - x57 = 0 - x58 = 0 - x59 = 0 - x60 = 0 - x61 = 0 - x62 = 0 - x63 = 0 - x64 = 0 - x65 = 0 - x66 = 0 - x67 = 0 - x68 = 0 - x69 = 0 - - -LargeUnion = ( - Literal[ - "a", - "b", - "c", - "d", - "e", - "f", - "g", - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - ] - | LargeEnum -) - - -@overload -def overloaded2(a: LargeUnion, b: Literal[2]) -> str: ... - - -@overload -def overloaded2(a: LargeUnion, b: Literal[3]) -> str: ... - - -@overload -def overloaded2(a: LargeUnion, b: Literal[4]) -> float: ... - - -@overload -def overloaded2(a: LargeUnion, b: Literal[9]) -> float: ... - - -@overload -def overloaded2(a: LargeUnion, b: Literal[10]) -> float: ... - - -def overloaded2(a: LargeUnion, b: LargeUnion | Literal[9, 10]) -> str | float: ... - - -def func2(a: LargeUnion, b: Literal[2, 3, 4], c: Literal[2, 3, 4, 9, 10] | LargeEnum): - v1 = overloaded2("a", 2) - reveal_type(v1, expected_text="str") - - v2 = overloaded2(a, b) - reveal_type(v2, expected_text="str | float") - - # This should generate an error because the expansion of union types - # will exceed the max number of expansions (256). - v3 = overloaded2(a, c) - reveal_type(v2, expected_text="str | float") - - -_T2 = TypeVar("_T2", str, bytes) - - -@overload -def overloaded3(x: str) -> str: ... - - -@overload -def overloaded3(x: bytes) -> bytes: ... - - -def overloaded3(x: str | bytes) -> str | bytes: ... - - -def func3(y: _T2): - overloaded3(y) - - -_T3 = TypeVar("_T3") - - -def func5(a: _T3) -> _T3: - return a - - -@overload -def overloaded4(b: str) -> str: ... - - -@overload -def overloaded4(b: int) -> int: ... - - -def overloaded4(b: str | int) -> str | int: ... - - -def func6(x: str | int) -> None: - y: str | int = overloaded4(func5(x)) - - -@overload -def overloaded5(pattern: AnyStr) -> AnyStr: ... - - -@overload -def overloaded5(pattern: int) -> int: ... - - -def overloaded5(pattern: AnyStr | int) -> AnyStr | int: - return 0 - - -def func7(a: str | bytes) -> str | bytes: - return overloaded5(a) - - -def func8(a: AnyStr | str | bytes) -> str | bytes: - return overloaded5(a) - - -class E(Enum): - A = "A" - B = "B" - - -@overload -def func9(v: Literal[E.A]) -> int: ... -@overload -def func9(v: Literal[E.B]) -> str: ... -@overload -def func9(v: bool) -> list[str]: ... - - -def func9(v: E | bool) -> int | str | list[str]: ... - - -def test9(a1: E | bool): - reveal_type(func9(a1), expected_text="int | str | list[str]") - - -@overload -def func10(v: Literal[True]) -> int: ... -@overload -def func10(v: Literal[False]) -> str: ... - - -def func10(v: bool) -> int | str: ... - - -def test10(a1: bool): - reveal_type(func10(a1), expected_text="int | str") - - -@overload -def func11(v: tuple[int, int]) -> int: ... - - -@overload -def func11(v: tuple[str, int]) -> str: ... - - -@overload -def func11(v: tuple[int, str]) -> int: ... - - -@overload -def func11(v: tuple[str, str]) -> str: ... - - -def func11(v: tuple[int | str, int | str]) -> int | str: ... - - -def test11(a1: tuple[int | str, int | str]): - reveal_type(func11(a1), expected_text="int | str") diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall5.py b/packages/vipeye-internal/src/tests/samples/overloadCall5.py deleted file mode 100644 index fb2730a2..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall5.py +++ /dev/null @@ -1,107 +0,0 @@ -# This sample tests an overload that provides a signature for -# a *args parameter. - - -from typing import Any, Iterable, Tuple, TypeVar, overload - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - - -# This should generate an error because this overload overlaps -# with the third one and returns a different type. -@overload -def func1(__iter1: Iterable[_T1]) -> Tuple[_T1]: ... - - -@overload -def func1(__iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> Tuple[_T1, _T2]: ... - - -@overload -def func1(*iterables: Iterable[_T1]) -> float: ... - - -def func1(*iterables: Iterable[_T1 | _T2]) -> Tuple[_T1 | _T2, ...] | float: ... - - -def test1(x: Iterable[int]): - v1 = func1(x) - reveal_type(v1, expected_text="Tuple[int]") - - v2 = func1(x, x) - reveal_type(v2, expected_text="Tuple[int, int]") - - y = [x, x, x, x] - - v3 = func1(*y) - reveal_type(v3, expected_text="float") - - z = (x, x) - - v4 = func1(*z) - reveal_type(v4, expected_text="Tuple[int, int]") - - -@overload -def func2() -> tuple[()]: ... - - -@overload -def func2(x: int, /) -> tuple[int]: ... - - -@overload -def func2(*x: int) -> tuple[int, ...]: ... - - -def func2(*x: int) -> tuple[int, ...]: - return x - - -reveal_type(func2(), expected_text="tuple[()]") -reveal_type(func2(1), expected_text="tuple[int]") -reveal_type(func2(1, 2), expected_text="tuple[int, ...]") -reveal_type(func2(*[1, 2, 3]), expected_text="tuple[int, ...]") - - -@overload -def func3(x: int, /) -> str: ... - - -@overload -def func3(x: int, y: int, /, *args: int) -> int: ... - - -def func3(*args: int) -> int | str: - return 1 - - -def test3(v: list[int]) -> None: - r = func3(*v) - reveal_type(r, expected_text="int") - - -def test4(v: list[tuple[int, str]]): - z1 = zip(*v) - reveal_type(z1, expected_text="zip[tuple[Any, ...]]") - - z2 = zip(v[0]) - reveal_type(z2, expected_text="zip[tuple[int | str]]") - - z3 = zip(v[0], v[1]) - reveal_type(z3, expected_text="zip[tuple[int | str, int | str]]") - - -@overload -def func4() -> tuple[()]: ... -@overload -def func4[T](**kwargs: T) -> tuple[T, ...]: ... -def func4(**kwargs: Any) -> tuple[Any, ...]: ... - - -def test5(): - v1 = func4(**{"a": 1}) - reveal_type(v1, expected_text="tuple[int, ...]") - v2 = func4() - reveal_type(v2, expected_text="tuple[()]") diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall6.py b/packages/vipeye-internal/src/tests/samples/overloadCall6.py deleted file mode 100644 index 388fc042..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall6.py +++ /dev/null @@ -1,321 +0,0 @@ -# This sample tests overload matching in cases where the match -# is ambiguous due to an Any or Unknown argument. - -# viper: reportMissingModuleSource=false - -from typing import Any, Generic, Literal, TypeVar, overload -from typing_extensions import LiteralString, TypeIs - -_T = TypeVar("_T") - - -@overload -def overload1(x: int, y: float) -> float: ... - - -@overload -def overload1(x: str, y: float) -> str: ... - - -def overload1(x: str | int, y: float) -> float | str: ... - - -def func1(a: Any): - v1 = overload1(1, 3.4) - reveal_type(v1, expected_text="float") - - v2 = overload1("", 3.4) - reveal_type(v2, expected_text="str") - - v3 = overload1(a, 3.4) - reveal_type(v3, expected_text="Unknown") - - v4 = overload1("", a) - reveal_type(v4, expected_text="str") - - -@overload -def overload2(x: int) -> Any: ... - - -@overload -def overload2(x: str) -> str: ... - - -def overload2(x: str | int) -> Any | str: ... - - -def func2(a: Any): - v1 = overload2("") - reveal_type(v1, expected_text="str") - - v2 = overload2(3) - reveal_type(v2, expected_text="Any") - - v3 = overload2(a) - reveal_type(v3, expected_text="Any") - - -@overload -def overload3(x: LiteralString) -> LiteralString: ... - - -@overload -def overload3(x: str) -> str: ... - - -def overload3(x: str) -> str: ... - - -def func3(a: Any, b: str): - v1 = overload3("") - reveal_type(v1, expected_text="LiteralString") - - v2 = overload3(b) - reveal_type(v2, expected_text="str") - - v3 = overload3(a) - reveal_type(v3, expected_text="str") - - -def func4(a: Any): - d = dict(a) - reveal_type(d, expected_text="dict[Any, Any]") - - -@overload -def overload4(x: str, *, flag: Literal[True]) -> int: ... - - -@overload -def overload4(x: str, *, flag: Literal[False] = ...) -> str: ... - - -@overload -def overload4(x: str, *, flag: bool = ...) -> int | str: ... - - -def overload4(x: str, *, flag: bool = False) -> int | str: ... - - -reveal_type(overload4("0"), expected_text="str") -reveal_type(overload4("0", flag=True), expected_text="int") -reveal_type(overload4("0", flag=False), expected_text="str") - - -def unknown_any() -> Any: ... - - -def func5(a: Any): - reveal_type(overload4(a, flag=False), expected_text="str") - reveal_type(overload4("0", flag=a), expected_text="Unknown") - - -@overload -def overload5(x: list[int]) -> list[int]: ... - - -@overload -def overload5(x: list[str]) -> list[str]: ... - - -def overload5(x: list[str] | list[int]) -> list[str] | list[int]: - return x - - -def func6(y: list[Any]): - reveal_type(overload5(y), expected_text="list[int]") - - -class ClassA(Generic[_T]): - @overload - def m1(self: "ClassA[int]") -> "ClassA[int]": ... - - @overload - def m1(self: "ClassA[str]") -> "ClassA[str]": ... - - def m1(self) -> "ClassA[Any]": - return self - - -def func7(a: ClassA[Any]): - reveal_type(a.m1(), expected_text="ClassA[int]") - - -class ClassB(Generic[_T]): - @overload - def m1(self: "ClassB[int]", obj: "int | ClassB[int]") -> "ClassB[int]": ... - - @overload - def m1(self: "ClassB[str]", obj: "str | ClassB[str]") -> "ClassB[str]": ... - - def m1(self, obj: Any) -> "ClassB[Any]": - return self - - -def func8(b: ClassB[Any]): - reveal_type(b.m1(b), expected_text="ClassB[int]") - - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - - -@overload -def overload6(a: _T1, /) -> tuple[_T1]: ... - - -@overload -def overload6(a: _T1, b: _T2, /) -> tuple[_T1, _T2]: ... - - -@overload -def overload6(*args: _T1) -> tuple[_T1, ...]: ... - - -def overload6(*args: Any) -> tuple[Any, ...]: - return tuple(args) - - -def func9(*args: int): - reveal_type(overload6(*args), expected_text="tuple[int, ...]") - - -@overload -def overload7(a: float = ..., *, b: Literal[True] = ...) -> float: ... - - -@overload -def overload7(a: float = ..., *, b: bool) -> str: ... - - -def overload7(a: float = 1.0, *, b: bool = True) -> float | str: ... - - -def func10(kwargs_dict: dict[Any, Any]): - reveal_type(overload7(**kwargs_dict), expected_text="Unknown") - - -def func11(kwargs_dict: dict[str, Any]): - reveal_type(overload7(**kwargs_dict), expected_text="Unknown") - - -def func12(kwargs_dict: dict[str, bool]): - reveal_type(overload7(**kwargs_dict), expected_text="str") - - -def func13(kwargs_dict: dict[str, Literal[True]]): - reveal_type(overload7(**kwargs_dict), expected_text="float") - - -def func14(): - reveal_type(overload7(), expected_text="float") - - -def func15(kwargs_dict: dict[str, str]): - # This should generate an error because str isn't a valid type for - # the b parameter. - overload7(1.0, **kwargs_dict) - - -@overload -def overload8(x: int = 3, **kwargs: int) -> int: ... - - -@overload -def overload8(**kwargs: str) -> str: ... - - -def overload8(*args, **kwargs) -> Any: - pass - - -def func16(a: dict[str, Any], i: int): - reveal_type(overload8(x=i, **a), expected_text="int") - reveal_type(overload8(**a), expected_text="Unknown") - - -@overload -def overload9(x: int, y: int) -> int: ... - - -@overload -def overload9(x: float, y: int, z: str) -> float: ... - - -@overload -def overload9(x: object, y: int, z: str, a: None) -> str: ... - - -def overload9(x, y, z="", a=None) -> Any: - pass - - -def func17(a: Any): - reveal_type(overload9(*a), expected_text="Unknown") - reveal_type(overload9(a, *a), expected_text="Unknown") - reveal_type(overload9(1, *a), expected_text="Unknown") - reveal_type(overload9(1.1, *a), expected_text="Unknown") - reveal_type(overload9("", *a), expected_text="str") - - -@overload -def overload10(x: list[int]) -> list[int]: ... - - -@overload -def overload10(x: list[Any]) -> list[Any]: ... - - -def overload10(x) -> Any: - pass - - -def func18(a: Any, b: list[Any], c: list[str], d: list[int]): - reveal_type(overload10(a), expected_text="list[int]") - reveal_type(overload10(b), expected_text="list[int]") - reveal_type(overload10(c), expected_text="list[Any]") - reveal_type(overload10(d), expected_text="list[int]") - - -class ClassC: - @overload - def method1(self, k: Literal["hi"], default: Any) -> float: ... - - @overload - def method1(self, k: str, default: _T) -> Any | _T: ... - - def method1(self, k: str, default: _T) -> Any | _T: ... - - -def func19(a: ClassC, b: list, c: Any): - my_list1: list = [] - v1 = a.method1("hi", my_list1) - reveal_type(v1, expected_text="float") - - v2 = a.method1("hi", b) - reveal_type(v2, expected_text="float") - - v3 = a.method1("hi", c) - reveal_type(v3, expected_text="float") - - my_list2: list[int] = [] - v1 = a.method1("hi", my_list2) - reveal_type(v1, expected_text="float") - - -@overload -def overload11(x: str) -> TypeIs[str]: ... - - -@overload -def overload11(x: int) -> TypeIs[int]: ... - - -def overload11(x: Any) -> Any: - return True - - -def func20(val: Any): - if overload11(val): - reveal_type(val, expected_text="Any") diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall7.py b/packages/vipeye-internal/src/tests/samples/overloadCall7.py deleted file mode 100644 index 989e3541..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall7.py +++ /dev/null @@ -1,5 +0,0 @@ -# This sample tests the case of nested overload resolution where the -# selected overload depends on bidirectional inference. - -l: list[str] = [] -"{s}".format(s="\n".join(sorted(l))) diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall8.py b/packages/vipeye-internal/src/tests/samples/overloadCall8.py deleted file mode 100644 index 005ef0dd..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall8.py +++ /dev/null @@ -1,9 +0,0 @@ -# This sample tests the case where the overloads have different -# parameter counts. This particular sample exposed a bug -# in pyright's logic at one point. - -import subprocess - - -def my_method(cmd, *args, **kwargs): - return subprocess.run(cmd, *args, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/overloadCall9.py b/packages/vipeye-internal/src/tests/samples/overloadCall9.py deleted file mode 100644 index 72207d3d..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadCall9.py +++ /dev/null @@ -1,131 +0,0 @@ -# This sample tests the handling of overloads with a ParamSpec. - -from typing import Callable, Concatenate, overload, TypeVar, ParamSpec - -P = ParamSpec("P") -R = TypeVar("R") - - -def callable1( - func: Callable[P, R], *args: P.args, **kwargs: P.kwargs -) -> Callable[[], R]: ... - - -@overload -def func1() -> None: ... - - -@overload -def func1(a: int) -> None: ... - - -def func1(a: int = 1) -> None: ... - - -callable1(func1) -callable1(func1, 1) -callable1(func1, a=1) - -# This should generate an error because none of the overloads -# captured by the ParamSpec match those arguments. -callable1(func1, 1, 2) - -# This should generate an error because none of the overloads -# captured by the ParamSpec match those arguments. -callable1(func1, b=2) - - -def callable2( - func: Callable[Concatenate[int, P], R], *args: P.args, **kwargs: P.kwargs -) -> Callable[[], R]: ... - - -@overload -def func2() -> None: ... - - -@overload -def func2(a: int) -> int: ... - - -@overload -def func2(a: int, b: str) -> str: ... - - -def func2(a: int = 1, b: str = "") -> None | int | str: ... - - -callable2(func2) -callable2(func2, "") -callable2(func2, b="") - -# This should generate an error because none of the overloads -# captured by the ParamSpec match those arguments. -callable2(func2, 1, "") - - -def callable3(func: Callable[P, R]) -> Callable[Concatenate[int, P], R]: ... - - -c3_2 = callable3(func2) -c3_2(1) -c3_2(1, a=1) -c3_2(1, 1, b="") - -# This should generate an error because none of the overloads -# match these arguments. -c3_2(1, "") - -# This should generate an error because none of the overloads -# match these arguments. -c3_2(1, 1, c="") - - -@overload -def func3(x: int) -> None: ... - - -@overload -def func3(x: str) -> None: ... - - -def func3(x) -> None: - pass - - -def callable4(func: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R: ... - - -callable4(func3, 1) -callable4(func3, x=1) -callable4(func3, "") -callable4(func3, x="") - -# This should generate an error. -callable4(func3, 1.0) - -# This should generate two errors because x is missing and y is unknown. -callable4(func3, y=1) - - -@overload -def func4(x: str) -> str: ... - - -@overload -def func4(x: int) -> int: ... - - -def func4(x: str | int): - return x - - -def callable5(f: Callable[P, R]): - def inner(*args: P.args, **kwargs: P.kwargs) -> list[R]: - return [f(*args, **kwargs)] - - return inner - - -callable5(func4)(0) -callable5(func4)("") diff --git a/packages/vipeye-internal/src/tests/samples/overloadImpl1.py b/packages/vipeye-internal/src/tests/samples/overloadImpl1.py deleted file mode 100644 index 13842efd..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadImpl1.py +++ /dev/null @@ -1,262 +0,0 @@ -# This sample tests the verification that overload implementation signatures -# are a superset of their associated overload signatures. - -from typing import ( - Any, - Awaitable, - Callable, - Generic, - Iterable, - Literal, - NoReturn, - TypeVar, - overload, -) - -T = TypeVar("T") - - -@overload -def func1(a: int) -> str: ... - - -@overload -def func1(a: str) -> int: ... - - -# This should generate two errors: -# The first is because of an incompatibility with overload 1 -# because the input parameter type is incompatible. -# This second is because of an incompatibility with overload 2 -# because the return type is incompatible. -def func1(a: str) -> str: - return a - - -@overload -def func2(a: int, b: str = ...) -> str: ... - - -@overload -def func2(a: None) -> str: ... - - -# This should generate an error because the parameter "b" is missing -# from the implementation but is required by overload 1. -def func2(a: int | None) -> str: ... - - -@overload -def func3(a: int, *, b: Literal["r"]) -> str: ... - - -@overload -def func3(a: int, *, b: Literal["b"]) -> bytes: ... - - -def func3(*args: Any, **kwargs: Any) -> Any: ... - - -@overload -def func4(a: None) -> None: ... - - -@overload -def func4(a: list[T]) -> T: ... - - -def func4(a: list[T] | None) -> T | None: ... - - -class ClassA: - @overload - def method4(self, a: None) -> None: ... - - @overload - def method4(self, a: list[T]) -> T: ... - - def method4(self, a: list[T] | None) -> T | None: ... - - -@overload -def func5(a: list[T]) -> T: ... - - -@overload -def func5(a: None) -> None: ... - - -# This should generate an error because list is not compatible with dict. -def func5(a: dict[Any, Any] | None) -> Any | None: ... - - -@overload -def func6(foo: int, /) -> int: ... - - -@overload -def func6(bar: str, /) -> int: ... - - -def func6(p0: int | str, /) -> int: - return 3 - - -class ClassB(Generic[T]): - @overload - def method1(self: "ClassB[None]") -> None: ... - - @overload - def method1(self, value: T) -> None: ... - - def method1(self, value: Any = None) -> None: ... - - -class ClassC: ... - - -class ClassD: ... - - -T_CD = TypeVar("T_CD", ClassC, ClassD) - - -@overload -def func7(cls: type[ClassC], var: int) -> ClassC: ... - - -@overload -def func7(cls: type[ClassD], var: str) -> ClassD: ... - - -def func7(cls: type[T_CD], var: int | str) -> T_CD: - return cls() - - -T_str = TypeVar("T_str", bound=str) - - -@overload -def func8(foo: int) -> int: ... - - -@overload -def func8(foo: T_str) -> tuple[T_str]: ... - - -def func8(foo: T_str | int) -> tuple[T_str] | int: ... - - -class ClassE: ... - - -T_E = TypeVar("T_E", bound=ClassE) - - -@overload -def func9() -> None: ... - - -@overload -def func9(bar: T_E) -> T_E: ... - - -def func9(bar: T_E | None = None) -> T_E | None: - raise NotImplementedError - - -T_int_str = TypeVar("T_int_str", int, str) - - -@overload -def func10(option: Literal["a"], var: str) -> str: ... - - -@overload -def func10(option: Literal["b"], var: int) -> str: ... - - -# This should generate an error. -def func10(option: Literal["a", "b"], var: T_int_str) -> T_int_str: ... - - -class ClassF: ... - - -T_F = TypeVar("T_F", bound=type[ClassF]) - - -@overload -def func11(var: T_F) -> T_F: ... - - -@overload -def func11(var: int) -> int: ... - - -def func11(var: T_F | int) -> T_F | int: ... - - -T7 = TypeVar("T7") -T8 = TypeVar("T8") -T9 = TypeVar("T9") - - -@overload -def func12( - func: Callable[[T7], T8], iterable: Iterable[T7], default_value: None = None, / -) -> Iterable[T8 | None]: ... - - -@overload -def func12( - func: Callable[[T7], T8], iterable: Iterable[T7], /, default_value: T9 -) -> Iterable[T8 | T9]: ... - - -def func12( - func: Callable[[T7], T8], - iterable: Iterable[T7], - /, - default_value: T9 = None, -) -> Iterable[T8 | T9]: ... - - -@overload -def func13(x: int) -> NoReturn: ... - - -@overload -def func13(x: str) -> str | NoReturn: ... - - -def func13(x: int | str) -> str: ... - - -class ClassG(Generic[T]): ... - - -@overload -def func14(target: Callable[..., Awaitable[T]]) -> ClassG[T]: ... - - -@overload -def func14(target: Callable[..., T]) -> ClassG[T]: ... - - -def func14( - target: Callable[..., Awaitable[T]] | Callable[..., T], -) -> ClassG[T]: ... - - -@overload -def func15(client_id: str, client_secret: str, /) -> None: ... - - -@overload -def func15(client_id: str, client_secret: str) -> None: ... - - -# This should generate an error because some of the keyword arguments are not present. -def func15(*creds: str) -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/overloadImpl2.py b/packages/vipeye-internal/src/tests/samples/overloadImpl2.py deleted file mode 100644 index ba69d207..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadImpl2.py +++ /dev/null @@ -1,146 +0,0 @@ -# This sample tests the verification that overload implementation signatures -# are a superset of their associated overload signatures. - -from typing import ( - Any, - Callable, - Generic, - Literal, - ParamSpec, - Protocol, - TypeVar, - TypeVarTuple, - overload, -) - - -T = TypeVar("T") -T_contra = TypeVar("T_contra", contravariant=True) -T_co = TypeVar("T_co", covariant=True) -TCall = TypeVar("TCall", bound=Callable[..., Any]) -R = TypeVar("R") -P = ParamSpec("P") -Ts = TypeVarTuple("Ts") - - -class ClassA(Protocol[T_co]): - _target_: str - - -class ClassB(ClassA[T_co], Protocol[T_co, P]): - def __init__(self, *args: P.args, **kwds: P.kwargs): ... - - -class ClassC(Protocol): - # This should generate a overlapping overload error. - @overload - def __call__( - self, - x: Callable[P, R], - *, - sig: Literal[True] = ..., - ) -> ClassB[type[R], P]: ... - - @overload - def __call__( - self, x: TCall, *, sig: Literal[False] = ... - ) -> ClassA[type[TCall]]: ... - - @overload - def __call__( - self, x: TCall | Callable[P, R], *, sig: bool - ) -> ClassA[type[TCall]] | ClassB[type[R], P]: ... - - def __call__( - self, x: TCall | Callable[P, R], *, sig: bool = False - ) -> ClassA[type[TCall]] | ClassB[type[R], P]: ... - - -Func = Callable[[*Ts], None] - - -@overload -def func1(function: Func[*Ts]) -> Func[*Ts]: ... - - -@overload -def func1() -> Callable[[Func[*Ts]], Func[*Ts]]: ... - - -def func1( - function: Func[*Ts] | None = None, -) -> Func[*Ts] | Callable[[Func[*Ts]], Func[*Ts]]: ... - - -@overload -def func2(d: dict[str, float], /) -> None: ... - - -@overload -def func2(**kwargs: float) -> None: ... - - -def func2(d: dict[str, float] | None = None, /, **kwargs: float) -> None: - pass - - -@overload -def func3(a: int) -> int: ... - - -@overload -def func3(*args: int) -> int: ... - - -# This should generate an error because the keyword parameter "a" is missing. -def func3(*args: int) -> int: ... - - -@overload -def func4(a: int) -> int: ... - - -@overload -def func4(*args: int) -> int: ... - - -def func4(*args: int, a: int = 1) -> int: ... - - -@overload -def func5(a: int) -> int: ... - - -@overload -def func5(*args: int) -> int: ... - - -def func5(*args: int, **kwargs: int) -> int: ... - - -@overload -def func6(x: tuple[()], /) -> None: ... - - -@overload -def func6(x: tuple[object], /) -> None: ... - - -def func6(x: tuple[object, ...], /) -> None: ... - - -class ClassD(Generic[T_contra]): - def method(self, x: T_contra) -> int: - assert False - - -@overload -def func7(x: None) -> int: ... - - -@overload -def func7(x: ClassD[T]) -> int: ... - - -def func7(x: ClassD[T] | None) -> int: - assert False diff --git a/packages/vipeye-internal/src/tests/samples/overloadImpl3.py b/packages/vipeye-internal/src/tests/samples/overloadImpl3.py deleted file mode 100644 index 639fbabe..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadImpl3.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests that the parameters of an overload implementation are not -# subject to the reportUnknownParameterType and reportMissingParameterType -# checks. The implementation signature is ignored by the type checker, so its -# parameters are allowed to remain unannotated. - -# viper: strict - -from typing import overload - - -class Foo: - @overload - def foo(self, value: int) -> int: ... - - @overload - def foo(self, value: str) -> str: ... - - # The unannotated "value" parameter should not generate errors here. - def foo(self, value) -> int | str: - return 0 - - -@overload -def func1(value: int) -> int: ... - - -@overload -def func1(value: str) -> str: ... - - -# The unannotated "value" parameter should not generate errors here. -def func1(value) -> int | str: - return 0 - - -# A non-overloaded function with an unannotated parameter should still -# generate errors. -def func2(value) -> int: - # This should generate an error because "value" has an unknown type and - # an error because "value" is missing a type annotation. - return 1 diff --git a/packages/vipeye-internal/src/tests/samples/overloadOverlap1.py b/packages/vipeye-internal/src/tests/samples/overloadOverlap1.py deleted file mode 100644 index ce8f6876..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadOverlap1.py +++ /dev/null @@ -1,511 +0,0 @@ -# This sample tests the type checker's detection of overlapping -# overload declarations. - -from typing import ( - Any, - AnyStr, - Callable, - Concatenate, - Generic, - Literal, - ParamSpec, - Protocol, - Sequence, - TypeVar, - overload, -) - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") -_P = ParamSpec("_P") - - -@overload -def func1(a: float, b: float | None, c: bool | None = None) -> int: ... - - -# This should generate an error because the overload is obscured. -@overload -def func1(a: int, b: int) -> int: ... - - -@overload -def func1(a: int, b: int, *, named: int = 3) -> int: ... - - -# This should generate an error because the overload is obscured. -@overload -def func1(a: int, b: int, *, named: int) -> int: ... - - -@overload -def func1(a: complex, b: int) -> int: ... - - -def func1(*args: Any, **kwargs: Any) -> Any: - pass - - -@overload -def func2(a: int, b: Any) -> int: - """Overload""" - - -# This should generate an error because the overload is obscured. -@overload -def func2(a: int, b: int) -> int: - """Overload""" - - -def func2(*args: Any, **kwargs: Any) -> Any: - pass - - -@overload -def func3(a: int, b: int) -> int: ... - - -@overload -def func3(a: int, b: int, **c: Any) -> int: ... - - -@overload -def func3(a: int, b: Any) -> int: ... - - -def func3(*args: Any, **kwargs: Any) -> Any: - pass - - -@overload -def func4(a: int, *, c: int, b: int) -> int: ... - - -# This should generate an error because the overload is obscured. -@overload -def func4(a: int, *, b: int, c: int) -> int: ... - - -def func4(*args: Any, **kwargs: Any) -> Any: - pass - - -# This should generate an error because the overload is overlapping -# in an unsafe way (i.e. returns an incompatible type). -@overload -def func5(a: int, b: int) -> int: ... - - -@overload -def func5(a: float, b: float = 3.4, *c: int, d: float = 4.5) -> str: ... - - -def func5(*args: Any, **kwargs: Any) -> Any: - pass - - -class GenericClass(Generic[_T1, _T2]): - @overload - def method1(self, a: _T1, b: tuple[_T2, ...]) -> int: ... - - @overload - def method1(self, a: _T1, b: tuple[Any, ...]) -> int: ... - - def method1(self, *args: Any, **kwargs: Any) -> Any: ... - - @overload - def method2(self, a: _T2, b: int) -> int: ... - - @overload - def method2(self, a: _T1, b: _T2) -> int: ... - - def method2(self, *args: Any, **kwargs: Any) -> Any: - pass - - -class Parent: ... - - -class Child(Parent): ... - - -# Test 1: Literal subtype - - -# This should generate an error because the overload is overlapping -# in an unsafe way (i.e. returns an incompatible type). -@overload -def func10(x: Literal[3]) -> int: ... - - -@overload -def func10(x: int) -> str: ... - - -def func10(*args: Any, **kwargs: Any) -> Any: - pass - - -# Test 2: Subclass subtype - - -# This should generate an error because the overload is overlapping -# in an unsafe way (i.e. returns an incompatible type). -@overload -def func11(x: Child) -> str: ... - - -@overload -def func11(x: Parent) -> int: ... - - -def func11(*args: Any, **kwargs: Any) -> Any: - pass - - -# Test 3: Implicit subtype - - -# This should generate an error because the overload is overlapping -# in an unsafe way (i.e. returns an incompatible type). -@overload -def func12(x: int) -> str: ... - - -@overload -def func12(x: float) -> int: ... - - -def func12(*args: Any, **kwargs: Any) -> Any: - pass - - -# Test 4: Union subtype - - -# This should generate an error because the overload is overlapping -# in an unsafe way (i.e. returns an incompatible type). -@overload -def func13(x: int) -> str: ... - - -@overload -def func13(x: int | str) -> int: ... - - -def func13(*args: Any, **kwargs: Any) -> Any: - pass - - -# Test 5: non-matching keyword argument - - -# This should generate an error because the overload is overlapping -# in an unsafe way (i.e. returns an incompatible type). -@overload -def func14(x: int, *, cls: str, **kwargs: Any) -> int: ... - - -@overload -def func14(x: int, **kwargs: Any) -> str: ... - - -def func14(*args: Any, **kwargs: Any) -> Any: - pass - - -# Test 6: non-matching keyword argument (shouldn't generate error) -@overload -def func15(cls: str, **kwargs: Any) -> int: ... - - -@overload -def func15(**kwargs: Any) -> str: ... - - -def func15(*args: Any, **kwargs: Any) -> Any: - pass - - -@overload -def func16(var: None) -> list[Any]: ... - - -@overload -def func16(var: _T1) -> list[_T1]: ... - - -def func16(var: _T1 | None) -> list[_T1] | list[Any]: ... - - -@overload -def func17(a: int, b: list[int]) -> int: ... - - -@overload -def func17(a: int, b: list[_T1]) -> _T1: ... - - -def func17(*args: Any, **kwargs: Any) -> Any: - pass - - -class ClassA(Generic[_T1]): - @overload - def __call__(self, f: _T1) -> _T1: ... - - @overload - def __call__(self, f: _T1 | None) -> _T1: ... - - def __call__(self, f: _T1 | None) -> _T1: ... - - -class ClassB: - @overload - def method1(self, x: type[Any]) -> bool: ... - - @overload - def method1(self, x: Any) -> str | bool: ... - - def method1(self, x: Any) -> Any: ... - - -class ClassC: - @overload - def method1(self, x: type) -> bool: ... - - @overload - def method1(self, x: Any) -> str | bool: ... - - def method1(self, x: Any) -> Any: ... - - -@overload -def func18(s: Sequence[_T1], extra: Literal[False]) -> list[_T1]: ... - - -@overload -def func18(s: Sequence[_T1], extra: Literal[True]) -> list[_T1] | tuple[_T1]: ... - - -@overload -def func18(s: Sequence[_T1], extra: bool) -> list[_T1] | tuple[_T1]: ... - - -def func18(s: Sequence[_T1], extra: bool) -> list[_T1] | tuple[_T1]: ... - - -class DProto1(Protocol): - def __radd__(self, other: Any, /) -> Any: ... - - -class DProto2(Protocol): - def __radd__(self: _T1, other: Any, /) -> _T1: ... - - -@overload -def func19(a: Any, b: DProto2) -> DProto2: ... - - -@overload -def func19(a: Any, b: DProto1) -> Any: ... - - -def func19(a: Any, b: Any) -> Any: - return a + b - - -AllStr = bytes | str - - -@overload -def func20(choices: AnyStr) -> AnyStr: ... - - -@overload -def func20(choices: AllStr) -> AllStr: ... - - -def func20(choices: AllStr) -> AllStr: ... - - -# This should generate an overlapping overload error. -@overload -def func21(self, p1: int | set[int], /) -> str: ... - - -@overload -def func21(self, p1: int | list[int], /) -> int: ... - - -def func21(self, p1: int | set[int] | list[int], /) -> str | int: - return "" - - -@overload -def func22(self, p1: str | set[int], /) -> str: ... - - -@overload -def func22(self, p1: int | list[int], /) -> int: ... - - -def func22(self, p1: str | int | set[int] | list[int], /) -> str | int: - return "" - - -@overload -def func23(f: Callable[Concatenate[_T1, _P], _T2]) -> int: ... - - -@overload -def func23(f: Callable[_P, _T2]) -> int: ... - - -def func23(f: Any) -> int: - return 1 - - -class E1: ... - - -TE1 = TypeVar("TE1", bound=E1) - - -class E2(E1, Generic[TE1]): ... - - -class E3(E1): ... - - -TE3 = TypeVar("TE3", bound=E3) - - -class E4(E1): ... - - -class ClassE(E2[E4], Generic[TE1]): - @overload - def unpack(self: "ClassE[E2[TE3]]") -> Sequence[TE3]: ... - - @overload - def unpack(self) -> Sequence[Any]: ... - - def unpack(self) -> Sequence[Any]: ... - - -@overload -def func24(f: Callable[[int], str]) -> int: ... - - -@overload -def func24(f: Callable[[_T1], str]) -> float: ... - - -def func24(f: Any) -> Any: - return f - - -_TInt = TypeVar("_TInt", bound=int) - - -@overload -def func25(val: _TInt) -> list[_TInt]: ... - - -@overload -def func25(val: str) -> int: ... - - -def func25(val: Any) -> Any: ... - - -@overload -def func26(val: _T1) -> list[_T1]: ... - - -# This should generate an error because it will never be used. -@overload -def func26(val: str) -> int: ... - - -def func26(val: Any) -> Any: ... - - -@overload -# This should generate an error because it is partially overlapping. -def func27(bar: None = ...) -> None: ... -@overload -def func27(bar: bool = ...) -> bool: ... -def func27(bar: bool | None = None) -> bool | None: ... - - -@overload -# This should generate an error because it is partially overlapping. -def func28(a: int, /, b: None = ...) -> None: ... -@overload -def func28(a: int, /) -> bool: ... -def func28(a: int, /, b: bool | None = None) -> bool | None: ... - - -class CBProto29(Protocol): - def __call__(self, *args: Any) -> Any: ... - - -@overload -def func29(func: CBProto29) -> None: ... - - -@overload -def func29(func: Callable[..., Any]) -> None: ... - - -def func29(func: Any) -> None: ... - - -class CBProto30(Protocol): - def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - - -@overload -def func30(func: CBProto30) -> None: ... - - -@overload -# This should generate an error because this overload will never be used. -def func30(func: Callable[..., Any]) -> None: ... - - -def func30(func: Any) -> None: ... - - -@overload -# This should generate an error because of a partial overlap. -def func31(*args: Any, a: int = ...) -> int: ... -@overload -def func31(*args: Any, a: str = ...) -> str: ... -def func31(*args: Any, a: int | str = 0) -> int | str: ... - - -type NestedList[V] = V | list[V | NestedList[V]] - - -@overload -def func32[V](n: list[NestedList[V]]) -> list[V]: ... -@overload -def func32(n: list[NestedList[Any]]) -> list[Any]: ... -def func32(n: Any) -> Any: ... - - -@overload -def func33(a: int, /, *args: str) -> None: ... -@overload -def func33(*args: str) -> None: ... -def func33(*args: int | str) -> None: ... - - -@overload -def func34(fn: Callable[[], Any]) -> None: ... -@overload -def func34[**P](fn: Callable[P, Any]) -> None: ... -def func34(fn: ...) -> ...: ... diff --git a/packages/vipeye-internal/src/tests/samples/overloadOverride1.py b/packages/vipeye-internal/src/tests/samples/overloadOverride1.py deleted file mode 100644 index defc34c0..00000000 --- a/packages/vipeye-internal/src/tests/samples/overloadOverride1.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the case where a base class method is overridden -# in a derived class with an overloaded method. - -# viper: reportIncompatibleMethodOverride=true - -from typing import overload - - -class Base1: - def foo(self, x: int) -> int: - return x - - -class Derived1(Base1): - @overload - def foo(self, x: int) -> int: ... - - @overload - def foo(self, x: str) -> str: ... - - def foo(self, x: int | str) -> int | str: - return x - - -class Base2: - def foo(self, x: int | str) -> int | str: - return x - - -class Derived2(Base2): - @overload - def foo(self, x: int) -> int: ... - - @overload - def foo(self, x: str) -> str: ... - - def foo(self, x: int | str) -> int | str: - return x - - -class Base3: - def foo(self, x: int) -> int: - return x - - -class Derived3(Base3): - @overload - def foo(self, x: float) -> float: ... - - @overload - def foo(self, x: str) -> str: ... - - # This should generate an error because no overloaded signature - # is compatible with the base method, nor is the implementation. - def foo(self, x: int | str | float) -> int | str | float: - return x diff --git a/packages/vipeye-internal/src/tests/samples/override1.py b/packages/vipeye-internal/src/tests/samples/override1.py deleted file mode 100644 index 6821fe48..00000000 --- a/packages/vipeye-internal/src/tests/samples/override1.py +++ /dev/null @@ -1,121 +0,0 @@ -# This sample tests the handling of the @override decorator as described -# in PEP 698. - -from typing import Callable, Protocol -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Any, - overload, - override, -) - - -class ClassA: - def method1(self) -> None: - pass - - -class ClassB: - def method3(self) -> None: - pass - - @overload - def method5(self, x: int) -> int: ... - - @overload - def method5(self, x: str) -> str: ... - - def method5(self, x: int | str) -> int | str: ... - - -class ClassC(ClassA, ClassB): - @property - @override - # This should generate an error because prop_a doesn't - # override anything in its base class. - def prop_a(self) -> int: - raise NotImplementedError - - @override - def method1(self) -> None: - pass - - def method2(self) -> None: - pass - - @override - def method3(self) -> None: - pass - - @override - # This should generate an error because method3 does not - # override anything in a base class. - def method4(self) -> None: - pass - - @overload - def method5(self, x: int) -> int: ... - - @overload - def method5(self, x: str) -> str: ... - - @override - def method5(self, x: int | str) -> int | str: ... - - @overload - def method6(self, x: int) -> int: ... - - @overload - def method6(self, x: str) -> str: ... - - @override - # This should generate an error because method6 does not - # override anything in a base class. - def method6(self, x: int | str) -> int | str: ... - - -class ClassD(Any): ... - - -class ClassE(ClassD): - @override - def method1(self) -> None: - pass - - -def evil_wrapper(func: Callable[..., Any], /): - def wrapped(*args: Any, **kwargs: Any) -> Any: - raise NotImplementedError - - return wrapped - - -class F: - def method1(self): - pass - - -class G(F): - @override - @evil_wrapper - def method1(self): - pass - - -class H(Protocol): - pass - - -class I(H, Protocol): - @override - # This should generate an error because method1 isn't present - # in the base. - def method1(self): - pass - - @overload - @override - # This should generate an error because method2 isn't present - # in the base. - def method2(self, x: int) -> int: ... - @overload - def method2(self, x: str) -> str: ... diff --git a/packages/vipeye-internal/src/tests/samples/override2.py b/packages/vipeye-internal/src/tests/samples/override2.py deleted file mode 100644 index 315d7ec1..00000000 --- a/packages/vipeye-internal/src/tests/samples/override2.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests the reportImplicitOverride diagnostic check -# (strict enforcement of PEP 698). - -from typing import Any, Callable -from typing_extensions import override # viper: ignore[reportMissingModuleSource] - - -def evil_wrapper(func: Callable[..., Any], /): - def wrapped(*args: Any, **kwargs: Any) -> Any: - raise NotImplementedError - - return wrapped - - -class Base: - @override - def __init__(self): - pass - - def method1(self): - pass - - @property - def prop_c(self) -> int: - return 0 - - def method2(self): - pass - - -class Child(Base): - def __init__(self): - pass - - # This should generate an error if reportImplicitOverride is enabled. - def method1(self): - pass - - @property - # This should generate an error if reportImplicitOverride is enabled. - def prop_c(self) -> int: - return 0 - - @evil_wrapper - def method2(self): - pass diff --git a/packages/vipeye-internal/src/tests/samples/paramInference1.py b/packages/vipeye-internal/src/tests/samples/paramInference1.py deleted file mode 100644 index 0921c960..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramInference1.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests the logic that infers parameter types based on -# default argument values or annotated base class methods. - - -class Parent: - def __init__(self, a: int, b: str): ... - - def func1(self, a: int, b: str) -> float: ... - - -class Child(Parent): - def __init__(self, a, b): - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="str") - - def func1(self, a, b): - reveal_type(self, expected_text="Self@Child") - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="str") - return a - - -def func2(a, b=0, c=None): - reveal_type(a, expected_text="Unknown") - reveal_type(b, expected_text="int") - reveal_type(c, expected_text="Unknown | None") - - -def func3(a=(1, 2), b=[1, 2], c={1: 2}): - reveal_type(a, expected_text="Unknown") - reveal_type(b, expected_text="Unknown") - reveal_type(c, expected_text="Unknown") - - -class _Undefined: - pass - - -Undefined = _Undefined() - - -def func4(a=1, b=None, c=Undefined, d=lambda x: x): - reveal_type(a, expected_text="int") - reveal_type(b, expected_text="Unknown | None") - reveal_type(c, expected_text="_Undefined | Unknown") - reveal_type(d, expected_text="Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/paramInference2.py b/packages/vipeye-internal/src/tests/samples/paramInference2.py deleted file mode 100644 index a0d151e1..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramInference2.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the logic that infers parameter types based on -# annotated base class methods when the base class is generic. - -# viper: reportIncompatibleMethodOverride=false - -from typing import Callable, Generic, ParamSpec, TypeVar - -T = TypeVar("T") -P = ParamSpec("P") -R = TypeVar("R") - - -class Parent1(Generic[T]): - def method1(self, a: T, b: list[T]) -> None: ... - - -class Child1(Parent1[float]): - def method1(self, a, b): - reveal_type(self, expected_text="Self@Child1") - reveal_type(a, expected_text="float") - reveal_type(b, expected_text="list[float]") - return a - - -class Parent2: - def method1(self, fn: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R: - return fn(*args, **kwargs) - - -class Child2(Parent2): - def method1(self, fn, *args, **kwargs): - reveal_type(self, expected_text="Self@Child2") - reveal_type(fn, expected_text="(...) -> Unknown") - reveal_type(args, expected_text="tuple[Unknown, ...]") - reveal_type(kwargs, expected_text="dict[str, Unknown]") - return super().method1(fn, *args, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/paramNames1.py b/packages/vipeye-internal/src/tests/samples/paramNames1.py deleted file mode 100644 index 3244eaf4..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramNames1.py +++ /dev/null @@ -1,89 +0,0 @@ -# This sample tests the reportSelfClsParameterName setting. - - -from typing import overload - - -def foo(): - pass - - -class Class1: - # This should generate an error or warning if the setting - # is enabled because __new__ is expected to take cls. - def __new__(blah): - return super().__new__(blah) - - # This should generate an error or warning if the setting - # is enabled because it's missing a "self" parameter. - def foo1(): - return 3 - - # This should generate an error or warning if the setting - # is enabled because "self" is misspelled. - def foo2(seeeelf): - return 4 - - # This should generate an error or warning if the setting - # is enabled because "self" is misspelled. - def foo3(cls): - return 4 - - @classmethod - def foo4(cls): - return 4 - - @classmethod - # This should generate an error or warning if the setting - # is enabled because "cls" is expected. - def foo5(self): - return 4 - - @overload - # This should generate an error or warning if the setting - # is enabled because "self" is expected. - def foo6(x: "Class1") -> int: ... - - @overload - # This should generate an error or warning if the setting - # is enabled because "self" is expected. - def foo6(x: int) -> str: ... - - # This should generate an error or warning if the setting - # is enabled because "self" is expected. - def foo6(x) -> int | str: ... - - @classmethod - # This should generate an error or warning if the setting - # is enabled because this isn't a metaclass. - def foo7(mcls): - return 4 - - -class Metaclass(type): - def __new__(mcls): ... - - # This should not generate a error because the class derives - # from type and is assumed to be a metaclass. - def foo1(cls): - return 3 - - # This should generate an error. - def foo2(mcls): - return 3 - - def foo3(self): - return 3 - - @classmethod - def foo4(cls): - return 3 - - @classmethod - def foo5(metacls): - return 3 - - # This should generate an error. - @classmethod - def foo6(bar): - return 3 diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec1.py b/packages/vipeye-internal/src/tests/samples/paramSpec1.py deleted file mode 100644 index f3d58afb..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec1.py +++ /dev/null @@ -1,60 +0,0 @@ -# This sample tests error conditions for ParamSpec (PEP 612). - -from typing import Any, Callable, ParamSpec, Protocol, cast - -P = ParamSpec("P") - - -# This should generate an error because ParamSpecs -# can't be used as a type annotation. -def func1(a: P) -> int: - return 1 - - -a = 3 - -# This should generate an error. -b = cast(P, a) - -func1(1) - - -def func2(x: Callable[P, Any]): - # This should generate an error. - c: list[P] = [] - - d: Callable[P, int] - - # This should generate an error. - e: Callable[P, P] - - # This should generate an error. - f: Callable[[P], int] - - # This should generate an error. - g: tuple[P] - - -class SomeWrapper(Protocol[P]): - def __call__(self, *args: P.args, **kwargs: P.kwargs): ... - - -# This should generate an error because P cannot be used with other -# type arguments. -def func3(x: SomeWrapper[P, int]): - pass - - -# This should generate an error because P cannot be used with other -# type arguments. -def func4(x: SomeWrapper[[P, int]]): - pass - - -def func5(x: SomeWrapper[P]): - pass - - -# This form is considered an error. -def func6(x: SomeWrapper[[P]]): - pass diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec10.py b/packages/vipeye-internal/src/tests/samples/paramSpec10.py deleted file mode 100644 index 3cb6447c..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec10.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the use of ParamSpec along with Concatenate in -# a return type. - -from typing import Callable, Protocol, TypeVar, Concatenate, ParamSpec -from threading import RLock -import functools - - -class HasLock(Protocol): - _lock: RLock - - -S = TypeVar("S", bound=HasLock) -P = ParamSpec("P") -R = TypeVar("R") - - -def with_lock(func: Callable[Concatenate[S, P], R]) -> Callable[Concatenate[S, P], R]: - @functools.wraps(func) - def wrapper(self: S, *args: P.args, **kwargs: P.kwargs) -> R: - with self._lock: - return func(self, *args, **kwargs) - - return wrapper - - -class MyClass: - def __init__(self): - self._lock = RLock() - - @with_lock - def test_1(self, param1: int) -> str: ... - - @with_lock - def test_2(self) -> str: ... - - -@with_lock -def test_3(cls: MyClass, param1: int) -> str: ... - - -testClass = MyClass() - -res1 = testClass.test_1(42) -reveal_type(res1, expected_text="str") - -res2 = testClass.test_2() -reveal_type(res2, expected_text="str") - -res3 = test_3(testClass, 42) -reveal_type(res3, expected_text="str") - -res4: Callable[[MyClass, int], str] = with_lock(test_3) -reveal_type(res4, expected_text="(MyClass, int) -> str") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec11.py b/packages/vipeye-internal/src/tests/samples/paramSpec11.py deleted file mode 100644 index 7633da8f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec11.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the handling of generic classes that are parameterized -# using a ParamSpec. - -from typing import Callable, Generic, TypeVar, ParamSpec - - -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -class MyDecorator(Generic[_P, _R]): - def __init__(self, function: Callable[_P, _R]): - self.function = function - - def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _R: - print("Inside Function Call") - return self.function(*args, **kwargs) - - def do_stuff(self, name: str, *args: _P.args, **kwargs: _P.kwargs) -> int: - return 0 - - -@MyDecorator -def func1(x: int, y: int, *, z: int): - return x + y - - -func1(6, 6, z=6) - - -@MyDecorator -def func2(*, a: int): - pass - - -func2.do_stuff("hi", a=4) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec12.py b/packages/vipeye-internal/src/tests/samples/paramSpec12.py deleted file mode 100644 index dc0dbe44..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec12.py +++ /dev/null @@ -1,87 +0,0 @@ -# This sample tests various error conditions for ParamSpec usage. - -from typing import ( - Annotated, - Any, - Callable, - Mapping, - Sequence, - TypeVar, - ParamSpec, - Union, -) - -P = ParamSpec("P") -R = TypeVar("R") - - -def puts_p_into_scope(f: Callable[P, int]) -> None: - def inner1(*args: P.args, **kwargs: P.kwargs) -> None: - pass - - def inner2(*args: "P.args", **kwargs: P.kwargs) -> None: - pass - - def inner3(*args: P.args, **kwargs: "P.kwargs") -> None: - pass - - def inner4(*args: "P.args", **kwargs: "P.kwargs") -> None: - pass - - def inner5(*args: Annotated[P.args, ""], **kwargs: "P.kwargs") -> None: - pass - - def inner6(*args: P.args, **kwargs: Annotated["P.kwargs", ""]) -> None: - pass - - # This should generate two errors because P.kwargs cannot be - # used with *args and P.args cannot be used with **kwargs. - def mixed_up(*args: P.kwargs, **kwargs: P.args) -> None: - pass - - # This should generate an error because P.args cannot be used - # with a simple parameter. - def misplaced(x: P.args) -> None: - pass - - # This should generate an error - stored_args: P.args - - # This should generate an error - stored_kwargs: P.kwargs - - # This should generate an error because P.args cannot be used - # without P.kwargs. - def just_args(*args: P.args) -> None: - pass - - # This should generate an error because P.kwargs cannot be used - # without P.args. - def just_kwargs(**kwargs: P.kwargs) -> None: - pass - - # This should generate two errors because P.args and P.kwargs cannot be used in - # a union. - def union_args1( - *args: P.args | Sequence[Any], **kwargs: P.kwargs | Mapping[str, Any] - ) -> None: - pass - - # This should generate two errors because P.args cannot be used in - # a union. - def union_args2( - *args: P.args | Sequence[Any], **kwargs: Union[P.kwargs, Mapping[str, Any]] - ) -> None: - pass - - -# This should generate an error because P is not defined in this context. -def out_of_scope(*args: P.args, **kwargs: P.kwargs) -> None: - pass - - -# This should generate an error because ParamSpec isn't allowed in this context -out_of_scope_var2: P = 12 - -# This should generate an error because P isn't allowed in this context. -out_of_scope_var3: P.args = 12 diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec13.py b/packages/vipeye-internal/src/tests/samples/paramSpec13.py deleted file mode 100644 index 9d160bfb..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec13.py +++ /dev/null @@ -1,129 +0,0 @@ -# This sample tests cases where a ParamSpec is used as a type parameter -# for a generic type alias, a generic function, and a generic class. - -import asyncio -from typing import ( - Any, - Callable, - Concatenate, - Coroutine, - Generic, - ParamSpec, - TypeAlias, - TypeVar, -) - -_P = ParamSpec("_P") -_R = TypeVar("_R") -_T = TypeVar("_T") - - -AddIntParam = Callable[Concatenate[int, _P], _T] - - -def func1(func: Callable[_P, _R]) -> AddIntParam[_P, _R]: ... - - -def func2(a: str, b: list[int]) -> str: ... - - -v1 = func1(func2) -reveal_type(v1, expected_text="(int, a: str, b: list[int]) -> str") - -# This should generate an error because 'int' isn't assignable to -# ParamSpec _P. -X = AddIntParam[int, int] - - -class RemoteResponse(Generic[_T]): ... - - -class RemoteFunction(Generic[_P, _R]): - def __init__(self, func: Callable[_P, _R]) -> None: ... - - def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... - - def remote(self, *args: _P.args, **kwargs: _P.kwargs) -> RemoteResponse[_R]: ... - - -r1 = RemoteFunction(func2) -reveal_type(r1, expected_text="RemoteFunction[(a: str, b: list[int]), str]") - -v2 = r1("hi", []) -reveal_type(v2, expected_text="str") - -v3 = r1.remote("hi", []) -reveal_type(v3, expected_text="RemoteResponse[str]") - -# This should generate an error -r1(1, []) - -# This should generate an error -r1("hi") - -# This should generate an error -r1.remote(1, []) - -# This should generate an error because 'int' is not assignable -# to ParamSpec _P. -A = RemoteFunction[int, int] - - -def remote(func: Callable[_P, _R]) -> RemoteFunction[_P, _R]: ... - - -v4 = remote(func2) -reveal_type(v4, expected_text="RemoteFunction[(a: str, b: list[int]), str]") - - -Coro = Coroutine[Any, Any, _T] -CoroFunc = Callable[_P, Coro[_T]] - - -class ClassA: ... - - -CheckFunc = CoroFunc[Concatenate[ClassA, _P], bool] - - -async def my_check_func(obj: ClassA, a: int, b: str) -> bool: - print(a, b) - return str(a) == b - - -async def takes_check_func( - check_func: CheckFunc[_P], *args: _P.args, **kwargs: _P.kwargs -): - await check_func(ClassA(), *args, **kwargs) - - -asyncio.run(takes_check_func(my_check_func, 1, "2")) - -# This should generate an error because the signature doesn't match. -asyncio.run(takes_check_func(my_check_func, 1, 2)) - - -TA1: TypeAlias = Callable[_P, Any] - -ta1_1: TA1[()] = lambda: 0 - -# This should generate an error. -ta1_2: TA1[()] = lambda x: x - - -TA2: TypeAlias = Callable[Concatenate[int, _P], None] - -TA3: TypeAlias = TA2[int, int] -TA4: TypeAlias = TA2[_P] - -# This should generate an error. -TA5: TypeAlias = TA2[[int, _P]] - -# This should generate an error. -TA6: TypeAlias = TA2[[int, ...]] - -TA7: TypeAlias = TA2[Concatenate[int, _P]] -TA8: TypeAlias = TA2[Concatenate[int, ...]] - -# This should generate two errors. -TA9: TypeAlias = TA2[int, Concatenate[int, _P]] diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec14.py b/packages/vipeye-internal/src/tests/samples/paramSpec14.py deleted file mode 100644 index c1584c26..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec14.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests the handling of ParamSpec when used with -# static methods and class methods. - -from typing import Any, Callable, Generic, ParamSpec, Self, TypeVar, overload - -P = ParamSpec("P") -T = TypeVar("T") - - -def deco(func: Callable[P, float]) -> Callable[P, int]: - def wrapper(*args: P.args, **kwargs: P.kwargs) -> int: - return round(func(*args, **kwargs)) - - return wrapper - - -class ClassA: - @deco - @classmethod - def identity_cls(cls, val: float) -> float: - return val - - @deco - @staticmethod - def identity_static(val: float) -> float: - return val - - -reveal_type(ClassA.identity_cls(1.2), expected_text="int") -reveal_type(ClassA.identity_static(1.2), expected_text="int") - - -class ClassB(Generic[P, T]): - @overload - @classmethod - def method1( - cls, run: Callable[P, T], /, *args: P.args, **kwargs: P.kwargs - ) -> Self: ... - - @overload - @classmethod - def method1(cls) -> "ClassB[[], None]": ... - - @classmethod - def method1(cls, *args: Any, **kwargs: Any) -> Any: ... - - -def func1() -> None: - pass - - -m1 = ClassB.method1 -m1(func1) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec15.py b/packages/vipeye-internal/src/tests/samples/paramSpec15.py deleted file mode 100644 index 1fd84e76..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec15.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the handling of generic classes parameterized -# with a ParamSpec. - -from typing import Callable, Generic, TypeVar -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -P = ParamSpec("P") -T = TypeVar("T") - - -class Foo(Generic[P, T]): - def __init__(self, func: Callable[P, T]) -> None: ... - - -def foo(foo: Foo[P, T], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -def func(a: int) -> str: ... - - -a = Foo(func) -reveal_type(a, expected_text="Foo[(a: int), str]") - -c = foo(a, 2) -reveal_type(c, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec16.py b/packages/vipeye-internal/src/tests/samples/paramSpec16.py deleted file mode 100644 index 5fb06c3d..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec16.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the matching of nested callables that each use -# ParamSpec. - -from typing import Callable, Generic, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -P = ParamSpec("P") -Q = ParamSpec("Q") - -T = TypeVar("T") -U = TypeVar("U") - - -class ClassA(Generic[P, T, Q, U]): ... - - -def decorator1( - func: Callable[Concatenate[Callable[P, T], Q], U], -) -> ClassA[P, T, Q, U]: ... - - -@decorator1 -def func1(func: Callable[[int], float], a: str) -> bool: ... - - -reveal_type(func1, expected_text="ClassA[(int), float, (a: str), bool]") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec17.py b/packages/vipeye-internal/src/tests/samples/paramSpec17.py deleted file mode 100644 index 57d73cec..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec17.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample validates that *P.args and **P.kwargs can be used as a -# tuple and dict, respectively. - -# viper: strict - -from collections.abc import Callable -from typing import Any -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -P = ParamSpec("P") - - -def func1(func: Callable[P, object], *args: P.args, **kwargs: P.kwargs) -> str: - arg_reprs = [repr(arg) for arg in args] - arg_reprs.extend(k + "=" + repr(v) for k, v in kwargs.items()) - - return func.__name__ + "(" + ", ".join(arg_reprs) + ")" - - -def func2(*values: object, sep: str | None = ..., end: str | None = ...) -> None: ... - - -func1(func2) - - -def func3(a: int, b: int): ... - - -def func4(*args: Any, **kwargs: Any): - func1(func3, *args, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec18.py b/packages/vipeye-internal/src/tests/samples/paramSpec18.py deleted file mode 100644 index c545efd7..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec18.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the handling of a ParamSpec within a callback protocol. - -from typing import Callable, Concatenate, ParamSpec, Protocol - - -P = ParamSpec("P") - - -def callback(a: int, b: str, c: str) -> int: ... - - -CallableWithConcatenate = Callable[Concatenate[int, P], int] - - -def func_with_callable(cb: CallableWithConcatenate[P]) -> Callable[P, bool]: ... - - -x1 = func_with_callable(callback) -reveal_type(x1, expected_text="(b: str, c: str) -> bool") - - -class ClassWithConcatenate(Protocol[P]): - def __call__(self, x: int, /, *args: P.args, **kwargs: P.kwargs) -> int: ... - - -def func_with_protocol(cb: ClassWithConcatenate[P]) -> Callable[P, bool]: ... - - -x2 = func_with_protocol(callback) -reveal_type(x2, expected_text="(b: str, c: str) -> bool") - - -class CallbackPos(Protocol[P]): - def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> None: ... - - -def invoke_pos(cb: CallbackPos[P], /, *args: P.args, **kwargs: P.kwargs) -> None: - cb(*args, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec19.py b/packages/vipeye-internal/src/tests/samples/paramSpec19.py deleted file mode 100644 index 0d7534b8..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec19.py +++ /dev/null @@ -1,91 +0,0 @@ -# This sample tests the case where a ParamSpec is used within a generic -# type alias with a Callable. - -from typing import Any, Callable, Generic, Protocol -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -P = ParamSpec("P") - -# Example 1: Callable generic type alias - -CommandHandler1 = Callable[Concatenate[int, P], dict[str, Any]] - - -class Command1(Generic[P]): - def __init__(self, handler: CommandHandler1[P]) -> None: ... - - -class Application1: - def func1(self, handler: CommandHandler1[P]) -> Command1[P]: - return Command1(handler) - - def func2( - self, - handler: CommandHandler1[P], - ) -> Callable[[CommandHandler1[P]], Command1[P]]: - def decorator(handler: CommandHandler1[P]) -> Command1[P]: - return self.func1(handler) - - return decorator - - -# Example 2: Callback Protocol - - -class CommandHandler2(Protocol[P]): - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> dict[str, Any]: ... - - -class Command2(Generic[P]): - def __init__(self, handler: CommandHandler2[P]) -> None: ... - - -class Application2: - def func1(self, handler: CommandHandler2[P]) -> Command2[P]: - return Command2(handler) - - def func2( - self, - handler: CommandHandler2[P], - ) -> Callable[[CommandHandler2[P]], Command2[P]]: - def decorator(handler: CommandHandler2[P]) -> Command2[P]: - return self.func1(handler) - - return decorator - - -def handler(arg1: int, arg2: str) -> dict[str, Any]: ... - - -v1: CommandHandler2 = handler - - -def func1_1(x: CommandHandler1[str]): - x(3, "hi") - - -def func1_2(x: CommandHandler1[[str, int]]): - x(3, "hi", 3) - - -def func2_1(x: CommandHandler2[str]): - x("hi") - - -def func2_2(x: CommandHandler2[[str, int]]): - x("hi", 3) - - -HandlerAlias = Callable[P, None] - -list_of_handlers: list[HandlerAlias[...]] = [] - - -class HandlerProtocol(Protocol[P]): - def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> None: ... - - -list_of_handler_protocols: list[HandlerProtocol[...]] = [] diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec2.py b/packages/vipeye-internal/src/tests/samples/paramSpec2.py deleted file mode 100644 index aa67e436..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec2.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests ParamSpec (PEP 612) behavior. - -from asyncio import Future -from typing import Awaitable, Callable, ParamSpec, TypeVar - -P = ParamSpec("P") -R = TypeVar("R") - - -def awaitable_wrapper(a: Callable[P, R]) -> Callable[P, Awaitable[R]]: - def foo_internal(*args: P.args, **kwargs: P.kwargs) -> Awaitable[R]: - ft: "Future[R]" = Future() - ft.set_result(a(*args, **kwargs)) - return ft - - return foo_internal - - -@awaitable_wrapper -def bar(a: int, b: str) -> float: - return 2.3 - - -async def bbb() -> float: - return await bar(2, "3") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec20.py b/packages/vipeye-internal/src/tests/samples/paramSpec20.py deleted file mode 100644 index a68340f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec20.py +++ /dev/null @@ -1,73 +0,0 @@ -# This sample tests the handling of class specialization expressions -# that provide signatures for ParamSpecs. - -from typing import Any, Callable, Concatenate, Generic, ParamSpec, TypeVar - - -T = TypeVar("T") -P1 = ParamSpec("P1") -P2 = ParamSpec("P2") - - -class X(Generic[T, P1]): - f: Callable[P1, int] - x: T - - -def x1(x: X[int, P2]) -> str: ... - - -def x2(x: X[int, Concatenate[int, P2]]) -> str: ... - - -def X3(x: X[int, [int, bool]]) -> str: ... - - -def x4(x: X[int, ...]) -> str: ... - - -# This should generate an error because "int" can't be bound to a ParamSpec. -def x5(x: X[int, int]) -> str: ... - - -# This should generate an error. -def x6(x: X[..., ...]) -> str: ... - - -# This should generate an error. -def x7(x: X[[int], [int, int]]) -> str: ... - - -class Y(Generic[P2]): - def __init__(self, cb: Callable[P2, Any]) -> None: ... - - def m1(self) -> X[int, Concatenate[float, P2]]: ... - - -y1 = Y(x4) -reveal_type(y1, expected_text="Y[(x: X[int, ...])]") - -y2 = y1.m1() -reveal_type(y2, expected_text="X[int, (float, x: X[int, ...])]") - - -class Z(Generic[P1]): - f: Callable[P1, int] - - -def z1(x: Z[[int, str, bool]]) -> str: ... - - -def z2(x: Z[int, str, bool]) -> str: ... - - -# This should generate an error. -def z3(x: Z[[int, [str], bool]]) -> str: ... - - -# This should generate an error. -def z4(x: Z[[[int, str, bool]]]) -> str: ... - - -# This should generate an error. -def z5(x: Z[[...]]) -> str: ... diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec21.py b/packages/vipeye-internal/src/tests/samples/paramSpec21.py deleted file mode 100644 index 89748cf5..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec21.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the case where a ParamSpec is used within a source -# and destination callback protocol. - -from typing import Callable, Protocol -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -P1 = ParamSpec("P1") -P2 = ParamSpec("P2") -P3 = ParamSpec("P3") -P4 = ParamSpec("P4") - - -class Context: ... - - -class Response: ... - - -class ContextCallback(Protocol[P1]): - def __call__( - self, ctx: Context, /, *args: P1.args, **kwargs: P1.kwargs - ) -> Response: ... - - -def call_context_callback( - callback: ContextCallback[P3], /, *args: P3.args, **kwargs: P3.kwargs -) -> Response: ... - - -class IntContextCallback(Protocol[P2]): - def __call__( - self, ctx: Context, value: int, /, *args: P2.args, **kwargs: P2.kwargs - ) -> Response: ... - - -def call_int_context_callback( - callback: IntContextCallback[P4], value: int, /, *args: P4.args, **kwargs: P4.kwargs -) -> Response: - return call_context_callback(callback, value, *args, **kwargs) - - -P5 = ParamSpec("P5") -P6 = ParamSpec("P6") -P7 = ParamSpec("P7") - -ContextCallable = Callable[Concatenate[Context, P5], Response] -IntContextCallable = Callable[Concatenate[Context, int, P6], Response] - - -def call_int_context_callable( - callback: IntContextCallable[P7], value: int, /, *args: P7.args, **kwargs: P7.kwargs -) -> Response: - return call_context_callback(callback, value, *args, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec22.py b/packages/vipeye-internal/src/tests/samples/paramSpec22.py deleted file mode 100644 index f848bbe9..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec22.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where a specialized generic class that uses -# a ParamSpec and a callback protocol is assigned to a Callable that -# uses a ParamSpec. - -from typing import Callable, Generic, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -P = ParamSpec("P") -R = TypeVar("R") - - -class MyPartial(Generic[P, R]): - def __init__(self, first: int, func: Callable[Concatenate[int, P], R]) -> None: - self.first = first - self.func = func - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -class MyPartialCreator(Generic[P, R]): - def __init__(self, func: Callable[Concatenate[int, P], R]): - self.func = func - - def create_partial(self, first: int) -> Callable[P, R]: - return MyPartial[P, R](first=first, func=self.func) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec23.py b/packages/vipeye-internal/src/tests/samples/paramSpec23.py deleted file mode 100644 index 38cec040..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec23.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a Callable that includes a Concatenate -# is assigned to a ParamSpec that doesn't include a Concatenate. - - -from typing import Callable, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -P = ParamSpec("P") - - -def is_inty(f: Callable[P, object]) -> Callable[P, int]: ... - - -T = TypeVar("T") - - -def outer(f: Callable[Concatenate[str, P], object]): - x = is_inty(f) - reveal_type(x, expected_text="(str, **P@outer) -> int") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec24.py b/packages/vipeye-internal/src/tests/samples/paramSpec24.py deleted file mode 100644 index 094636f0..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec24.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the case where a Callable that includes a Concatenate -# is used as an input parameter to a function that returns a generic -# type parameterized by a ParamSpec and specialized with a Concatenate. - -# viper: reportOverlappingOverload=false - -from __future__ import annotations -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Self, - Concatenate, - ParamSpec, -) -from typing import Any, Callable, TypeVar, Protocol, Generic, overload - -T = TypeVar("T") -O = TypeVar("O") -P = ParamSpec("P") -Self_A = TypeVar("Self_A", bound="A") - - -class _callable_cache(Protocol[P, T]): - foo: int = 0 - val: T - - def __init__(self, val: T) -> None: - self.val = val - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T: - return self.val - - -class _wrapped_cache(_callable_cache[P, T], Generic[O, P, T]): - @overload - def __get__( # type: ignore - self, instance: None, owner: type[O] - ) -> _callable_cache[Concatenate[O, P], T]: ... - - @overload - def __get__(self, instance: O, owner: type[O]) -> Self: ... - - -@overload -def cache(fn: Callable[Concatenate[Self_A, P], T]) -> _wrapped_cache[Self_A, P, T]: # type: ignore - ... - - -@overload -def cache(fn: Callable[P, T]) -> _wrapped_cache[Any, P, T]: ... - - -@cache -def not_in_class(a: int, b: str) -> str: ... - - -class A: - @cache - def in_class(self, a: int, b: str) -> str: ... - - -reveal_type(not_in_class, expected_text="_wrapped_cache[Any, (a: int, b: str), str]") -not_in_class(1, "") - -a = A() - -reveal_type(a.in_class, expected_text="_wrapped_cache[A, (a: int, b: str), str]") -a.in_class(1, "") - -reveal_type(A.in_class, expected_text="_callable_cache[(A, a: int, b: str), str]") -A.in_class(a, 1, "") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec25.py b/packages/vipeye-internal/src/tests/samples/paramSpec25.py deleted file mode 100644 index 4d4bc4b5..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec25.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the case where a generic type uses a ParamSpec -# as a type parameter and it is specialized using an empty signature. - -from typing import Any, Callable, Concatenate, Generic, ParamSpec - -P = ParamSpec("P") - - -class Context: ... - - -CommandHandler = Callable[Concatenate[Context, P], Any] - - -class Command(Generic[P]): - def __init__(self, handler: CommandHandler[P]) -> None: ... - - -def handler_no_args(ctx: Context) -> None: ... - - -def handler_one_arg(ctx: Context, a: int) -> None: ... - - -cmd_no_args = Command(handler_no_args) -reveal_type(cmd_no_args, expected_text="Command[()]") - -cmd_one_arg = Command(handler_one_arg) -reveal_type(cmd_one_arg, expected_text="Command[(a: int)]") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec26.py b/packages/vipeye-internal/src/tests/samples/paramSpec26.py deleted file mode 100644 index 4879253b..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec26.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a generic class parameterized by a -# ParamSpec is specialized using a Concatenate[] type argument. - -from typing import ParamSpec, Concatenate, Generic, Callable, Any - -P = ParamSpec("P") - - -class A(Generic[P]): - def __init__(self, func: Callable[P, Any]) -> None: ... - - -def func1(a: A[Concatenate[int, P]]) -> A[P]: ... - - -def func2(a: int, b: str) -> str: ... - - -val1 = A(func2) -reveal_type(val1, expected_text="A[(a: int, b: str)]") -val2 = func1(val1) -reveal_type(val2, expected_text="A[(b: str)]") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec27.py b/packages/vipeye-internal/src/tests/samples/paramSpec27.py deleted file mode 100644 index f6ab838d..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec27.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests the case where an ellipsis is used to specialize -# a generic class parameterized by a ParamSpec. - -from typing import Callable, Generic, Protocol, assert_type -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, - TypeAlias, -) - -P = ParamSpec("P") - - -def func1(a: int, b: str) -> None: ... - - -def func2(a: str, b: str) -> None: ... - - -class Handler(Protocol[P]): - def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> None: ... - - -class ConcatHandler(Protocol[P]): - def __call__(self, a: int, /, *args: P.args, **kwargs: P.kwargs) -> None: ... - - -ConcatCallableHandler: TypeAlias = Callable[Concatenate[int, P], None] - - -handler_callable1: Callable[..., None] = func1 -concat_handler_callable1: ConcatCallableHandler[...] = func1 - -# This should generate an error because the first param of func2 is not int. -concat_handler_callable2: ConcatCallableHandler[...] = func2 - -handler1: Handler[...] = func1 -concat_handler1: ConcatHandler[...] = func1 - -# This should generate an error because the first param of func2 is not int. -concat_handler2: ConcatHandler[...] = func2 - - -def func0(x: ConcatCallableHandler[str, str]): - assert_type(x, Callable[[int, str, str], None]) - - -class Command(Generic[P]): - def __init__(self, handler: Handler[P]) -> None: - self.handler: Handler[P] = handler - - -commands: list[Command[...]] = [] - - -def do_something(int_handler: Handler[int], var_args_handler: Handler[P], /) -> None: - int_command = Command(int_handler) - commands.append(int_command) - - var_args_command = Command(var_args_handler) - commands.append(var_args_command) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec28.py b/packages/vipeye-internal/src/tests/samples/paramSpec28.py deleted file mode 100644 index a76c418f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec28.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests a complicated combination of ParamSpec usage. - -# viper: strict - -from typing import Any, Callable, Concatenate, ParamSpec, Protocol, TypeVar - - -_Fn = TypeVar("_Fn", bound=Callable[..., Any]) -_Ret = TypeVar("_Ret") -_Args = ParamSpec("_Args") -_Self = TypeVar("_Self", bound="_GenerativeType") - - -def decorator( - target: Callable[Concatenate[_Fn, _Args], _Ret], -) -> Callable[[_Fn], Callable[_Args, _Ret]]: ... - - -class _GenerativeType(Protocol): - def _generate(self: "_Self") -> "_Self": ... - - -def generative( - fn: Callable[Concatenate[_Self, _Args], None], -) -> Callable[Concatenate[_Self, _Args], _Self]: - @decorator - def _generative( - fn: Callable[Concatenate[_Self, _Args], None], - self: _Self, - *args: _Args.args, - **kw: _Args.kwargs, - ) -> _Self: ... - - decorated = _generative(fn) - - return decorated diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec29.py b/packages/vipeye-internal/src/tests/samples/paramSpec29.py deleted file mode 100644 index e9294acd..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec29.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the case where an inner function uses concatenation -# and the return type of the outer function doesn't. - -from typing import Callable, Concatenate, ParamSpec - -P = ParamSpec("P") - - -def decorator1(f: Callable[P, None]) -> Callable[P, None]: - def inner(var: int, *args: P.args, **kwargs: P.kwargs) -> None: - f(*args, **kwargs) - - # This should generate an error because the concatenated parameters don't match. - return inner - - -def decorator2(f: Callable[P, None]) -> Callable[Concatenate[int, P], None]: - def inner(*args: P.args, **kwargs: P.kwargs) -> None: - f(*args, **kwargs) - - # This should generate an error because the concatenated parameters don't match. - return inner - - -def decorator3(f: Callable[P, None]) -> Callable[Concatenate[int, P], None]: - def inner(var: str, *args: P.args, **kwargs: P.kwargs) -> None: - f(*args, **kwargs) - - # This should generate an error because the concatenated parameters don't match. - return inner - - -def decorator4(f: Callable[P, None]) -> Callable[Concatenate[str, P], None]: - def inner(var: str, *args: P.args, **kwargs: P.kwargs) -> None: - f(*args, **kwargs) - - return inner diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec3.py b/packages/vipeye-internal/src/tests/samples/paramSpec3.py deleted file mode 100644 index 84986276..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec3.py +++ /dev/null @@ -1,131 +0,0 @@ -# This sample tests ParamSpec (PEP 612) behavior. - -from typing import ( - Awaitable, - Callable, - Generic, - Iterable, - ParamSpec, - TypeVar, - overload, -) - -P = ParamSpec("P") -R = TypeVar("R") - - -def decorator1(f: Callable[P, R]) -> Callable[P, Awaitable[R]]: - async def inner(*args: P.args, **kwargs: P.kwargs) -> R: - return f(*args, **kwargs) - - return inner - - -@decorator1 -def func1(x: int, y: str) -> int: - return x + 7 - - -async def func2(): - await func1(1, "A") - - # This should generate an error because - # the first parameter is not an int. - await func1("B", "2") - - -@overload -def func3(x: int) -> None: ... - - -@overload -def func3(x: str) -> str: ... - - -def func3(x: int | str) -> str | None: - if isinstance(x, int): - return None - else: - return x - - -reveal_type( - decorator1(func3), - expected_text="Overload[(x: int) -> Awaitable[None], (x: str) -> Awaitable[str]]", -) - - -class ClassA(Generic[P, R]): - def __init__(self, func: Callable[P, R]): - self.func = func - - -def func4(f: Callable[P, R]) -> ClassA[P, R]: - return ClassA(f) - - -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -def decorator2(f: Callable[P, R]) -> Callable[P, R]: - return f - - -def func5(f: Callable[[], list[T1]]) -> Callable[[list[T2]], list[T1 | T2]]: - def inner(res: list[T2], /) -> list[T1 | T2]: ... - - return decorator2(inner) - - -def func6(x: Iterable[Callable[P, None]]) -> Callable[P, None]: - def inner(*args: P.args, **kwargs: P.kwargs) -> None: - for fn in x: - fn(*args, **kwargs) - - return inner - - -class Callback1: - def __call__(self, x: int | str, y: int = 3) -> None: ... - - -class Callback2: - def __call__(self, x: int, /) -> None: ... - - -class Callback3: - def __call__(self, *args, **kwargs) -> None: ... - - -def func7(f1: Callable[P, R], f2: Callable[P, R]) -> Callable[P, R]: ... - - -def func8(cb1: Callback1, cb2: Callback2, cb3: Callback3): - v1 = func7(cb1, cb2) - reveal_type(v1, expected_text="(x: int, /) -> None") - - v2 = func7(cb1, cb3) - reveal_type(v2, expected_text="(x: int | str, y: int = 3) -> None") - - -def func9(f: Callable[P, object], *args: P.args, **kwargs: P.kwargs) -> object: - # This should generate an error because "name" doesn't exist. - return f(*args, **kwargs, name="") - - -def func10(data: int = 1) -> None: - pass - - -def func11[**P]( - cls: Callable[P, None], data: str, *args: P.args, **kwargs: P.kwargs -) -> None: ... - - -func11(func10, "") -func11(func10, "", 0) - -# This should generate an error because one of the two "data" parameters -# does not have a default value. -func11(func10) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec30.py b/packages/vipeye-internal/src/tests/samples/paramSpec30.py deleted file mode 100644 index 5e33fbb2..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec30.py +++ /dev/null @@ -1,52 +0,0 @@ -# This sample tests a complicated combination of ParamSpec usage. - -# viper: strict - -from typing import Callable, TypeVar, overload -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -_T = TypeVar("_T") -_R = TypeVar("_R") -_P = ParamSpec("_P") - - -@overload -def error_decorator( - error_codes: None = None, -) -> Callable[ - [Callable[Concatenate[_T, _P], _R]], Callable[Concatenate[_T, _P], _R] -]: ... - - -@overload -def error_decorator( - error_codes: list[str], -) -> Callable[ - [Callable[Concatenate[_T, _P], _R]], Callable[Concatenate[_T, _P], _R | None] -]: ... - - -def error_decorator( - error_codes: list[str] | None = None, -) -> Callable[ - [Callable[Concatenate[_T, _P], _R]], Callable[Concatenate[_T, _P], _R | None] -]: - """Filter specific errors and raise custom exception for remaining once.""" - - def decorator( - func: Callable[Concatenate[_T, _P], _R], - ) -> Callable[Concatenate[_T, _P], _R | None]: - def wrapper(self: _T, *args: _P.args, **kwargs: _P.kwargs) -> _R | None: - try: - return func(self, *args, **kwargs) - except Exception as ex: - if error_codes is not None: - return None - raise Exception("Custom exception") from ex - - return wrapper - - return decorator diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec31.py b/packages/vipeye-internal/src/tests/samples/paramSpec31.py deleted file mode 100644 index d6cc5ae6..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec31.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that an Any expression fills in a default signature -# when it binds to a ParamSpec. - -from typing import Any, Callable, TypeVar -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -T = TypeVar("T") -P = ParamSpec("P") - - -def func1(f: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -def func2(a: Any) -> None: - reveal_type(func1(a, 1), expected_text="Any") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec32.py b/packages/vipeye-internal/src/tests/samples/paramSpec32.py deleted file mode 100644 index bb2dae9a..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec32.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample tests the case where a ParamSpec and its P.args and P.kwargs -# parameters are used within a constructor. - -from typing import Callable, Generic, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Concatenate, - ParamSpec, -) - -P = ParamSpec("P") -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -def add_k(x: int, k: int) -> int: - return x + k - - -class Class1(Generic[P, T2]): - def __init__(self, fn: Callable[P, T2], *args: P.args, **kwargs: P.kwargs) -> None: - self.fn = fn - self.args = args - self.kwargs = kwargs - - def __call__(self) -> T2: - return self.fn(*self.args, **self.kwargs) - - -# This should generate an error because arguments x and k are missing. -Class1(add_k) - -# This should generate an error because arguments x has the wrong type. -Class1(add_k, "3", 2) - -Class1(add_k, 3, 2) -Class1(add_k, x=3, k=2) - - -class Class2(Generic[P, T1, T2]): - def __init__( - self, fn: Callable[Concatenate[T1, P], T2], *args: P.args, **kwargs: P.kwargs - ) -> None: - self.fn = fn - self.args = args - self.kwargs = kwargs - - def __call__(self, value: T1) -> T2: - return self.fn(value, *self.args, **self.kwargs) - - -# This should generate an error because argument x is missing. -Class2(add_k) - -# This should generate an error because arguments x has the wrong type. -Class2(add_k, "3") - -Class2(add_k, 2) - -Class2(add_k, k=2) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec33.py b/packages/vipeye-internal/src/tests/samples/paramSpec33.py deleted file mode 100644 index 3cf20a16..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec33.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample verifies that an error is returned if an inner function -# doesn't use P.args and P.kwargs in its parameter list but is returned -# by an outer function that uses P in its return type. - -from typing import Callable, Concatenate -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -P = ParamSpec("P") - - -def func1(func: Callable[P, int]) -> Callable[P, int]: - def inner_func(x: int) -> int: - # This should generate a type error. - return func() - - # This should generate a type error. - return inner_func - - -def func2( - func: Callable[Concatenate[int, P], int], -) -> Callable[Concatenate[int, P], int]: - def inner_func(x: int) -> int: - # This should generate a type error. - return func(x) - - # This should generate a type error. - return inner_func diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec34.py b/packages/vipeye-internal/src/tests/samples/paramSpec34.py deleted file mode 100644 index 82a7aab0..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec34.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the handling of nested functions that involve ParamSpecs. - -import functools -from typing import Callable, TypeVar -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -P = ParamSpec("P") -R = TypeVar("R") - - -def deprecated( - instead: str | None = None, -) -> Callable[[Callable[P, R]], Callable[P, R]]: - def actual_decorator(func: Callable[P, R]) -> Callable[P, R]: - @functools.wraps(func) - def decorated(*args: P.args, **kwargs: P.kwargs) -> R: - return func(*args, **kwargs) - - return decorated - - return actual_decorator diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec35.py b/packages/vipeye-internal/src/tests/samples/paramSpec35.py deleted file mode 100644 index 99cd7c8d..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec35.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample ensures that when solving for a ParamSpec, all assignments -# are consistent. - -from typing import Callable, ParamSpec - -P = ParamSpec("P") - - -def func1(x: Callable[P, int], y: Callable[P, int]) -> Callable[P, bool]: ... - - -def a1(p0: int) -> int: ... - - -def a2(p0: int, p2: str) -> int: ... - - -v1 = func1(a1, a1) -reveal_type(v1, expected_text="(p0: int) -> bool") - -v2 = func1(a2, a2) -reveal_type(v2, expected_text="(p0: int, p2: str) -> bool") - -# This should generate an error because a1 and a2 are not compatible. -v3 = func1(a1, a2) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec36.py b/packages/vipeye-internal/src/tests/samples/paramSpec36.py deleted file mode 100644 index ab4e625c..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec36.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the case where a callback protocol uses a method-scoped -# param spec. - -import contextlib -from concurrent.futures import Future, ThreadPoolExecutor -from typing import Callable, Iterator, ParamSpec, Protocol, TypeVar - -P = ParamSpec("P") -R = TypeVar("R") - - -class TakesFunctionWithArguments(Protocol): - def __call__( - self, func: Callable[P, R], *args: P.args, **kwargs: P.kwargs - ) -> Future[R]: ... - - -@contextlib.contextmanager -def submit_wrapper() -> Iterator[TakesFunctionWithArguments]: - with ThreadPoolExecutor() as pool: - - def my_submit( - func: Callable[P, R], *args: P.args, **kwargs: P.kwargs - ) -> Future[R]: - return pool.submit(func, *args, **kwargs) - - yield my_submit - - -def foo(a: int, b: int, c: int) -> int: - return a + b + c - - -with submit_wrapper() as submit: - submit(foo, a=1, b=2, c=3) - submit(foo, 1, 2, 3) - - # This should generate two errors. - submit(foo, a=1, b=2, d=3) - - # This should generate an error. - submit(foo, 1, 2) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec37.py b/packages/vipeye-internal/src/tests/samples/paramSpec37.py deleted file mode 100644 index ebb16e7f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec37.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where a source type includes a ParamSpec -# and a dest type includes an *args: Any and **kwargs: Any. - -from typing import Any, Callable, Protocol, TypeVar, ParamSpec - -P = ParamSpec("P") -R = TypeVar("R") -T = TypeVar("T") - - -class ClassA(Protocol[R]): - def __call__(self, n: int, /, *args: Any, **kwargs: Any) -> list[R]: ... - - -def noop(v: T) -> T: - return v - - -def func1(maker: Callable[P, R]) -> ClassA[R]: - def inner(n: int, /, *args: P.args, **kwargs: P.kwargs) -> list[R]: - reveal_type(args, expected_text="P@func1.args") - reveal_type(noop(args), expected_text="P@func1.args") - reveal_type(kwargs, expected_text="P@func1.kwargs") - reveal_type(noop(kwargs), expected_text="P@func1.kwargs") - - return [maker(*args, **kwargs) for _ in range(n)] - - return inner diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec38.py b/packages/vipeye-internal/src/tests/samples/paramSpec38.py deleted file mode 100644 index 135f2fc1..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec38.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests that a **kwargs parameter captured by a ParamSpec -# is preserved. - -from typing import Callable, Generic, ParamSpec, TypeVar - - -P = ParamSpec("P") -R = TypeVar("R") - - -class ClassA(Generic[P, R]): - def __init__(self, callback: Callable[P, R]): - self.callback = callback - - def method(self, *args: P.args, **kwargs: P.kwargs) -> R: - return self.callback(*args, **kwargs) - - -def func1(obj: object, **kwargs: object) -> object: ... - - -reveal_type( - ClassA(func1).method, expected_text="(obj: object, **kwargs: object) -> object" -) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec39.py b/packages/vipeye-internal/src/tests/samples/paramSpec39.py deleted file mode 100644 index d3277ce4..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec39.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where a function that uses a ParamSpec -# is passed to itself. This should not cause a crash or infinite recursion -# within the type evaluator. - -from typing import TypeVar, Callable -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -P = ParamSpec("P") -R = TypeVar("R") - - -def func1(x: Callable[P, R]) -> Callable[P, R]: - return x - - -func1(func1) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec4.py b/packages/vipeye-internal/src/tests/samples/paramSpec4.py deleted file mode 100644 index 90fb1c0f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec4.py +++ /dev/null @@ -1,159 +0,0 @@ -# This sample tests the type checker's handling of ParamSpec -# and Concatenate as described in PEP 612. - -from typing import ( - Callable, - Concatenate, - Generic, - Iterable, - ParamSpec, - Protocol, - TypeVar, - assert_type, -) - -P = ParamSpec("P") -R = TypeVar("R") - - -class Request: ... - - -def with_request(f: Callable[Concatenate[Request, P], R]) -> Callable[P, R]: - def inner(*args: P.args, **kwargs: P.kwargs) -> R: - return f(Request(), *args, **kwargs) - - return inner - - -@with_request -def takes_int_str(request: Request, x: int, y: str) -> int: - # use request - return x + 7 - - -takes_int_str(1, "A") - -# This should generate an error because the first arg -# is the incorrect type. -takes_int_str("B", "A") - -# This should generate an error because there are too -# many parameters. -takes_int_str(1, "A", 2) - - -# This should generate an error because a ParamSpec can appear -# only within the last type arg for Concatenate -def decorator1(f: Callable[Concatenate[P, P], int]) -> Callable[P, int]: ... - - -# This should generate an error because the last type arg -# for Concatenate should be a ParamSpec. -def decorator2(f: Callable[Concatenate[int, int], int]) -> Callable[P, int]: ... - - -# This should generate an error because Concatenate is missing -# its type arguments. -def decorator3(f: Callable[Concatenate, int]) -> Callable[P, int]: ... - - -def decorator4(func: Callable[P, None]) -> Callable[Concatenate[int, P], None]: - def wrapper(x: int, /, *args: P.args, **kwargs: P.kwargs) -> None: ... - - return wrapper - - -def func1(func: Callable[Concatenate[int, P], None]) -> Callable[P, None]: ... - - -def func2(a: int, b: str, c: str) -> None: ... - - -def func3(a: int, /, b: str, c: str) -> None: ... - - -def func4(a: int, b: str, /, c: str) -> None: ... - - -v1 = func1(func2) -reveal_type(v1, expected_text="(b: str, c: str) -> None") - -v2 = func1(func3) -reveal_type(v2, expected_text="(b: str, c: str) -> None") - -v3 = func1(func4) -reveal_type(v3, expected_text="(b: str, /, c: str) -> None") - - -def func5(__fn: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R: ... - - -def func6(name: str, *args: str): ... - - -v5 = func5(func6, "a", "b", "c") - -# This should generate an error because 1 isn't assignable to str. -v6 = func5(func6, "a", "b", "c", 1) - - -def func7(name: str, **kwargs: str): ... - - -v7 = func5(func7, "a", b="b", c="c") - -# This should generate an error because 1 isn't assignable to str. -v8 = func5(func7, "a", b="b", c=1) - - -T = TypeVar("T", covariant=True) -X = TypeVar("X") - - -class DecoProto(Protocol[P, T]): - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T: ... - - -def func8(cb: Callable[Concatenate[X, P], T]) -> DecoProto[Concatenate[X, P], T]: - return cb - - -@func8 -def func9(x: Iterable[T]) -> T: - return next(iter(x)) - - -v9 = func9([1, 2]) -reveal_type(v9, expected_text="int") - - -class A(Generic[R, P]): - f: Callable[P, str] - prop: R - - def __init__(self, f: Callable[P, str], prop: R) -> None: - self.f = f - self.prop = prop - - -def func10(q: int, /) -> str: ... - - -y1 = A(func10, 1) -assert_type(y1, A[int, [int]]) -reveal_type(y1, expected_text="A[int, (q: int, /)]") - - -# This should generate an error because Concatenate is not -# allowed in this context. -def func11(func: Concatenate[int, ...]) -> None: - # This should generate an error because Concatenate is not - # allowed in this context. - x: Concatenate[int, ...] - - -class B: - # This should generate an error because Concatenate is not - # allowed in this context. - x: Concatenate[int, ...] diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec40.py b/packages/vipeye-internal/src/tests/samples/paramSpec40.py deleted file mode 100644 index 678b379b..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec40.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the interaction between a generic callable parameterized -# with a ParamSpec and another generic callable that is parameterized -# with a TypeVar. - -from typing import Callable, ParamSpec, TypeVar, TypedDict, Unpack - -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -def call(obj: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: - return obj(*args, **kwargs) - - -def func1(): - return 0 - - -def func2(): - return 0.0 - - -result1 = map(call, [func1]) -reveal_type(result1, expected_text="map[int]") - -result2 = map(call, [func1, func2]) -reveal_type(result2, expected_text="map[float]") - - -class TD1(TypedDict, total=False): - e: str - f: str - - -def func3( - a: int, b: int, /, *, c: str = ..., d: str = ..., **kwargs: Unpack[TD1] -) -> float: ... - - -call(func3, 1, 2, e="", c="") -call(func3, 1, 2, c="", d="", e="") -call(func3, 1, 2, e="") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec41.py b/packages/vipeye-internal/src/tests/samples/paramSpec41.py deleted file mode 100644 index 8226a422..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec41.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where a function-scoped ParamSpec is -# partially specialized through a binding operation. - -from typing import Callable, ParamSpec, Self, reveal_type - -P = ParamSpec("P") - - -class A: - def __init__(self, x: int, y: int, z: str) -> None: - self.a = x - - # This should generate an error. - @classmethod - def f(cls: Callable[P, Self], *args: P.args, **kwargs: P.kwargs) -> int: - return cls(*args, **kwargs).a - - -reveal_type(A.f, expected_text="(x: int, y: int, z: str) -> int") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec42.py b/packages/vipeye-internal/src/tests/samples/paramSpec42.py deleted file mode 100644 index c987b7fb..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec42.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the case where a generic class is parameterized -# by a ParamSpec, and this ParamSpec is used in a method with -# *args and **kwargs parameters. In cases where the ParamSpec captures -# a generic function, the TypeVars for this generic function should -# still be solvable. - -from typing import Callable, Generic, ParamSpec, TypeVar - - -S = TypeVar("S") -T = TypeVar("T") - -P = ParamSpec("P") -R = TypeVar("R") - - -def func1(a: S, b: T) -> dict[S, T]: ... - - -class DecoratorClass1(Generic[P, R]): - def __init__(self, func: Callable[P, R]): - self._func = func - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: - return self._func(*args, **kwargs) - - def other(self, val: int, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -decorated_func1 = DecoratorClass1(func1) - -reveal_type( - decorated_func1, - expected_text="DecoratorClass1[(a: S@func1, b: T@func1), dict[S@func1, T@func1]]", -) - -func1_ret = decorated_func1(1, "") -reveal_type(func1_ret, expected_text="dict[int, str]") - - -func1_other_ret = decorated_func1.other(0, 1, "") -reveal_type(func1_other_ret, expected_text="dict[int, str]") - - -def func2(func: Callable[P, R]) -> Callable[P, R]: ... - - -d1 = func2(func1) -d2 = func2(d1) -d3 = d2(1, "") -reveal_type(d3, expected_text="dict[int, str]") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec43.py b/packages/vipeye-internal/src/tests/samples/paramSpec43.py deleted file mode 100644 index 87923777..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec43.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where a generic class has a function-local -# ParamSpec in its constructor. - -from typing import TypeVar, Callable, ParamSpec, Protocol - -P = ParamSpec("P") -R = TypeVar("R") - - -class Decorator(Protocol): - def __call__(self, __x: Callable[P, R]) -> Callable[P, R]: ... - - -def func1(deco: Decorator): - deco(lambda: None)() - deco(lambda x: x)(1) - deco(lambda x, y: x)(1, "") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec44.py b/packages/vipeye-internal/src/tests/samples/paramSpec44.py deleted file mode 100644 index 237364ab..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec44.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the handling of function assignments that involve -# ParamSpecs. - -from typing import overload, ParamSpec, TypeVar, Callable - -P = ParamSpec("P") -R = TypeVar("R") - - -@overload -def func1(f: Callable[P, R]) -> Callable[P, R]: ... - - -@overload -def func1() -> Callable[[Callable[P, R]], Callable[P, R]]: ... - - -def func1( - f: Callable[P, R] | None = None, -) -> Callable[P, R] | Callable[[Callable[P, R]], Callable[P, R]]: ... diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec45.py b/packages/vipeye-internal/src/tests/samples/paramSpec45.py deleted file mode 100644 index 33fab200..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec45.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the case where the same function that uses a ParamSpec -# is called multiple times as arguments to the same call. - -from typing import Callable, ParamSpec - -P = ParamSpec("P") - - -def func1(func: Callable[P, object], *args: P.args, **kwargs: P.kwargs) -> object: ... - - -def func2(x: str) -> int: ... - - -def func3(y: str) -> int: ... - - -print(func1(func2, x="..."), func1(func3, y="...")) - - -def func4(fn: Callable[P, int], *args: P.args, **kwargs: P.kwargs) -> int: - return fn(*args, **kwargs) - - -def func5(x: int, y: int) -> int: - return x + y - - -func5(func4(lambda x: x, 1), func4(lambda x, y: x + y, 2, 3)) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec46.py b/packages/vipeye-internal/src/tests/samples/paramSpec46.py deleted file mode 100644 index ff68dd7f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec46.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests support for Concatenate with a ... type argument. - -from typing import Callable, Concatenate - -TA1 = Callable[Concatenate[int, ...], None] - - -def func1(cb: Callable[Concatenate[int, str, ...], None]): ... - - -def func2(cb: TA1): ... - - -def cb1(x: int, y: str, z: str) -> None: ... - - -func1(cb1) -func2(cb1) - - -def cb2(x: int, y: str, *args: int, **kwargs: str) -> None: ... - - -func1(cb2) -func2(cb2) - - -def cb3(x: str, y: str) -> None: ... - - -# This should generate an error. -func1(cb3) - -# This should generate an error. -func2(cb3) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec47.py b/packages/vipeye-internal/src/tests/samples/paramSpec47.py deleted file mode 100644 index b19448b7..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec47.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the handling of recursive uses of ParamSpec. - -from typing import Any, Callable, ParamSpec - - -P = ParamSpec("P") - - -def func1(f: Callable[P, Any], *args: P.args, **kwargs: P.kwargs) -> str: ... - - -def func2(a: int) -> int: - return 42 - - -v2 = func1(func2, 42) -reveal_type(v2, expected_text="str") - -# This should generate an error. -func1(func2, "42") - -v3 = func1(func1, func2, 42) -reveal_type(v3, expected_text="str") - -# This should generate an error. -func1(func1, func2, "42") - -# This should generate an error. -func1(func1) - -v4 = func1(func1, lambda: None) -reveal_type(v4, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec48.py b/packages/vipeye-internal/src/tests/samples/paramSpec48.py deleted file mode 100644 index 225c7b1f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec48.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a function with a ParamSpec is called -# with *args and **kwargs that are defined as Any. - -from typing import Any, Callable, Concatenate, ParamSpec - - -P = ParamSpec("P") - - -def func3(f: Callable[Concatenate[int, P], int], *args: Any, **kwargs: Any) -> int: - return f(*args, **kwargs) - - -def func4(f: Callable[Concatenate[int, ...], int], *args: Any, **kwargs: Any) -> int: - return f(*args, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec49.py b/packages/vipeye-internal/src/tests/samples/paramSpec49.py deleted file mode 100644 index 5869d2bb..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec49.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests the case where a function parameterized with a -# ParamSpec P is called with *args: P.args and **kwargs: P.kwargs. - -from typing import Any, Generic, ParamSpec - -P = ParamSpec("P") - - -class TaskDeclaration(Generic[P]): - pass - - -class Dispatcher: - def dispatch( - self, - task_declaration: TaskDeclaration[P], - count: int, - /, - *args: P.args, - **kwargs: P.kwargs, - ) -> None: - pass - - -class Queue: - dispatcher: Dispatcher - - def method1(self, stub: TaskDeclaration[P]) -> Any: - def inner0(*args: P.args, **kwargs: P.kwargs) -> None: - self.dispatcher.dispatch(stub, 1, *args, **kwargs) - - def inner1(*args: P.args, **kwargs: P.kwargs) -> None: - # This should generate an error because a positional argument - # cannot appear after an unpacked keyword argument. - self.dispatcher.dispatch(stub, 1, **kwargs, *args) - - def inner2(*args: P.args, **kwargs: P.kwargs) -> None: - # This should generate an error because it's missing - # a positional argument for 'count'. - self.dispatcher.dispatch(stub, *args, **kwargs) - - def inner3(*args: P.args, **kwargs: P.kwargs) -> None: - # This should generate an error because it has an - # additional positional argument. - self.dispatcher.dispatch(stub, 1, 1, *args, **kwargs) - - def inner4(*args: P.args, **kwargs: P.kwargs) -> None: - # This should generate an error because it is missing - # the *args argument. - self.dispatcher.dispatch(stub, 1, **kwargs) - - def inner5(*args: P.args, **kwargs: P.kwargs) -> None: - # This should generate an error because it is missing - # the *kwargs argument. - self.dispatcher.dispatch(stub, 1, *args) - - def inner6(*args: P.args, **kwargs: P.kwargs) -> None: - # This should generate an error because it has an - # extra *args argument. - self.dispatcher.dispatch(stub, 1, *args, *args, **kwargs) - - # This should generate an error because it has an - # extra **kwargs argument. - self.dispatcher.dispatch(stub, 1, *args, **kwargs, **kwargs) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec5.py b/packages/vipeye-internal/src/tests/samples/paramSpec5.py deleted file mode 100644 index 60ce2ea6..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec5.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests ParamSpec processing when the source -# callable type has keyword-only or positional-only -# parameter separators. - -from typing import Callable, ParamSpec, TypeVar - - -P = ParamSpec("P") -R = TypeVar("R") - - -def decorator(fn: Callable[P, R]) -> Callable[P, R]: - return fn - - -def func1(*, value: str) -> None: ... - - -f1 = decorator(func1) -reveal_type(f1, expected_text="(*, value: str) -> None") - - -def func2(value: str, /) -> None: ... - - -f2 = decorator(func2) -reveal_type(f2, expected_text="(value: str, /) -> None") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec50.py b/packages/vipeye-internal/src/tests/samples/paramSpec50.py deleted file mode 100644 index 5ae51b27..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec50.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the case where a ParamSpec captures another ParamSpec. - -from typing import Callable, Iterator, ParamSpec, TypeVar - -P = ParamSpec("P") -T = TypeVar("T") - - -def deco1(func: Callable[P, Iterator[T]]) -> Callable[P, Iterator[T]]: ... - - -@deco1 -def func1( - func: Callable[P, str], - *func_args: P.args, - **func_kwargs: P.kwargs, -) -> Iterator[str]: ... - - -def func2(a: int, b: float) -> str: ... - - -def func3(a: int) -> str: ... - - -func1(func2, 3, 1.1) - -# This should generate an error. -func1(func2, 3.1, 1.1) - -func1(func3, 3) - -# This should generate an error. -func1(func3) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec51.py b/packages/vipeye-internal/src/tests/samples/paramSpec51.py deleted file mode 100644 index 217b57f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec51.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests a case where a method-scoped ParamSpec is used within one -# of several overloads but not in others. - -from typing import Callable, Concatenate, overload, Any -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - ParamSpec, - Self, -) - -P = ParamSpec("P") - - -class A: - @overload - def method1( - self, - cb: Callable[Concatenate[Self, P], None], - *args: P.args, - **kwargs: P.kwargs, - ) -> None: ... - - @overload - def method1( - self, cb: tuple[Callable[..., None], str], *args: Any, **kwargs: Any - ) -> None: ... - - def method1(self, cb, *args, **kwargs) -> None: - if isinstance(cb, tuple): - cb[0](self, *args, **kwargs) - else: - cb(self, *args, **kwargs) - - -def func1(fo: A, x: int) -> None: ... - - -def func2(fo: A, x: int, /, y: str) -> None: ... - - -def func3(fo: A, x: int, /, y: str, *, z: tuple[int, int]) -> None: ... - - -a = A() - -a.method1(func1, 1) -a.method1(func2, 3, "f1") -a.method1(func3, 6, "f2", z=(0, 1)) - -a.method1((func1, "f1"), 1) -a.method1((func2, "f2"), 2, "a") -a.method1((func3, "f3"), 3, "b", z=(0, 1)) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec52.py b/packages/vipeye-internal/src/tests/samples/paramSpec52.py deleted file mode 100644 index 519f8436..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec52.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests an illegal use of a ParamSpec that resulted in -# a crash. - -from typing import Callable, Generic, ParamSpec - -P = ParamSpec("P") - - -class A(Generic[P]): - def __call__(self, a: int, b: int, *args: P.args, **kwargs: P.kwargs) -> None: ... - - -class B: - # This should generate an error. - x: A[P] - - -# This should generate an error, not crash. -B().x(1) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec53.py b/packages/vipeye-internal/src/tests/samples/paramSpec53.py deleted file mode 100644 index 6d81060b..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec53.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a ParamSpec captures a named parameter -# that is combined with a positional-only parameter of the same name. - -from typing import TypeVar, Callable, ParamSpec - -P = ParamSpec("P") -T = TypeVar("T") - - -class Mixin: - @classmethod - def factory( - cls: Callable[P, T], data: str, /, *args: P.args, **kwargs: P.kwargs - ) -> T: ... - - -class Next(Mixin): - def __init__(self, data: int) -> None: - pass - - -Next.factory("", data=2) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec54.py b/packages/vipeye-internal/src/tests/samples/paramSpec54.py deleted file mode 100644 index a5e904fd..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec54.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests a function that uses a Concatenate with a callback -# that has a *args parameter. - -from typing import Callable, Concatenate, reveal_type - - -def func1[T, **P, R](fn: Callable[Concatenate[T, P], R], val: T) -> Callable[P, R]: ... - - -def test1(*args: str) -> None: ... - - -reveal_type(func1(test1, ""), expected_text="(*args: str) -> None") -reveal_type(func1(func1(test1, ""), ""), expected_text="(*args: str) -> None") - - -def test2(p1: int, *args: str) -> None: ... - - -reveal_type(func1(test2, 0), expected_text="(*args: str) -> None") -reveal_type(func1(func1(test2, 0), ""), expected_text="(*args: str) -> None") -reveal_type(func1(func1(func1(test2, 0), ""), ""), expected_text="(*args: str) -> None") - - -def func2[T1, T2, **P, R]( - fn: Callable[Concatenate[T1, T2, P], R], val1: T1, val2: T2 -) -> Callable[P, R]: ... - - -reveal_type(func2(test1, "", ""), expected_text="(*args: str) -> None") -reveal_type(func2(func2(test1, "", ""), "", ""), expected_text="(*args: str) -> None") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec55.py b/packages/vipeye-internal/src/tests/samples/paramSpec55.py deleted file mode 100644 index 655a7b99..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec55.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a function with a ParamSpec -# is assigned to another function with a Concatenate and a ParamSpec. - -from typing import Any, Concatenate, Callable - - -class MyGeneric[**P0]: - def __call__(self, *args: P0.args, **kwargs: P0.kwargs) -> Any: ... - - -def deco1[**P1](func: Callable[[Callable[P1, Any]], Any]) -> MyGeneric[P1]: ... - - -@deco1 -def func1[**P2](func: Callable[Concatenate[int, P2], Any]): ... - - -reveal_type(func1, expected_text="MyGeneric[(int, **P2@func1)]") - - -v1: MyGeneric[[int]] = func1 - -# This should generate an error. -v2: MyGeneric[[int, int]] = func1 diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec56.py b/packages/vipeye-internal/src/tests/samples/paramSpec56.py deleted file mode 100644 index 2de92a76..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec56.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests a case derived from the wrapt 2.1.x stubs that -# previously caused pyright to hang. A function parameter is typed -# as a union of three generic Callable aliases, each parameterized -# with the same ParamSpec and TypeVar, and the argument is itself a -# generic Callable whose return type is a union (`R | Awaitable[R]`). -# Bidirectional inference must terminate (and not blow up -# combinatorially) on this case. - -from collections.abc import Awaitable, Callable -from typing import Any, ParamSpec, TypeVar - -P = ParamSpec("P") -R = TypeVar("R", covariant=True) - -GenericCallableWrapperFunction = Callable[ - [Callable[P, R], Any, tuple[Any, ...], dict[str, Any]], R -] -ClassMethodWrapperFunction = Callable[ - [type[Any], Callable[P, R], Any, tuple[Any, ...], dict[str, Any]], R -] -InstanceMethodWrapperFunction = Callable[ - [Any, Callable[P, R], Any, tuple[Any, ...], dict[str, Any]], R -] -WrapperFunction = ( - GenericCallableWrapperFunction[P, R] - | ClassMethodWrapperFunction[P, R] - | InstanceMethodWrapperFunction[P, R] -) - - -def wrap_function_wrapper( - target: str, name: str, wrapper: WrapperFunction[P, R] -) -> None: ... - - -def make_async_wrapper[**P1, R1]() -> Callable[ - [Callable[P1, R1], Any, tuple[Any, ...], dict[str, Any]], Awaitable[R1] -]: ... - - -def make_sync_wrapper[**P1, R1]() -> Callable[ - [Callable[P1, R1], Any, tuple[Any, ...], dict[str, Any]], R1 -]: ... - - -def make_wrapper[**P1, R1]( - is_async: bool, -) -> Callable[ - [Callable[P1, R1], Any, tuple[Any, ...], dict[str, Any]], R1 | Awaitable[R1] -]: - return make_async_wrapper() if is_async else make_sync_wrapper() - - -# This call must terminate. The constraint solver sees a cyclic -# constraint (R := R | Awaitable[R]) which has no finite solution, -# so it refuses to bind R and the call returns no useful inferred type. -# Analysis must not hang. -wrap_function_wrapper("example", "target", make_wrapper(False)) diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec6.py b/packages/vipeye-internal/src/tests/samples/paramSpec6.py deleted file mode 100644 index ccb262cc..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec6.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that ParamSpecs support parameters with default values. - -from typing import Callable, ParamSpec, TypeVar - -P = ParamSpec("P") -R = TypeVar("R") - - -def func1(fn: Callable[P, R]) -> Callable[P, R]: ... - - -def func2(a: str, b: str = "") -> str: ... - - -func1(func2)("") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec7.py b/packages/vipeye-internal/src/tests/samples/paramSpec7.py deleted file mode 100644 index 2218a170..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec7.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the handling of a specialized function -# used as an argument to a ParamSpec. - -from typing import Callable, Generic, ParamSpec, TypeVar - -P = ParamSpec("P") -R = TypeVar("R") - - -def func1(f: Callable[P, R]) -> Callable[P, R]: ... - - -class ClassA(Generic[R]): - def method1(self, v: R) -> None: ... - - -v1: ClassA[int] = ClassA() - -reveal_type(v1.method1, expected_text="(v: int) -> None") -reveal_type(func1(v1.method1), expected_text="(v: int) -> None") diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec8.py b/packages/vipeye-internal/src/tests/samples/paramSpec8.py deleted file mode 100644 index c548d8fd..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec8.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests error conditions for ParamSpec (PEP 612). - -from typing import Callable, Concatenate, ParamSpec - -P = ParamSpec("P") - - -def add(f: Callable[P, int]) -> Callable[Concatenate[str, P], None]: - def func1(s: str, *args: P.args, **kwargs: P.kwargs) -> None: # Accepted - pass - - # Parameter 's' and 't' should generate an error according to PEP 612 - def func2(*args: P.args, s: str, t: int, **kwargs: P.kwargs) -> None: # Rejected - pass - - return func1 # Accepted - - -def remove(f: Callable[Concatenate[int, P], int]) -> Callable[P, None]: - def func1(*args: P.args, **kwargs: P.kwargs) -> None: - f(1, *args, **kwargs) # Accepted - - # Should generate an error because positional parameter - # after *args is not allowed. - f(*args, 1, **kwargs) # Rejected - - # Should generate an error because positional parameter - # is missing. - f(*args, **kwargs) # Rejected - - return func1 - - -def outer(f: Callable[P, None]) -> Callable[P, None]: - def func1(x: int, *args: P.args, **kwargs: P.kwargs) -> None: - f(*args, **kwargs) - - def func2(*args: P.args, **kwargs: P.kwargs) -> None: - func1(1, *args, **kwargs) # Accepted - - # This should generate an error because keyword parameters - # are not allowed in this situation. - func1(x=1, *args, **kwargs) # Rejected - - # This should generate an error because *args is duplicated. - func1(1, *args, *args, **kwargs) - - # This should generate an error because **kwargs is duplicated. - func1(1, *args, **kwargs, **kwargs) - - return func2 diff --git a/packages/vipeye-internal/src/tests/samples/paramSpec9.py b/packages/vipeye-internal/src/tests/samples/paramSpec9.py deleted file mode 100644 index c0945cc3..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramSpec9.py +++ /dev/null @@ -1,78 +0,0 @@ -# This sample tests the handling of a ParamSpec used with -# *args: P.args, **kwargs: P.kwargs. - -from typing import Any, Callable, ParamSpec - - -P = ParamSpec("P") - - -def twice(f: Callable[P, int], *args: P.args, **kwargs: P.kwargs) -> int: - return f(*args, **kwargs) + f(*args, **kwargs) - - -def a_int_b_str(a: int, b: str) -> int: - return 1 - - -twice(a_int_b_str, 1, "A") # Accepted - -twice(a_int_b_str, b="A", a=1) # Accepted - -twice(a_int_b_str, 1, b="hi") # Accepted - -# This should generate an error because b is a incorrect type. -twice(a_int_b_str, 1, b=2) # Rejected - -# This should generate an error because a is a incorrect type. -twice(a_int_b_str, "1", b="2") # Rejected - -# This should generate two errors because c is unknown and b is missing. -twice(a_int_b_str, 1, c=2) # Rejected - -# This should generate an error because c is unknown. -twice(a_int_b_str, 1, b="hi", c=2) # Rejected - -# This should generate an error because type of a is wrong. -twice(a_int_b_str, "A", "1") # Rejected - -# This should generate an error because type of b is wrong. -twice(a_int_b_str, 1, 1) # Rejected - -# This should generate an error because of too many arguments. -twice(a_int_b_str, 1, "1", 2) # Rejected - -# This should generate an error because of too few arguments. -twice(a_int_b_str, 1) # Rejected - -# This should generate an error because of too few arguments. -twice(a_int_b_str) # Rejected - - -def func1(func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs): - pass - - -def func2(func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs): - func1(func, *args, **kwargs) - - -def args_b(*args: int, b: str) -> int: - return 1 - - -some_args = (1, 2, 3) - -# This should generate an error because of too few arguments. -twice(args_b) - -# This should generate an error because of too few arguments. -twice(args_b, 3) - -# This should generate an error because it's missing a keyword argument. -twice(args_b, *some_args, 3) - -twice(args_b, *some_args, b="3") - -# This should generate an error because the keyword argument type is incorrect. -twice(args_b, *some_args, b=3) diff --git a/packages/vipeye-internal/src/tests/samples/paramType1.py b/packages/vipeye-internal/src/tests/samples/paramType1.py deleted file mode 100644 index 7e7c5d8f..00000000 --- a/packages/vipeye-internal/src/tests/samples/paramType1.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample validates that parameter types specified for "self" -# and "cls" parameters are compatible with the containing class. - -from typing import Iterator, TypeVar - - -class Parent: - pass - - -_T = TypeVar("_T") -_TChild1 = TypeVar("_TChild1", bound="Child1") - - -class Child1: - def m1(self: "Child1"): ... - - # This should generate an error. - def m2(self: Parent): ... - - # This should generate an error. - def m3(self: type["Child1"]): ... - - def m4(self: _TChild1) -> _TChild1: ... - - # This should generate an error. - def m5(self: type[_TChild1]) -> _TChild1: ... - - def m6(self: _T) -> _T: ... - - # This should generate an error. - def __new__(cls: "Child1"): ... - - @classmethod - def cm1(cls: type["Child1"]): ... - - # This should generate an error. - @classmethod - # This should generate an error. - def cm2(cls: "Child1"): ... - - @classmethod - # This should generate an error. - def cm3(cls: type[Parent]): ... - - @classmethod - def cm4(cls: type[_TChild1]) -> _TChild1: ... - - # This should generate an error. - @classmethod - # This should generate an error. - def cm5(cls: _TChild1) -> _TChild1: ... - - @classmethod - def cm6(cls: type[_T]) -> _T: ... - - -class MyMeta(type): - def m1(self: type[_T]) -> Iterator[_T]: ... diff --git a/packages/vipeye-internal/src/tests/samples/parameters1.py b/packages/vipeye-internal/src/tests/samples/parameters1.py deleted file mode 100644 index fabe4ee9..00000000 --- a/packages/vipeye-internal/src/tests/samples/parameters1.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the reportMissingParameterType check. - - -class A: - # This should generate an error if reportMissingParameterType is enabled - # because 'y' is missing a type annotation. - def method1(self, x: int, _, y) -> int: ... - - def method2(self, x, y): - # type: (int, int) -> int - ... - - -def g(__p: int, x: int, y: str): ... diff --git a/packages/vipeye-internal/src/tests/samples/partial1.py b/packages/vipeye-internal/src/tests/samples/partial1.py deleted file mode 100644 index 558c1907..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial1.py +++ /dev/null @@ -1,175 +0,0 @@ -# This sample tests the functools.partial support. - -from functools import partial -from typing import Callable, Protocol, Self, TypeVar - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2", covariant=True) - - -def func1(): - """func1""" - return 0 - - -p1_0 = partial(func1) - -reveal_type(p1_0(), expected_text="Literal[0]") - -# This should generate an error. -p1_0("") - -# This should generate an error. -p1_1 = partial(func1, "", "") - - -def func2(name: str, number: int) -> None: - """func2""" - pass - - -p2_0 = partial(func2) - -reveal_type(p2_0("", 3), expected_text="None") - -# This should generate an error. -p2_0() - -# This should generate an error. -p2_0("") - -# This should generate an error. -p2_0("", 3, 3) - -# This should generate an error. -p2_0("", 3, 3) - -p2_0("", number=3) - -# This should generate an error. -p2_0("", 3, number=3) - -p2_1 = partial(func2, "") - -# This should generate an error. -p2_1() - -p2_1(3) -p2_1(number=3) - -# This should generate an error. -p2_1(3, number=3) - -p2_2 = partial(func2, number=3) -p2_2("") - -p2_3 = partial(func2, number=3, name="") -p2_3() - - -def func3(name: str, /, number: int): - return 0 - - -p3_0 = partial(func3) - -reveal_type(p3_0("", 3), expected_text="Literal[0]") - -# This should generate an error. -p3_0(name="", number=3) - -p3_1 = partial(func3, "") - -p3_1(3) -p3_1(number=3) - - -def func4(name: str, *, number: int): - return 0 - - -p4_0 = partial(func4) - -# This should generate an error. -p4_0("", 3) - -p4_0("", number=3) - - -def func5(name: _T1, number: _T1) -> _T1: - return name - - -p5_0 = partial(func5) -reveal_type(p5_0(3, 3), expected_text="int") -reveal_type(p5_0("3", "3"), expected_text="str") - - -p5_1 = partial(func5, 2) - -p5_1(3) - -# This should generate an error. -p5_1("3") - - -def func6(a: int, name: _T1, number: _T1) -> _T1: - return name - - -p6_0 = partial(func6, 3, 4) - -reveal_type(p6_0(3), expected_text="int") - - -def func7(a: int, name: float, *args: str): - return 0 - - -p7_0 = partial(func7, 3, 3, "", "", "") -p7_0("", "") - -# This should generate an error. -p7_0(3) - -p7_1 = partial(func7) -p7_1(3, 0) -p7_1(3, 0, "", "") - -# This should generate an error. -p7_1(3, 0, foo=3) - - -def func8(a: int, name: str, **kwargs: int): - return 0 - - -p8_0 = partial(func8, 3, "") -p8_0() -p8_0(foo=3) - -# This should generate an error. -p8_0(foo="") - -p8_1 = partial(func8) -p8_1(3, "") - -# This should generate an error. -p8_1(3) - - -# This should generate an error. -p8_1(3, "", 5) - -p8_1(3, "", foo=4, bar=5) - - -class Partial(Protocol[_T2]): - def __new__(cls, __func: Callable[..., _T2]) -> Self: ... - - -def func9() -> int: ... - - -# This should generate an error. -x: Partial[str] = partial(func9) diff --git a/packages/vipeye-internal/src/tests/samples/partial2.py b/packages/vipeye-internal/src/tests/samples/partial2.py deleted file mode 100644 index c48453c9..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the functools.partial support for keyword parameters. - -from functools import partial -from typing import Protocol - - -def func1(a: int, b: int, x: str) -> str: - return x - - -class Proto1(Protocol): - def __call__(self, x: str) -> str: ... - - -func2: Proto1 = partial(func1, 3, 4, x="a") -func2() -func2(x="b") - - -class Proto2(Protocol): - def __call__(self, b: int) -> str: ... - - -func3: Proto2 = partial(func1, 3, b=3, x="a") -func3() -func3(x="b") -func3(b=3) -func3(x="b", b=3) -func3(b=3, x="b") diff --git a/packages/vipeye-internal/src/tests/samples/partial3.py b/packages/vipeye-internal/src/tests/samples/partial3.py deleted file mode 100644 index 619cdb9e..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial3.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests that the functools.partial special-case logic -# properly handles bidirectional type inference for argument evaluation. - -from functools import partial - - -class BaseClass: - pass - - -class SubClass(BaseClass): - pass - - -def func_base(base: BaseClass): - pass - - -def func_list(base: list[BaseClass]): - pass - - -def func_set(base: set[BaseClass]): - pass - - -sub = SubClass() - -partial(func_base, sub) -partial(func_list, [sub]) -partial(func_set, {sub}) diff --git a/packages/vipeye-internal/src/tests/samples/partial4.py b/packages/vipeye-internal/src/tests/samples/partial4.py deleted file mode 100644 index f5bbafba..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial4.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the case where an overloaded function is passed -# to functools.partial. - -from functools import partial -from typing import overload - - -@overload -def func1(val1: float, val2: float) -> float: ... - - -@overload -def func1(val1: str, val2: str) -> str: ... - - -def func1(val1: float | str, val2: float | str) -> float | str: - return max(val1, val2) - - -def func2(): - op_float = partial(func1, 1.0) - v1 = op_float(2.0) - reveal_type(v1, expected_text="float") - - # This should generate an error. - op_float("a") - - op_str = partial(func1, "a") - v2 = op_str("b") - reveal_type(v2, expected_text="str") - - # This should generate an error. - op_str(1.0) - - # This should generate an error. - op_complex = partial(func1, 3j) diff --git a/packages/vipeye-internal/src/tests/samples/partial5.py b/packages/vipeye-internal/src/tests/samples/partial5.py deleted file mode 100644 index 960193ee..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial5.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the case where a class is passed as the first argument -# to functools.partial. - -from dataclasses import dataclass -from functools import partial -from typing import Self, TypeVar - - -class A: - def __init__(self, x: int, y: int) -> None: ... - - -# This should generate an error because "y" has the wrong type. -v1 = partial(A, x=1, y="a") - -v2 = partial(A, x=1, y=2) -reveal_type(v2, expected_text="partial[A]") -v2() -v2(x=2) - - -T = TypeVar("T", bound=A) - - -def func1(x: type[T]): - # This should generate an error because "z" is not a valid parameter. - v1 = partial(x, x=1, z="a") - - v2 = partial(x, y=1) - - # This should generate an error because it's missing "x". - v2() - - v2(x=1) - - -@dataclass -class B: - x: int - y: str - - @classmethod - def from_x(cls, x: int) -> Self: - make_b = partial(cls, x=x) - reveal_type(make_b, expected_text="partial[Self@B]") - - self = make_b(y="") - reveal_type(self, expected_text="Self@B") - - return self diff --git a/packages/vipeye-internal/src/tests/samples/partial6.py b/packages/vipeye-internal/src/tests/samples/partial6.py deleted file mode 100644 index 8d28674f..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial6.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests functools.partial with an unpacked TypedDict in the -# **kwargs annotation. - -from functools import partial -from typing import TypedDict, Unpack - - -class DC1(TypedDict, total=False): - x: str - y: int - - -def test1(**kwargs: Unpack[DC1]) -> None: ... - - -test1_partial = partial(test1, x="") - -# This should generate an error. -test1_partial(x=1) - -# This should generate an error. -test1_partial(y="") - -test1_partial(x="") -test1_partial(y=1) diff --git a/packages/vipeye-internal/src/tests/samples/partial7.py b/packages/vipeye-internal/src/tests/samples/partial7.py deleted file mode 100644 index 5214c206..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial7.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where functools.partial is applied to -# a function that has a **kwargs parameter that is typed as an -# unpacked TypedDict. - -from functools import partial -from typing import TypedDict, NotRequired, Unpack - - -class TD1(TypedDict): - c: list[str] - a: int - b: NotRequired[str] - - -def func1(**kwargs: Unpack[TD1]) -> None: - print(f"a: {kwargs['a']}, b: {kwargs.get('b')}, c: {kwargs['c']}") - - -func1_1 = partial(func1, c=["a", "b"], a=2) -func1_1(b="2") - -func1_2 = partial(func1, a=2, b="", c=["a", "b"]) -func1_2(a=2, b="2") - -func1_3 = partial(func1, c=["a", "b"]) - -# This should generate an error. -func1_3(b="2") diff --git a/packages/vipeye-internal/src/tests/samples/partial8.py b/packages/vipeye-internal/src/tests/samples/partial8.py deleted file mode 100644 index 7f959f87..00000000 --- a/packages/vipeye-internal/src/tests/samples/partial8.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where functools.partial is applied to -# a function that includes a positional-only parameter separator. - -from functools import partial - - -def func1(s: int, /, a: int, b: str) -> int: ... - - -func1_partial = partial(func1, 1, 0, "") -reveal_type(func1_partial(), expected_text="int") - -func1_partial_missing = partial(func1, 1) -reveal_type(func1_partial_missing(0, ""), expected_text="int") - -# This should generate an error. -partial(func1, s=1) diff --git a/packages/vipeye-internal/src/tests/samples/private1.py b/packages/vipeye-internal/src/tests/samples/private1.py deleted file mode 100644 index 9aa95d53..00000000 --- a/packages/vipeye-internal/src/tests/samples/private1.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests the "reportPrivateUsage" feature. - -from typing import NamedTuple -from .private2 import TestClass, _TestClass, TestClass as _Foo - -_Test = 1 - - -class Foo(object): - _my_var1 = 1 - - _my_var2 = _my_var1 - - def foo(self): - a = _Test - return self._my_var1 - - -# This should generate an error -a = _TestClass() - -b = TestClass() - -a = _Foo() - -# This should generate an error -c = b.__priv1 - - -d = Foo() - -# This should generate an error -e = d._my_var1 - -f = _Test - - -class TestSubclass(TestClass): - def blah(self): - return self._prot1 - - def blah2(self): - # This should generate an error - return self.__priv1 - - -class MyTuple(NamedTuple): - field1: int - field2: str - - -# This should not generate an error because _replace is declared -# within a stub file and is presumably part of the public interface -# contract. -MyTuple(1, "2")._replace(field1=3) diff --git a/packages/vipeye-internal/src/tests/samples/private2.py b/packages/vipeye-internal/src/tests/samples/private2.py deleted file mode 100644 index 48a49ba5..00000000 --- a/packages/vipeye-internal/src/tests/samples/private2.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the "reportPrivateUsage" feature. - - -class _TestClass(object): - pass - - -class TestClass(object): - def __init__(self): - self.__priv1 = 1 - self._prot1 = 1 diff --git a/packages/vipeye-internal/src/tests/samples/private3.py b/packages/vipeye-internal/src/tests/samples/private3.py deleted file mode 100644 index 642e90f1..00000000 --- a/packages/vipeye-internal/src/tests/samples/private3.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests that __all__ membership suppresses reportPrivateUsage -# for module-level single-underscore names. - -__all__ = ["_exported_via_all", "Public"] - - -def _exported_via_all() -> int: - return 1 - - -def _not_exported() -> int: - return 2 - - -class Public: - pass diff --git a/packages/vipeye-internal/src/tests/samples/private4.py b/packages/vipeye-internal/src/tests/samples/private4.py deleted file mode 100644 index 01577ca9..00000000 --- a/packages/vipeye-internal/src/tests/samples/private4.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests that __all__ membership suppresses reportPrivateUsage -# for module-level single-underscore names. - -from .private3 import _exported_via_all, _not_exported - -# This should NOT generate an error: _exported_via_all is listed in -# private3.__all__, so it is part of the module's public interface despite -# the leading underscore. -a = _exported_via_all() - -# This should generate an error: _not_exported is not in __all__. -b = _not_exported() diff --git a/packages/vipeye-internal/src/tests/samples/private5.py b/packages/vipeye-internal/src/tests/samples/private5.py deleted file mode 100644 index 8c48375e..00000000 --- a/packages/vipeye-internal/src/tests/samples/private5.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that single-underscore names remain private when __all__ -# uses an unsupported (computed) form. The binder cannot determine the -# contents of __all__ here, so deferred resolution should still mark _name -# as private. - -_base: list[str] = [] -__all__ = _base + ["public"] - - -def _name() -> int: - return 1 - - -def public() -> int: - return 2 diff --git a/packages/vipeye-internal/src/tests/samples/private6.py b/packages/vipeye-internal/src/tests/samples/private6.py deleted file mode 100644 index 44592856..00000000 --- a/packages/vipeye-internal/src/tests/samples/private6.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that single-underscore names remain private when the -# defining module's __all__ uses an unsupported (computed) form. - -from .private5 import _name, public - -# This should generate an error: private5.__all__ is computed, so _name -# stays private. -a = _name() - -b = public() diff --git a/packages/vipeye-internal/src/tests/samples/property1.py b/packages/vipeye-internal/src/tests/samples/property1.py deleted file mode 100644 index 13f35c3d..00000000 --- a/packages/vipeye-internal/src/tests/samples/property1.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests the type checker's ability to validate -# properties. - - -from typing import Self - - -class ClassA: - @property - def read_only_prop(self): - return 1 - - @property - def read_write_prop(self): - return "hello" - - @read_write_prop.setter - def read_write_prop(self, value: str): - return - - @property - def deletable_prop(self): - return 1 - - @deletable_prop.deleter - def deletable_prop(self): - return - - -a = ClassA() - -# These are disabled because fget, fset and fdel are not -# properly modeled for type checking. -# ClassA.read_only_prop.fget(ClassA()) -# ClassA.read_write_prop.fset(ClassA(), "") -# ClassA.deletable_prop.fdel(ClassA()) - -val = a.read_only_prop - -reveal_type(ClassA.read_only_prop, expected_text="property") -reveal_type(ClassA.read_only_prop.__doc__, expected_text="str | None") - -# This should generate an error because this -# property has no setter. -a.read_only_prop = val - -# This should generate an error because this -# property has no deleter. -del a.read_only_prop - -val = a.read_write_prop - -a.read_write_prop = "hello" - -# This should generate an error because the type -# is incorrect. -a.read_write_prop = ClassA() - -# This should generate an error because this -# property has no deleter. -del a.read_write_prop - -val = a.deletable_prop - -# This should generate an error because this -# property has no setter. -a.deletable_prop = val - -del a.deletable_prop - - -class ClassB: - @property - def name(self) -> str: - return "bar" - - -p1: property = ClassA.read_only_prop -p2: property = ClassA.read_write_prop -p3: property = ClassA.deletable_prop - - -class ClassC: - @property - def prop1(self) -> type[Self]: ... - - def method1(self) -> None: - reveal_type(self.prop1, expected_text="type[Self@ClassC]") - - -class ClassD(ClassC): - def method1(self) -> None: - reveal_type(self.prop1, expected_text="type[Self@ClassD]") diff --git a/packages/vipeye-internal/src/tests/samples/property10.py b/packages/vipeye-internal/src/tests/samples/property10.py deleted file mode 100644 index c2540674..00000000 --- a/packages/vipeye-internal/src/tests/samples/property10.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where properties are unannotated, -# and the type needs to be determined via inference. - - -class ClassA: - def __init__(self): - self._x = None - - @property - def x(self): - return self._x - - @x.setter - def x(self, value): - self._x = value - - -c = ClassA() -reveal_type(c.x, expected_text="Unknown | None") diff --git a/packages/vipeye-internal/src/tests/samples/property11.py b/packages/vipeye-internal/src/tests/samples/property11.py deleted file mode 100644 index f29b2c46..00000000 --- a/packages/vipeye-internal/src/tests/samples/property11.py +++ /dev/null @@ -1,43 +0,0 @@ -# This sample tests the handling of class properties, which -# are supported in Python 3.9 and newer. - - -from typing import TypeVar - - -class Class1: - @classmethod - @property - def prop1(cls) -> str: - return "" - - @classmethod - @prop1.setter - def prop1(cls, value: str): - pass - - -reveal_type(Class1.prop1, expected_text="str") -reveal_type(Class1().prop1, expected_text="str") - -Class1.prop1 = "hi" - -# This should generate an error. -Class1.prop1 = 1 - - -T = TypeVar("T", bound="Class2") - - -class Class2: - @classmethod - @property - def prop1(cls: type[T]) -> type[T]: - return cls - - -class Class3(Class2): ... - - -reveal_type(Class2.prop1, expected_text="type[Class2]") -reveal_type(Class3.prop1, expected_text="type[Class3]") diff --git a/packages/vipeye-internal/src/tests/samples/property12.py b/packages/vipeye-internal/src/tests/samples/property12.py deleted file mode 100644 index bee49b46..00000000 --- a/packages/vipeye-internal/src/tests/samples/property12.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the use of @functools.cache with a property. - -from functools import cache - - -class Rectangle: - def __init__(self, length: int, width: int) -> None: - self._length = length - self._width = width - - @property - @cache - def area(self) -> int: - return self._length * self._width - - -def is_large_rectangle(rec: Rectangle) -> bool: - print(rec.area) - return rec.area >= 100 - - -rec = Rectangle(10, 10) -print(is_large_rectangle(rec)) diff --git a/packages/vipeye-internal/src/tests/samples/property13.py b/packages/vipeye-internal/src/tests/samples/property13.py deleted file mode 100644 index 8595d347..00000000 --- a/packages/vipeye-internal/src/tests/samples/property13.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the case where a property is defined on a metaclass. - - -class MyMeta(type): - @property - def something(cls) -> "Base": - return Base(1234) - - -class Base(metaclass=MyMeta): - def __new__(cls, arg) -> "Base": ... - - -reveal_type(Base.something, expected_text="Base") diff --git a/packages/vipeye-internal/src/tests/samples/property14.py b/packages/vipeye-internal/src/tests/samples/property14.py deleted file mode 100644 index a0ffc08e..00000000 --- a/packages/vipeye-internal/src/tests/samples/property14.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample handles the case where a property setter contains -# a function-scoped TypeVar. - -from typing import Hashable, TypeVar, Sequence - -HashableT = TypeVar("HashableT", bound=Hashable) - - -class ClassA: - def __init__(self): - self._something = [] - - @property - def something(self) -> Sequence[Hashable]: - return self._something - - @something.setter - def something(self, thing: list[HashableT]): - self._something = thing - - -f = ClassA() -f.something = ["a", "b", "c"] diff --git a/packages/vipeye-internal/src/tests/samples/property15.py b/packages/vipeye-internal/src/tests/samples/property15.py deleted file mode 100644 index 2556940d..00000000 --- a/packages/vipeye-internal/src/tests/samples/property15.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the specialization of property return types. - -from typing import TypeVar, Generic - -T = TypeVar("T") - - -class ClassA(Generic[T]): - def __init__(self, bar: T): - self._bar = bar - - @property - def prop1(self) -> T: - return self._bar - - def method1(self) -> T: - reveal_type(self._bar, expected_text="T@ClassA") - return self._bar - - -a = ClassA[int](3) - -# This should work fine because a.bar should be an int -a.prop1.bit_length() diff --git a/packages/vipeye-internal/src/tests/samples/property16.py b/packages/vipeye-internal/src/tests/samples/property16.py deleted file mode 100644 index cccdaeb2..00000000 --- a/packages/vipeye-internal/src/tests/samples/property16.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the case where a property's getter and setter -# are defined in different classes. - -# viper: reportIncompatibleMethodOverride=false - -from typing import Generic, Self, TypeVar - - -T = TypeVar("T") - - -class Parent(Generic[T]): - @property - def prop1(self) -> T: ... - - @property - def prop2(self) -> Self: ... - - -class Child(Parent[str]): - @Parent.prop1.setter - def prop1(self, value: str) -> None: ... - - @Parent.prop2.setter - def prop2(self, value: str) -> None: ... - - -parent = Parent[int]() -reveal_type(parent.prop1, expected_text="int") -reveal_type(parent.prop2, expected_text="Parent[int]") - -# This should generate an error because there is no setter -# on the parent's property. -parent.prop1 = "" - -child = Child() -reveal_type(child.prop1, expected_text="str") -reveal_type(child.prop2, expected_text="Child") - -child.prop1 = "" diff --git a/packages/vipeye-internal/src/tests/samples/property17.py b/packages/vipeye-internal/src/tests/samples/property17.py deleted file mode 100644 index cf1cf1a7..00000000 --- a/packages/vipeye-internal/src/tests/samples/property17.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests a complex intersection between generic protocols -# and properties that are defined in mix-in classes. - -from dataclasses import dataclass -from typing import Generic, Protocol, TypeVar - -T_co = TypeVar("T_co", covariant=True) -T = TypeVar("T") - - -class Proto(Protocol[T_co]): - @property - def prop(self) -> T_co: ... - - -@dataclass -class Model(Generic[T]): - prop: T - - -class RootProto(Protocol[T_co]): - @property - def root(self) -> Proto[T_co]: ... - - -class RootMixin(Generic[T]): - @property - def prop(self: RootProto[T]) -> T: - return self.root.prop - - -@dataclass -class Root(RootMixin[T]): - root: Model[T] - - -def func1(s: Root[str]): - x: Proto[str] = s diff --git a/packages/vipeye-internal/src/tests/samples/property18.py b/packages/vipeye-internal/src/tests/samples/property18.py deleted file mode 100644 index bb091de8..00000000 --- a/packages/vipeye-internal/src/tests/samples/property18.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests the case where a @property decorator is applied to -# a method that has been previously decorated. - -from typing import Concatenate, ParamSpec, Protocol, TypeVar, Callable - -P = ParamSpec("P") -R = TypeVar("R") -S = TypeVar("S", bound="HasAttr") - - -def deco1(func: Callable[P, R]) -> Callable[P, R]: ... - - -class ClassA: - @property - @deco1 - def prop(self) -> int: - return 1 - - -a = ClassA() -reveal_type(a.prop, expected_text="int") - - -class HasAttr(Protocol): - my_attr: str - - -def decorate( - func: Callable[Concatenate[S, P], R], -) -> Callable[Concatenate[S, P], R]: ... - - -class ClassB: - my_attr: str - - @property - @decorate - def prop(self) -> int: - return 1 - - -b = ClassB() -reveal_type(b.prop, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/property19.py b/packages/vipeye-internal/src/tests/samples/property19.py deleted file mode 100644 index 40e50c94..00000000 --- a/packages/vipeye-internal/src/tests/samples/property19.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests support for overloads on property setters. - -from typing import overload - - -class A: - @property - def t1(self) -> int: ... - - @t1.setter - @overload - def t1(self, value: int) -> None: ... - - @t1.setter - @overload - def t1(self, value: None) -> None: ... - - @t1.setter - def t1(self, value: str) -> None: ... - - @t1.deleter - def t1(self) -> None: ... - - -a = A() - -reveal_type(a.t1, expected_text="int") - -# These should not generate errors because they match -# the setter overloads. -a.t1 = 1 -a.t1 = None - -# This should generate an error because str does not match -# any of the setter overloads. -a.t1 = "str" - -# The deleter is defined, so this should not generate an error. -del a.t1 diff --git a/packages/vipeye-internal/src/tests/samples/property2.py b/packages/vipeye-internal/src/tests/samples/property2.py deleted file mode 100644 index 3b87aec4..00000000 --- a/packages/vipeye-internal/src/tests/samples/property2.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests handling of the @abc.abstractproperty decorator. - -import abc - - -def requires_int(x: int): - pass - - -class Foo(abc.ABC): - @abc.abstractproperty - def x(self) -> int: - raise NotImplementedError - - @x.setter - def x(self, value: int): - raise NotImplementedError - - @abc.abstractproperty - def y(self) -> float: - raise NotImplementedError - - -a = Foo() -requires_int(a.x) - -a.x = 3 - -# This should generate an error because a.y is not an int -requires_int(a.y) - -# This should generate an error because the assigned type -# isn't compatible with the setter. -a.x = 4.5 diff --git a/packages/vipeye-internal/src/tests/samples/property20.py b/packages/vipeye-internal/src/tests/samples/property20.py deleted file mode 100644 index feaccd53..00000000 --- a/packages/vipeye-internal/src/tests/samples/property20.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests deprecation reporting for overloaded property setters. - -from typing import overload -from typing_extensions import deprecated # viper: ignore[reportMissingModuleSource] - - -class A: - @property - def t1(self) -> int: ... - - @t1.setter - @overload - @deprecated("Setting t1 to None is deprecated") - def t1(self, value: None) -> None: ... - - @t1.setter - @overload - def t1(self, value: int) -> None: ... - - @t1.setter - def t1(self, value: int | None) -> None: ... - - -a = A() - -# This should be marked deprecated because it resolves to the -# deprecated setter overload. -a.t1 = None - -# This should not be marked deprecated. -a.t1 = 1 diff --git a/packages/vipeye-internal/src/tests/samples/property21.py b/packages/vipeye-internal/src/tests/samples/property21.py deleted file mode 100644 index c9ab8960..00000000 --- a/packages/vipeye-internal/src/tests/samples/property21.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests that a @deprecated marker on an overloaded property -# setter implementation propagates to all of the setter overloads, per PEP 702. - -from typing import overload -from typing_extensions import deprecated # viper: ignore[reportMissingModuleSource] - - -class A: - @property - def t1(self) -> int: ... - - @t1.setter - @overload - def t1(self, value: None) -> None: ... - - @t1.setter - @overload - def t1(self, value: int) -> None: ... - - @t1.setter - @deprecated("Setting t1 is deprecated") - def t1(self, value: int | None) -> None: ... - - -a = A() - -# Both of these should be marked deprecated because the setter -# implementation is deprecated, which propagates to all overloads. -a.t1 = None -a.t1 = 1 diff --git a/packages/vipeye-internal/src/tests/samples/property22.py b/packages/vipeye-internal/src/tests/samples/property22.py deleted file mode 100644 index 17c62bfa..00000000 --- a/packages/vipeye-internal/src/tests/samples/property22.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests a property setter that has exactly one @overload -# signature plus an implementation. This is the edge case where the -# synthesized __set__ has a single overload signature. - -from typing import overload - - -class A: - @property - def t1(self) -> int: ... - - @t1.setter - @overload - def t1(self, value: int) -> None: ... - - @t1.setter - def t1(self, value: str) -> None: ... - - -a = A() - -reveal_type(a.t1, expected_text="int") - -# This should not generate an error because it matches the single -# setter overload signature. -a.t1 = 1 - -# This should generate an error because str matches only the setter -# implementation, which is not counted as an overload signature. -a.t1 = "str" diff --git a/packages/vipeye-internal/src/tests/samples/property23.py b/packages/vipeye-internal/src/tests/samples/property23.py deleted file mode 100644 index 05cdb377..00000000 --- a/packages/vipeye-internal/src/tests/samples/property23.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample documents a current limitation: override-compatibility -# checking is not performed for overloaded property accessors. A subclass -# that overrides an overloaded setter with an incompatible signature is -# not currently flagged by reportIncompatibleMethodOverride because the -# base-class accessor is represented as an OverloadedType, which the -# override-compatibility checks intentionally skip. - -from typing import overload - - -class Base: - @property - def t1(self) -> int: ... - - @t1.setter - @overload - def t1(self, value: int) -> None: ... - - @t1.setter - @overload - def t1(self, value: None) -> None: ... - - @t1.setter - def t1(self, value: int | None) -> None: ... - - -class Derived(Base): - @property - def t1(self) -> int: ... - - # If override-compatibility checking supported overloaded accessors, - # this incompatible setter override would be flagged. It is currently - # not reported (documented limitation); update this sample when that - # support is added. - @t1.setter - def t1(self, value: str) -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/property3.py b/packages/vipeye-internal/src/tests/samples/property3.py deleted file mode 100644 index 708ddb95..00000000 --- a/packages/vipeye-internal/src/tests/samples/property3.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests the type checker's ability to handle -# custom subclasses of property. - - -from typing import Any, Callable - - -class custom_property1(property): - pass - - -class Custom1(object): - @custom_property1 - def x(self) -> int: - return 3 - - @custom_property1 - def y(self) -> float: - return 3.5 - - @y.setter - def y(self, val: float): - pass - - @y.deleter - def y(self): - pass - - -m1 = Custom1() - -a1: int = m1.x - -# This should generate an error because m.x is -# an int and cannot be assigned to str. -b1: str = m1.x - -c1: float = m1.y - -# This should generate an error because m.y is -# a float and cannot be assigned to int. -d1: int = m1.y - -# This should generate an error because there -# is no setter for x. -m1.x = 4 - -m1.y = 4 - -# This should generate an error because there is -# no deleter for x. -del m1.x - -del m1.y - - -class custom_property2(property): - _custom_func: Callable[..., Any] | None - - def custom_function(self, _custom_func: Callable[..., Any]): - self._custom_func = _custom_func - return self - - -class Custom2(object): - @custom_property2 - def x(self) -> int: - return 3 - - @custom_property2 - def y(self) -> float: - return 3.5 - - @y.setter - def y(self, val: float): - pass - - @y.deleter - def y(self): - pass - - @y.custom_function - def y(self): - pass - - -m2 = Custom2() - -a2 = m2.y -reveal_type(a2, expected_text="float") - -m2.y = 4 -del m2.y diff --git a/packages/vipeye-internal/src/tests/samples/property4.py b/packages/vipeye-internal/src/tests/samples/property4.py deleted file mode 100644 index 338eb9ed..00000000 --- a/packages/vipeye-internal/src/tests/samples/property4.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the handling of a property that's defined -# with a generic type for the "self" parameter. - -from typing import TypeVar - - -_P = TypeVar("_P", bound=str) - - -class ClassA(str): - @property - def parent(self: _P) -> _P: ... - - -p = ClassA().parent -reveal_type(p, expected_text="ClassA") diff --git a/packages/vipeye-internal/src/tests/samples/property5.py b/packages/vipeye-internal/src/tests/samples/property5.py deleted file mode 100644 index 272d5c7f..00000000 --- a/packages/vipeye-internal/src/tests/samples/property5.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the specialization of a property -# provided by a generic subclass. - -from typing import TypeVar, Generic - -T = TypeVar("T", bound=int) - - -class Foo(Generic[T]): - def __init__(self, bar: T): - self._bar = bar - - @property - def bar(self) -> T: - return self._bar - - def bar_method(self) -> T: - return self._bar - - -class NewInt(int): - def new_thing(self): - pass - - -class FooNewInt(Foo[NewInt]): - def fizz(self) -> None: - self.bar.new_thing() - self.bar_method().new_thing() diff --git a/packages/vipeye-internal/src/tests/samples/property6.py b/packages/vipeye-internal/src/tests/samples/property6.py deleted file mode 100644 index b2033a10..00000000 --- a/packages/vipeye-internal/src/tests/samples/property6.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the reportPropertyTypeMismatch diagnostic rule. - -from typing import Generic, TypeVar - -_T = TypeVar("_T") - - -class ClassA(Generic[_T]): - @property - def prop_1(self) -> float | None: - return 2 - - @prop_1.setter - def prop_1(self, value: int) -> None: - pass - - @property - def prop_2(self) -> int | None: - return 2 - - # This should generate an error because a float - # is not assignable to an Optional[int]. - @prop_2.setter - def prop_2(self, value: float) -> None: - pass - - @property - def prop_3(self) -> list[_T]: - return [] - - # This should generate an error because _T is - # not assignable to List[_T]. - @prop_3.setter - def prop_3(self, value: _T) -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/property7.py b/packages/vipeye-internal/src/tests/samples/property7.py deleted file mode 100644 index 7c5df669..00000000 --- a/packages/vipeye-internal/src/tests/samples/property7.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests member access expressions where the -# LHS is a class and the RHS is a property. - - -class A: - def __init__(self): - return - - @property - def value(self): - return 42 - - def __getattr__(self, name: str): - return 0 - - -b1 = A.value -# This should generate an error because __getattr__ -# is not applied to a class. -b2 = A.blah -b3 = A.value.fget - - -a = A() - -c1 = a.value -c2 = a.blah -# This should generate an error because a.value is -# the property value. -c3 = a.value.fget diff --git a/packages/vipeye-internal/src/tests/samples/property8.py b/packages/vipeye-internal/src/tests/samples/property8.py deleted file mode 100644 index 92c42f83..00000000 --- a/packages/vipeye-internal/src/tests/samples/property8.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the error reporting for static methods -# used with property getters, setters and deleters. - - -class ClassA: - @property - def legal1(self) -> None: - pass - - # This should generate an error. - @property - @staticmethod - def illegal1() -> None: - pass - - # This should generate an error. - @illegal1.setter - @staticmethod - def illegal1(val: None) -> None: - pass - - # This should generate an error. - @illegal1.deleter - @staticmethod - def illegal1() -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/property9.py b/packages/vipeye-internal/src/tests/samples/property9.py deleted file mode 100644 index 9969c0dc..00000000 --- a/packages/vipeye-internal/src/tests/samples/property9.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample verifies the case where a property returns a callable. - -from typing import Callable - - -class ClassA: - def __init__(self, converter: Callable[[str, int], int]) -> None: - self.converter = converter - - @property - def converter_prop(self) -> Callable[[str, int], int]: - return self.converter - - -def str_to_int(arg: str, base: int) -> int: - return int(arg, base=base) - - -obj = ClassA(str_to_int) -val1: int = obj.converter("123", 10) -val2: int = obj.converter_prop("123", 10) - -reveal_type(obj.converter, expected_text="(str, int) -> int") -reveal_type(obj.converter_prop, expected_text="(str, int) -> int") diff --git a/packages/vipeye-internal/src/tests/samples/protocol1.py b/packages/vipeye-internal/src/tests/samples/protocol1.py deleted file mode 100644 index 2a1d0fec..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol1.py +++ /dev/null @@ -1,137 +0,0 @@ -# This sample tests the type checker's handling of generic protocol types. - -from typing import Generic, Protocol, TypeVar - -T = TypeVar("T") -T_co = TypeVar("T_co", covariant=True) -T_contra = TypeVar("T_contra", contravariant=True) - - -class Box(Protocol[T_co]): - def content(self) -> T_co: ... - - -class Box_Impl: - def content(self) -> int: ... - - -box: Box[float] -second_box: Box[int] = Box_Impl() - -# This should not generate an error due to the covariance of 'Box'. -box = second_box - - -class Sender(Protocol[T_contra]): - def send(self, data: T_contra) -> int: ... - - -class Sender_Impl: - def send(self, data: float) -> int: ... - - -sender: Sender[float] = Sender_Impl() -new_sender: Sender[int] - -# This should not generate an error because 'Sender' is contravariant. -new_sender = sender - - -class Proto(Protocol[T]): - def m1(self, p0: T) -> None: - pass - - attr: T - - -class Proto_Impl: - def m1(self, p0: int) -> None: - pass - - attr: int - - -class NotProto2: - attr: int - - -var: Proto[float] -another_var: Proto[int] = Proto_Impl() - -# This should generate an error because T is invariant. -var = another_var - -another_var2: NotProto2 = NotProto2() - -# This should generate an error because T is invariant. -var = another_var2 - - -# This should generate an error because "Protocol" cannot be used -# as a type argument. -var2: list[Protocol] = [] - - -class Abstract1(Protocol[T_contra]): - def do(self, x: T_contra | None): ... - - -class Concrete1: - def do(self, x: int | None): - pass - - -def use_protocol1(a: Abstract1[int]): - a.do(1) - - -use_protocol1(Concrete1()) - - -# This should generate an error because TypeVars cannot -# be defined in both Protocol and Generic. -class Proto2(Protocol[T_co], Generic[T_co]): ... - - -class Proto3(Protocol, Generic[T_co]): ... - - -_A = TypeVar("_A", covariant=True) -_B = TypeVar("_B", covariant=True, bound=int) - - -class ProtoBase1(Protocol[_A, _B]): ... - - -# This should generate an error because Protocol must -# include all of the TypeVars. -class Proto4(ProtoBase1[_A, _B], Protocol[_A]): ... - - -class ProtoBase2(Protocol[_B]): ... - - -class Proto5(ProtoBase2[_B], Protocol[_A, _B]): ... - - -p5_1: Proto5[float, int] - -# This should generate an error because the second type argument -# corresponds to _B, which is bound to int. -p5_2: Proto5[int, float] - - -def func1(): - # This should generate an error because Protocol isn't - # allowed in a type annotation. - v: Protocol | int - - -# This should generate an error because Protocol isn't -# allowed in a TypeVar bound. -T2 = TypeVar("T2", bound=Protocol | int) - - -# This should generate an error because int is not a TypeVar -class Proto6(Protocol[int]): - pass diff --git a/packages/vipeye-internal/src/tests/samples/protocol10.py b/packages/vipeye-internal/src/tests/samples/protocol10.py deleted file mode 100644 index c0b70657..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol10.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the interactions between the synthesized -# type for "self" and protocol matching. - -from typing import Protocol - - -class ProtocolBase(Protocol): - def a(self) -> None: ... - - def b(self) -> None: ... - - -class ProtocolExtended(ProtocolBase, Protocol): - def c(self) -> None: ... - - -class Base: - def a(self) -> None: - pass - - -class ImplementsBase(Base): - def b(self) -> None: - pass - - -class ImplementsExtended(ImplementsBase): - def c(self) -> None: - pass - - -a: ProtocolExtended -a = ImplementsExtended() diff --git a/packages/vipeye-internal/src/tests/samples/protocol11.py b/packages/vipeye-internal/src/tests/samples/protocol11.py deleted file mode 100644 index d81d7281..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol11.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests the assignment of generic classes to -# a generic protocol in the case where the protocol is -# satisfied by a generic subclass. - -from typing import Generic, Iterator, Optional, TypeVar - - -class Base: - pass - - -_T1 = TypeVar("_T1") -_TBase1 = TypeVar("_TBase1", bound=Base) -_TBase2 = TypeVar("_TBase2", bound=Base) - - -def my_next(__i: Iterator[_T1]) -> _T1: ... - - -class SourceProvider(Generic[_TBase1]): - def __iter__(self): - return self - - -class ManagedSourceProvider(SourceProvider[_TBase2]): - def get(self) -> Optional[_TBase2]: - source = my_next(self) - return source - - def __next__(self) -> _TBase2: - raise NotImplementedError diff --git a/packages/vipeye-internal/src/tests/samples/protocol12.py b/packages/vipeye-internal/src/tests/samples/protocol12.py deleted file mode 100644 index 7013b6f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol12.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample verifies that an error is generated when a non-protocol -# class is used as a base class for a protocol class. - -from typing import Protocol - - -class BaseClass: - x: int - - -class DerivedClass(BaseClass, Protocol): - x: int diff --git a/packages/vipeye-internal/src/tests/samples/protocol13.py b/packages/vipeye-internal/src/tests/samples/protocol13.py deleted file mode 100644 index 48291915..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol13.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the handling of protocol class methods that -# include keyword-only parameters that match to positional parameters -# within class that is being tested for protocol compatibility. - -from typing import Protocol - - -class CollectionProtocol(Protocol): - def watch(self, *, max_time: int | None = ..., key: str | None = ...) -> None: ... - - -class Collection: - def watch(self, key: str | None = None, max_time: int | None = None) -> None: ... - - -# This should not generate an error even though the "keys" and -# "max_time" parameters in Collection.watch are not marked as -# keyword-only parameters and are not in the same order. -col: CollectionProtocol = Collection() diff --git a/packages/vipeye-internal/src/tests/samples/protocol14.py b/packages/vipeye-internal/src/tests/samples/protocol14.py deleted file mode 100644 index 6ce135e1..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol14.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests a protocol that uses generics in the "self" -# parameter. - -from typing import Protocol, Self, TypeVar - -T = TypeVar("T") - - -class HasParent(Protocol): - def get_parent(self: T) -> T: ... - - -GenericNode = TypeVar("GenericNode", bound=HasParent) - - -def generic_get_parent(n: GenericNode) -> GenericNode: - return n.get_parent() - - -class ConcreteNode: - def get_parent(self) -> Self: - return self - - -node = ConcreteNode() -parent = generic_get_parent(node) diff --git a/packages/vipeye-internal/src/tests/samples/protocol15.py b/packages/vipeye-internal/src/tests/samples/protocol15.py deleted file mode 100644 index 5a2e5d73..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol15.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the handling of protocols with properties and -# methods that make use of generics. - -from typing import Callable, Protocol, TypeVar - -T = TypeVar("T") - - -class Proto(Protocol): - @property - def f(self: T) -> T: ... - - def m(self, item: T, callback: Callable[[T], str]) -> str: ... - - -class Concrete: - @property - def f(self: T) -> T: - return self - - def m(self, item: T, callback: Callable[[T], str]) -> str: ... - - -x: Proto = Concrete() diff --git a/packages/vipeye-internal/src/tests/samples/protocol16.py b/packages/vipeye-internal/src/tests/samples/protocol16.py deleted file mode 100644 index 69b8dd20..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol16.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests that function parameter names match in a protocol. - -from typing import Any, Protocol - - -class Session(Protocol): - def execute(self, statement: Any, *args: Any, **kwargs: Any) -> None: ... - - -class CoolSession(Protocol): - def execute(self, stmt: Any, *args: Any, **kwargs: Any) -> None: ... - - -def func1(arg: Session) -> None: ... - - -def func2(x: CoolSession): - # This should generate an error because "statement" and "stmt" don't match. - func1(x) diff --git a/packages/vipeye-internal/src/tests/samples/protocol17.py b/packages/vipeye-internal/src/tests/samples/protocol17.py deleted file mode 100644 index 00ee1599..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol17.py +++ /dev/null @@ -1,95 +0,0 @@ -# This sample tests for generic protocol variance consistency. - -from typing import Protocol, TypeVar -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -# viper: strict - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2", bound=int) -_T3 = TypeVar("_T3", bytes, str) -_T1_co = TypeVar("_T1_co", covariant=True) -_T1_contra = TypeVar("_T1_contra", contravariant=True) - - -class Protocol1(Protocol[_T1, _T2, _T3]): - def m1(self, p0: _T1, p1: _T2, p2: _T3) -> _T1 | _T2: ... - - def m2(self) -> _T1: ... - - def m3(self) -> _T2: ... - - def m4(self) -> _T3: ... - - -# This should generate an error because _T3 should be contravariant -class Protocol2(Protocol[_T1, _T2, _T3]): - def m1(self, p0: _T1, p1: _T2, p2: _T3) -> _T1: ... - - def m2(self) -> _T1: ... - - def m3(self) -> _T2: ... - - -class Protocol3(Protocol[_T1_co]): - def m1(self) -> None: - pass - - -# This should generate an error because _T1 should be contravariant. -class Protocol4(Protocol[_T1]): - def m1(self, p0: _T1) -> None: ... - - -# This should generate an error because _T1_co should be contravariant. -class Protocol5(Protocol[_T1_co]): - # This should generate an error because a covariant TypeVar - # should not be used as a parameter type. - def m1(self, p0: _T1_co) -> None: ... - - -# This should generate an error because _T1 should be covariant. -class Protocol6(Protocol[_T1]): - def m1(self) -> _T1: ... - - -# This should generate an error because _T1_contra should be covariant. -class Protocol7(Protocol[_T1_contra]): - # This should generate an error because a contravariant TypeVar - # should not be used as a return type. - def m1(self) -> _T1_contra: ... - - -class Protocol8(Protocol[_T1]): - def m1(self) -> _T1: ... - - def m2(self, p1: _T1) -> None: - pass - - -P = ParamSpec("P") -R = TypeVar("R", covariant=True) - - -class Callback(Protocol[P, R]): - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -class Protocol9(Protocol[_T1_co]): - @property - def prop1(self) -> _T1_co: ... - - -class Protocol10(Protocol[_T1_co]): - def m1(self) -> type[_T1_co]: ... - - -class Protocol11(Protocol[_T1]): - x: _T1 | None - - -class Protocol12(Protocol[_T1_contra]): - def m1(self: "Protocol12[_T1_contra]", x: _T1_contra) -> None: ... - - @classmethod - def m2(cls: "type[Protocol12[_T1_contra]]") -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/protocol18.py b/packages/vipeye-internal/src/tests/samples/protocol18.py deleted file mode 100644 index 03ceeb50..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol18.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests that instantiation of a protocol is flagged -# as an error. - -from typing import Protocol - - -class A(Protocol): ... - - -# This should generate an error. -A() - - -class B(A): ... - - -B() - - -class C(A, Protocol): ... - - -# This should generate an error. -C() diff --git a/packages/vipeye-internal/src/tests/samples/protocol19.py b/packages/vipeye-internal/src/tests/samples/protocol19.py deleted file mode 100644 index 5a27ec99..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol19.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests the detection of Final mismatches between a protocol -# and a purported instance of a protocol. - -from dataclasses import dataclass, field -from typing import NamedTuple, Protocol, Final - - -class ProtoA(Protocol): - x: Final[int] = field() - - -@dataclass -class ConcreteA: - x: int = 0 - - -# This should generate an error -a1: ProtoA = ConcreteA(0) - - -class ProtoB(Protocol): - y: int - - -@dataclass -class ConcreteB: - y: Final[int] = 0 - - -# This should generate an error -b1: ProtoB = ConcreteB(0) - - -class ProtoC(Protocol): - x: Final[int] - - -class ConcreteC1(NamedTuple): - x: int - - -@dataclass(frozen=True) -class ConcreteC2: - x: int - - -c1: ProtoC = ConcreteC1(0) -c2: ProtoC = ConcreteC2(0) diff --git a/packages/vipeye-internal/src/tests/samples/protocol2.py b/packages/vipeye-internal/src/tests/samples/protocol2.py deleted file mode 100644 index c66e7202..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol2.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the type checker's handling of -# generic protocols with invariant, constrained, and contravariant -# type arguments. - -from typing import TypeVar, Protocol - - -T = TypeVar("T") -StrLike = TypeVar("StrLike", str, bytes) -T_contra = TypeVar("T_contra", contravariant=True) - - -class Writer(Protocol[T_contra]): - def write(self, data: T_contra) -> None: ... - - -class WriteFile: - def write(self, data: bytes) -> None: - pass - - -def f(writer: Writer[bytes]): - pass - - -def g(writer: Writer[T], v: T | None = None): - pass - - -def h(writer: Writer[StrLike], v: StrLike | None = None): - pass - - -w = WriteFile() -f(w) -g(w) -h(w) diff --git a/packages/vipeye-internal/src/tests/samples/protocol20.py b/packages/vipeye-internal/src/tests/samples/protocol20.py deleted file mode 100644 index 06702f96..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol20.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a TypeVar is bound to a -# protocol class. - -from typing import Protocol, TypeVar - - -class ClsProtocol(Protocol): - def __init__(self): ... - - -T1 = TypeVar("T1", bound="ClsProtocol") - - -class Sample: - @classmethod - def test(cls: type[T1]) -> T1: - return cls() - - -reveal_type(Sample.test(), expected_text="Sample") -reveal_type(Sample().test(), expected_text="Sample") diff --git a/packages/vipeye-internal/src/tests/samples/protocol21.py b/packages/vipeye-internal/src/tests/samples/protocol21.py deleted file mode 100644 index 078dda29..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol21.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the handling of protocol classes that define properties -# to indicate a read-only attribute. It also tests that a member access through -# a protocol class (not an instance) is flagged as an error. - -from typing import Protocol - - -class A(Protocol): - @property - def name(self) -> str: ... - - -class B: - name: str - - -def do_something(a: A, class_a: type[A]) -> None: - val1 = a.name - reveal_type(val1, expected_text="str") - - # This should generate an error because accesses to - # properties from a protocol class are not allowed. - val2 = class_a.name - - val3: A = B() diff --git a/packages/vipeye-internal/src/tests/samples/protocol22.py b/packages/vipeye-internal/src/tests/samples/protocol22.py deleted file mode 100644 index 15ecc212..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol22.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests that a type variable existing in a union type -# of multiple type variables is treated as covariant with the -# union type, thus affecting the variance restriction. - -from typing import Protocol, TypeVar - -# viper: strict - -_T1 = TypeVar("_T1") -_T1_co = TypeVar("_T1_co", covariant=True) -_T1_contra = TypeVar("_T1_contra", contravariant=True) - -_T2 = TypeVar("_T2") -_T2_co = TypeVar("_T2_co", covariant=True) -_T2_contra = TypeVar("_T2_contra", contravariant=True) - - -# This is right, as `_T1_co` and `_T2_co` are only covariant with -# return type. -class P1(Protocol[_T1_co, _T2_co]): - def m1(self) -> _T1_co | _T2_co: ... - - -# This is right, as `_T1_contra` and `_T2_contra` are only covariant -# with the argument type. -class P2(Protocol[_T1_contra, _T2_contra]): - def m1(self, a: _T1_contra | _T2_contra) -> None: ... - - -# This is right, as `_T1` and `_T2` are both covariant with the -# argument type and the return type. -class P3(Protocol[_T1, _T2]): - def m1(self, a: _T1, b: _T2) -> _T1 | _T2: ... - - -# This is right, as `_T1` and `_T2` are both covariant with the -# argument type and the return type. -class P4(Protocol[_T1, _T2]): - def m2(self, a: _T1 | _T2) -> tuple[_T1, _T2]: ... diff --git a/packages/vipeye-internal/src/tests/samples/protocol23.py b/packages/vipeye-internal/src/tests/samples/protocol23.py deleted file mode 100644 index f7f7e1bc..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol23.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests the provision in PEP 544 that a protocol class -# can't be assigned to Type[Proto]. - -from abc import abstractmethod -from typing import Protocol - - -class Proto(Protocol): - @abstractmethod - def meth(self) -> int: ... - - -class Concrete: - def meth(self) -> int: - return 42 - - -def func1(cls: type[Proto]) -> int: - return cls().meth() - - -func1(Concrete) - -# This should generate an error because Proto is a protocol class, -# not a concrete class type that implements the protocol. -func1(Proto) - -val1: type[Proto] -val1 = Concrete -val1().meth() - -# This should generate an error because Proto is a protocol class. -val1 = Proto - - -def func2() -> type[Proto]: ... - - -val1 = func2() diff --git a/packages/vipeye-internal/src/tests/samples/protocol24.py b/packages/vipeye-internal/src/tests/samples/protocol24.py deleted file mode 100644 index a0b79c49..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol24.py +++ /dev/null @@ -1,101 +0,0 @@ -# This sample tests the provision in PEP 544 where a class type can -# be assigned to a protocol. - -from typing import Any, ClassVar, Protocol - - -class ProtoA(Protocol): - def meth(_self, x: int) -> int: ... - - -class ProtoB(Protocol): - def meth(_self, self: Any, x: int) -> int: ... - - -class C: - def meth(self, x: int) -> int: ... - - -# This should generate an error because C.meth isn't compatible -# with ProtoA().meth. -a: ProtoA = C - -b: ProtoB = C - - -class ProtoD(Protocol): - var1: int - - @property - def var2(self) -> str: ... - - -class E: - var1: ClassVar[int] - var2: ClassVar[str] - - -class F: - var1: ClassVar[int] - var2: ClassVar[int] - - -d: ProtoD = E - -# This should generate an error because var2 is the wrong type. -e: ProtoD = F - - -class Jumps(Protocol): - def jump(self) -> int: ... - - -class Jumper1: - @classmethod - def jump(cls) -> int: ... - - -class Jumper2: - def jump(self) -> int: ... - - -def do_jump(j: Jumps): - print(j.jump()) - - -do_jump(Jumper1) -do_jump(Jumper2()) - - -class ProtoG1(Protocol): - attr1: ClassVar[int] - - -class ProtoG2(Protocol): - attr1: int - - -class ConcreteG1: - attr1: ClassVar[int] = 1 - - -class ConcreteG2: - attr1: int = 1 - - -class GMeta(type): - attr1: int - - -class ConcreteG3(metaclass=GMeta): - pass - - -# The following four lines should generate an error. -pc1: ProtoG1 = ConcreteG1 -pc2: ProtoG1 = ConcreteG2 -pc3: ProtoG2 = ConcreteG2 -pc4: ProtoG1 = ConcreteG3 - -pc5: ProtoG2 = ConcreteG1 -pc6: ProtoG2 = ConcreteG3 diff --git a/packages/vipeye-internal/src/tests/samples/protocol25.py b/packages/vipeye-internal/src/tests/samples/protocol25.py deleted file mode 100644 index 1ecb4ca5..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol25.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the special-case handling for __slots__ and -# __class_getitem__ during protocol matching. - - -from typing import Any, Iterable, Protocol - - -class B: ... - - -class C: - def __class_getitem__(cls, __item: Any) -> Any: ... - - -class SupportsClassGetItem(Protocol): - __slots__: str | Iterable[str] = () - - def __class_getitem__(cls, __item: Any) -> Any: ... - - -b1: SupportsClassGetItem = B() # OK (missing __class_getitem__ is ignored) -c1: SupportsClassGetItem = C() # OK - - -# This should generate an error because __class_getitem__ is not exempt -# when performing class object protocol matching. -b2: SupportsClassGetItem = B # Error -c2: SupportsClassGetItem = C # OK diff --git a/packages/vipeye-internal/src/tests/samples/protocol26.py b/packages/vipeye-internal/src/tests/samples/protocol26.py deleted file mode 100644 index f7d67b94..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol26.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests protocol class assignment in a case that involves tricky -# recursion. - -from typing import Protocol, Sequence, TypeVar, overload - -_T_co = TypeVar("_T_co", covariant=True) - - -class SupportsIndex(Protocol): - def __index__(self) -> int: ... - - -class TupleLike(Sequence[_T_co]): - @overload - def __getitem__(self, index: SupportsIndex) -> _T_co: ... - - @overload - def __getitem__(self, index: slice) -> "TupleLike[_T_co]": ... - - def __getitem__( - self, index: slice | SupportsIndex - ) -> "_T_co | TupleLike[_T_co]": ... - - -class NestedSequence(Protocol[_T_co]): - @overload - def __getitem__(self, index: int, /) -> "_T_co | NestedSequence[_T_co]": ... - - @overload - def __getitem__(self, index: slice, /) -> "NestedSequence[_T_co]": ... - - -def func(t: TupleLike[int]): - x: int | NestedSequence[int] = t - y: NestedSequence[int] = t diff --git a/packages/vipeye-internal/src/tests/samples/protocol28.py b/packages/vipeye-internal/src/tests/samples/protocol28.py deleted file mode 100644 index e80f64a9..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol28.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests a complicated use case involving multiple -# callback protocols. - -from typing import Protocol, TypeVar, Any - - -_T1 = TypeVar("_T1", contravariant=True) -_T2 = TypeVar("_T2", covariant=True) -_T3 = TypeVar("_T3", covariant=True) - - -class Callable1(Protocol[_T1]): - def __call__(self, __x: _T1) -> Any: ... - - -_T4 = TypeVar("_T4", bound=Callable1[Any]) - - -class Decorator1(Protocol[_T2]): - def __call__(self, __x: Callable1[_T2]) -> Any: ... - - -def decorator1(__x: Decorator1[_T3]) -> Decorator1[_T3]: ... - - -def func1(__x: _T4) -> _T4: ... - - -decorator1(func1) diff --git a/packages/vipeye-internal/src/tests/samples/protocol29.py b/packages/vipeye-internal/src/tests/samples/protocol29.py deleted file mode 100644 index df20dcda..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol29.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the special-case handling of properties that return -# generics within a protocol. - -from functools import partial -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Protocol, - Self, -) -from typing import Any, Callable, TypeVar - -_T = TypeVar("_T", covariant=True) - - -class Partial(Protocol[_T]): - @property - def func(self) -> Callable[..., _T]: ... - - def __new__( - cls: type[Self], __func: Callable[..., _T], *args: Any, **kwargs: Any - ) -> Self: ... - - -def func1(x: Partial[int]): ... - - -func1(partial(int)) diff --git a/packages/vipeye-internal/src/tests/samples/protocol3.py b/packages/vipeye-internal/src/tests/samples/protocol3.py deleted file mode 100644 index 261bb334..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol3.py +++ /dev/null @@ -1,328 +0,0 @@ -# This sample tests the assignment of protocols that -# include property declarations. - -from _typeshed import DataclassInstance -from dataclasses import dataclass -from typing import ( - ClassVar, - ContextManager, - Final, - Generic, - NamedTuple, - Protocol, - Sequence, - TypeVar, -) - - -class Class1(Protocol): - @property - def batch_shape(self) -> int: - return 0 - - -class MockClass1: - def __init__(self, batch_shape: int): - self._batch_shape = batch_shape - - @property - def batch_shape(self) -> int: - return self._batch_shape - - -# This should not generate an error. -d: Class1 = MockClass1(batch_shape=1) - - -class Class2(Protocol): - @property - def batch_shape(self) -> int: - return 0 - - -class MockClass2: - def __init__(self, batch_shape: int): - self._batch_shape = batch_shape - - @property - def batch_shape(self) -> float: - return self._batch_shape - - -# This should generate an error because the -# type of the batch_shape property is not compatible. -e: Class2 = MockClass2(batch_shape=1) - - -class Class3(Protocol): - @property - def batch_shape(self) -> int: - return 0 - - @batch_shape.setter - def batch_shape(self, value: int) -> None: - pass - - -class MockClass3: - def __init__(self, batch_shape: int): - self._batch_shape = batch_shape - - @property - def batch_shape(self) -> int: - return self._batch_shape - - -# This should generate an error because it is missing -# a setter. -f: Class3 = MockClass3(batch_shape=1) - - -class Class4(Protocol): - @property - def batch_shape(self) -> int: - return 0 - - @batch_shape.deleter - def batch_shape(self) -> None: - pass - - -class MockClass4: - def __init__(self, batch_shape: int): - self._batch_shape = batch_shape - - @property - def batch_shape(self) -> int: - return self._batch_shape - - @batch_shape.setter - def batch_shape(self, value: int) -> None: - pass - - -# This should generate an error because it is missing -# a deleter. -g: Class4 = MockClass4(batch_shape=1) - - -_T_co = TypeVar("_T_co", covariant=True) -_Self = TypeVar("_Self") - - -class Class5: - @property - def real(self: _Self) -> _Self: ... - - -class MockClass5(Protocol[_T_co]): - @property - def real(self) -> _T_co: ... - - -foo5 = Class5() -h: MockClass5[Class5] = foo5 - - -P6 = TypeVar("P6", bound="MockClass6") -C6 = TypeVar("C6", bound="Class6") - - -class MockClass6(Protocol): - @property - def bar(self: P6) -> ContextManager[P6]: ... - - -class Class6: - @property - def bar(self: C6) -> ContextManager[C6]: ... - - -i: MockClass6 = Class6() - - -class Proto7(Protocol): - x: str - - -class Class7(NamedTuple): - x: str - - -# This should generate an error because the protocol -# indicates that 'a' must be writable. -a: Proto7 = Class7("") - - -class Proto8(Protocol): - @property - def x(self) -> str: ... - - -class Class8(NamedTuple): - x: str - - -b: Proto8 = Class8("") - - -class Proto9(Protocol): - @property - def x(self) -> str: ... - - @x.setter - def x(self, n: str) -> None: ... - - -class Proto10(Protocol): - x: str - - -class NT9(NamedTuple): - x: str = "" - - -@dataclass(frozen=False) -class DC9: - x: str = "" - - -@dataclass(frozen=True) -class DCFrozen9: - x: str = "" - - -# This should generate an error because named tuple -# attributes are immutable. -p9_1: Proto9 = NT9() - -# This should generate an error because frozen dataclass -# attributes are immutable. -p9_2: Proto9 = DCFrozen9() - -p9_3: Proto9 = DC9() - -# This should generate an error because named tuple -# attributes are immutable. -p10_1: Proto10 = NT9() - -# This should generate an error because frozen dataclass -# attributes are immutable. -p10_2: Proto10 = DCFrozen9() - -p10_3: Proto10 = DC9() - - -class Proto11(Protocol): - val1: ClassVar[Sequence[int]] - - -class Concrete11: - val1: Sequence[int] - - -# This should generate an error because of a ClassVar mismatch. -p11_1: Proto11 = Concrete11() - - -class Proto12(Protocol): - val1: list[int] - - -class Concrete12: - val1: ClassVar = [1, 2, 3] - - -# This should generate an error because of a ClassVar mismatch. -p12_1: Proto12 = Concrete12() - - -def func12(p11: Proto11, p12: Proto12): - # This should generate an error because of a ClassVar mismatch. - v1: Proto12 = p11 - - # This should generate an error because of a ClassVar mismatch. - v2: Proto11 = p12 - - -T13 = TypeVar("T13", covariant=True) - - -class Proto13(Protocol[T13]): - @property - def prop1(self) -> T13: ... - - -class Proto14(Proto13[T13], Protocol): ... - - -class Concrete14(Generic[T13]): - def __init__(self, val: T13): - self.prop1 = val - - -def func14(val: Proto14[T13]): ... - - -func14(Concrete14(1)) - - -class Proto15(Protocol): - @property - def prop1(self) -> int: - return 0 - - -class Concrete15_1: - prop1: Final[int] = 0 - - -class Concrete15_2: - prop1: int = 0 - - -class Concrete15_3: - prop1: int - - def __init__(self): - self.prop1 = 0 - - -@dataclass -class Concrete15_4: - prop1: Final[int] = 0 - - -@dataclass(frozen=True) -class Concrete15_5: - prop1: int = 0 - - -# This should generate an error because it is not a ClassVar in the protocol. -p15_1: Proto15 = Concrete15_1() - -p15_2: Proto15 = Concrete15_2() -p15_3: Proto15 = Concrete15_3() - -p15_4_1: Proto15 = Concrete15_4() -p15_4_2: DataclassInstance = Concrete15_4() - -p15_5_1: Proto15 = Concrete15_5() -p15_5_2: DataclassInstance = Concrete15_5() - - -class Proto16(Protocol): - __name__: str - - -class Concrete16_1(NamedTuple): - other: int - - -@dataclass(frozen=True) -class Concrete16_2: - other: int - - -p16_1: Proto16 = Concrete16_1 -p16_2: Proto16 = Concrete16_2 diff --git a/packages/vipeye-internal/src/tests/samples/protocol30.py b/packages/vipeye-internal/src/tests/samples/protocol30.py deleted file mode 100644 index 699fa235..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol30.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample validates that mutable class and instance variables -# are treated as invariant during protocol matching. - -from typing import ClassVar, Protocol - - -class P1(Protocol): - v1: float - - -class C1(Protocol): - v1: int - - -def func1(c1: C1): - # This should generate an error because v1 is invariant. - x: P1 = c1 - - -class P2(Protocol): - v1: ClassVar[float] - - -class C2(Protocol): - v1: int - - -def func2(c2: C2): - # This should generate an error because v1 is invariant. - x: P2 = c2 diff --git a/packages/vipeye-internal/src/tests/samples/protocol31.py b/packages/vipeye-internal/src/tests/samples/protocol31.py deleted file mode 100644 index 3142cf9a..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol31.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where an implementation of a protocol -# implements a function with a named + positional parameter but -# the protocol has a name-only parameter. - -from typing import Generic, Protocol, TypeVar - -T = TypeVar("T") -Tct = TypeVar("Tct", contravariant=True) - - -class Interface(Protocol[Tct]): - def run(self, *, value1: Tct, value2: int) -> object: ... - - -class Implementation(Generic[Tct]): - def run(self, value2: float, value1: Tct) -> object: - return None - - -def get(_: T) -> Interface[T]: - return Implementation[T]() diff --git a/packages/vipeye-internal/src/tests/samples/protocol32.py b/packages/vipeye-internal/src/tests/samples/protocol32.py deleted file mode 100644 index 222840e4..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol32.py +++ /dev/null @@ -1,79 +0,0 @@ -# This sample tests the case where a protocol class derives from -# another protocol class. - -from typing import Generic, TypeVar, Protocol, overload - -Arg = TypeVar("Arg", contravariant=True) -Value = TypeVar("Value") - - -class Base1(Protocol[Value]): - def method1(self, default: Value) -> Value: ... - - -class Base2(Base1[Value], Protocol): - def method2(self, default: Value) -> Value: ... - - -class Interface(Base2[Value], Protocol[Arg, Value]): - def another(self, arg: Arg) -> None: ... - - -class Implementation1(Generic[Arg, Value]): - def method1(self, default: Value) -> Value: - return default - - def method2(self, default: Value) -> Value: - return default - - def another(self, arg: Arg) -> None: - return - - -def func1(arg: Arg, value: Value) -> Interface[Arg, Value]: - return Implementation1[Arg, Value]() - - -class Implementation2(Generic[Arg, Value]): - def method1(self, default: Value) -> Value: - return default - - def another(self, arg: Arg) -> None: - return - - -def func2(arg: Arg, value: Value) -> Interface[Arg, Value]: - # This should generate an error because - # Implementation2 doesn't implement method2. - return Implementation2[Arg, Value]() - - -class Implementation3(Generic[Arg, Value]): - def method1(self, default: int) -> int: - return default - - def method2(self, default: Value) -> Value: - return default - - def another(self, arg: Arg) -> None: - return - - -def func3(arg: Arg, value: Value) -> Interface[Arg, Value]: - # This should generate an error because - # Implementation3's signature doesn't match. - return Implementation3[Arg, Value]() - - -class Base4(Protocol): - @overload - def method3(self, message: int) -> int: ... - - @overload - def method3(self, message: str) -> str: ... - - def method3(self, message: str | int): - return message - - -class Implementation4(Base4): ... diff --git a/packages/vipeye-internal/src/tests/samples/protocol33.py b/packages/vipeye-internal/src/tests/samples/protocol33.py deleted file mode 100644 index f4346496..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol33.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests a protocol matching case that involves -# a union of TypeVars. - -from typing import Generic, TypeVar, Protocol - -T = TypeVar("T", covariant=True) -U = TypeVar("U", covariant=True) - - -class AProto(Generic[T, U], Protocol): - def f(self) -> T | U: ... - - def g(self) -> "AProto[T, U]": ... - - -class A(Generic[T, U]): - def f(self) -> T | U: - raise NotImplementedError - - def g(self) -> AProto[T, U]: - return A[T, U]() - - -class BProto(Generic[T, U], Protocol): - def f(self) -> T | U: ... - - def g(self) -> "BProto[T, U]": ... - - -class B(Generic[T, U]): - def f(self) -> T | U: - raise NotImplementedError - - def g(self) -> BProto[T, U]: - return B[T, U]() diff --git a/packages/vipeye-internal/src/tests/samples/protocol34.py b/packages/vipeye-internal/src/tests/samples/protocol34.py deleted file mode 100644 index 4ba0958c..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol34.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests a case where a method calls its own constructor -# with a specialized type that uses its own TypeVar and the expected -# type is a protocol. - -from typing import Generic, TypeVar, Protocol - -T = TypeVar("T") - - -class X(Protocol): - def f(self) -> int: ... - - -class Y(Generic[T]): - def f(self) -> T: - raise NotImplementedError - - def g(self) -> X: - # This should generate a type error. - return Y[T]() diff --git a/packages/vipeye-internal/src/tests/samples/protocol35.py b/packages/vipeye-internal/src/tests/samples/protocol35.py deleted file mode 100644 index 0fc1c8a7..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol35.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests that protocol compatibility caching produces -# the correct result when the first example of protocol matching within -# the file does not require invariance enforcement but some later one -# does. The cached protocol compatibility cannot be used in this case. - -from dataclasses import dataclass -from typing import Protocol - - -class P1(Protocol): - x: int - - -class P2(Protocol): - y: P1 - - -@dataclass -class A: - x: int - - -@dataclass -class B: - y: A - - -y: P1 = A(3) - -# This should generate an error. -x: P2 = B(A(3)) - -z: P1 = A(3) diff --git a/packages/vipeye-internal/src/tests/samples/protocol36.py b/packages/vipeye-internal/src/tests/samples/protocol36.py deleted file mode 100644 index 921b11e8..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol36.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the handling of nested protocols. - -from typing import Protocol, TypeVar, overload - -_T_co = TypeVar("_T_co", covariant=True) - - -class NestedSequence(Protocol[_T_co]): - @overload - def __getitem__(self, __i: int) -> _T_co | "NestedSequence[_T_co]": ... - - @overload - def __getitem__(self, __s: slice) -> "NestedSequence[_T_co]": ... - - -def func(v1: list[list[list[int]]]): - a: NestedSequence[int] = v1 - b: NestedSequence[int] = [[[3, 4]]] diff --git a/packages/vipeye-internal/src/tests/samples/protocol37.py b/packages/vipeye-internal/src/tests/samples/protocol37.py deleted file mode 100644 index b007a29a..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol37.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests that a method can be satisfied by a metaclass -# when doing protocol matching. - -from typing import Iterator - - -class StyleMeta(type): - def __iter__(cls) -> Iterator[str]: - yield "a" - yield "b" - yield "c" - - -class Style(metaclass=StyleMeta): - pass - - -x: type[Style] = Style -print(list(x)) diff --git a/packages/vipeye-internal/src/tests/samples/protocol38.py b/packages/vipeye-internal/src/tests/samples/protocol38.py deleted file mode 100644 index cc316cf5..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol38.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the case where a protocol is specialized with -# a literal type. - -from typing import Any, Literal, Protocol, TypeVar - - -class Negatable(Protocol): - def __neg__(self) -> "Negatable": ... - - -def func1(x: Negatable) -> None: ... - - -func1(0) - - -def func2(val: Literal[0, 1]): - func1(val) - - -T = TypeVar("T", covariant=True) - - -class SupportsGetItem(Protocol[T]): - def __getitem__(self, __k: int) -> T: ... - - -def func3(a: tuple[Any, ...]): - x: SupportsGetItem[Literal["a"]] = a - - -def func4(x: SupportsGetItem[T]) -> T: - return x[0] - - -def func5(x: list[int] | list[str]) -> None: - y = func4(x) - reveal_type(y, expected_text="int | str") diff --git a/packages/vipeye-internal/src/tests/samples/protocol39.py b/packages/vipeye-internal/src/tests/samples/protocol39.py deleted file mode 100644 index ba7ed680..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol39.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests that functions (or any callable) conforms to -# a protocol that includes attributes defined in builtins.function. - -from typing import Any, Protocol - - -class SupportsGet(Protocol): - @property - def __get__(self) -> Any: ... - - -def func1(cls: Any) -> None: - pass - - -v1: SupportsGet = func1 diff --git a/packages/vipeye-internal/src/tests/samples/protocol4.py b/packages/vipeye-internal/src/tests/samples/protocol4.py deleted file mode 100644 index c1d4f4f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol4.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests that instance and class variables -# assigned within a Protocol method are flagged as errors. - -from typing import ClassVar, Protocol - - -class ProtoA(Protocol): - a: int - b: ClassVar[str] - - def method(self) -> None: - self.a = 3 - - # This should be an error - self.temp: list[int] = [] - - @classmethod - def cls_method(cls) -> None: - cls.b = "3" - - # This should be an error - cls.test2 = 3 - - -class ProtoB(Protocol): - x: ClassVar[int] - - -class B: - x: int - - -# This should generate an error because x is not a ClassVar in B -# but is a ClassVar in the protocol. -b: ProtoB = B() - - -class ProtoC(Protocol): - x: ClassVar[int] - - -class C: - def __init__(self): - self.x: int = 0 - - -# This should generate an error because x is an instance-only variable -# and doesn't satisfy the ClassVar annotation in the protocol. -c: ProtoC = C() diff --git a/packages/vipeye-internal/src/tests/samples/protocol40.py b/packages/vipeye-internal/src/tests/samples/protocol40.py deleted file mode 100644 index 7d6922a4..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol40.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests that the Self type in a Protocol subclass is partially -# specialized appropriately during protocol matching. - -from typing import Generic, Protocol, TypeVar, Self - -T = TypeVar("T", covariant=True) -S = TypeVar("S", covariant=True) - - -class P1Parent(Protocol[S]): - def f0(self, /) -> Self: ... - - -class P1Child(P1Parent[S], Protocol[S]): ... - - -class C1(Generic[T]): - def f0(self, /) -> Self: ... - - -a1: P1Parent[str] = C1[str]() -b1: P1Child[str] = C1[str]() - - -class P2Parent(Protocol[T]): - def f0(self, right: Self, /) -> "P2Parent[T]": - return right - - -class P2Child(P2Parent[T], Protocol[T]): ... - - -class C2(Generic[S]): - def f0(self, other: Self) -> "C2[S]": - return other - - -a2: P2Parent[str] = C2[str]() -b2: P2Child[str] = C2[str]() diff --git a/packages/vipeye-internal/src/tests/samples/protocol41.py b/packages/vipeye-internal/src/tests/samples/protocol41.py deleted file mode 100644 index 2af2e129..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol41.py +++ /dev/null @@ -1,73 +0,0 @@ -# This sample verifies that a generic protocol that is specialized with -# a type variable can be matched if that type variable's type is -# supplied by another argument in a call. - -from typing import Any, Protocol, TypeVar, overload - -_T_co = TypeVar("_T_co", covariant=True) -_T_contra = TypeVar("_T_contra", contravariant=True) - - -class MyStr: ... - - -class MyBytes: - def __buffer__(self, __flags: int) -> memoryview: ... - - -MyAnyStr = TypeVar("MyAnyStr", MyStr, MyBytes) - - -class Buffer(Protocol): - def __buffer__(self, __flags: int) -> memoryview: ... - - -class SupportsRead(Protocol[_T_co]): - def read(self, __length: int = ...) -> _T_co: ... - - -class SupportsWrite(Protocol[_T_contra]): - def write(self, __s: _T_contra) -> object: ... - - -class BufferedWriter: - def write(self, __buffer: Buffer) -> int: - raise NotImplementedError - - -def func1(s: SupportsRead[MyAnyStr], t: SupportsWrite[MyAnyStr]) -> None: ... - - -def test1(src: SupportsRead[MyBytes], tgt: BufferedWriter) -> None: - func1(src, tgt) - - -def test2(src: Any, tgt: BufferedWriter) -> None: - func1(src, tgt) - - -AnyStr_contra = TypeVar("AnyStr_contra", str, bytes, contravariant=True) - - -class BytesIO: - def write(self, __b: Buffer) -> None: - pass - - -class WriteBuffer(Protocol[AnyStr_contra]): - def write(self, __b: AnyStr_contra) -> Any: ... - - -class NDFrame: - @overload - def to_csv(self, p: WriteBuffer[bytes]) -> None: ... - - @overload - def to_csv(self, p: None = ...) -> str: ... - - def to_csv(self, p: Any = None) -> Any: ... - - -def test3(b: BytesIO) -> None: - df = NDFrame() - df.to_csv(b) diff --git a/packages/vipeye-internal/src/tests/samples/protocol42.py b/packages/vipeye-internal/src/tests/samples/protocol42.py deleted file mode 100644 index 38426dc7..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol42.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a protocol implementation uses a -# method-scoped type variable. - -from typing import Protocol, Sequence, TypeVar - -Input = TypeVar("Input", contravariant=True) -Output = TypeVar("Output", covariant=True) -T = TypeVar("T") - - -class ProtoA(Protocol[Input, Output]): - def __call__(self, input: Input) -> Output: - raise NotImplementedError - - -class ImplA: - def __call__(self, input: Sequence[T]) -> T: - return input[0] - - -v1: ProtoA[Sequence[int], int] = ImplA() diff --git a/packages/vipeye-internal/src/tests/samples/protocol43.py b/packages/vipeye-internal/src/tests/samples/protocol43.py deleted file mode 100644 index fcb90d14..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol43.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the handling of generic protocols or protocols -# with generic methods. - -from typing import Protocol, Sequence, TypeVar - -A = TypeVar("A") - - -class HasAdd1(Protocol[A]): - def __add__(self: A, other: A) -> A: ... - - -T1 = TypeVar("T1", bound=HasAdd1) - - -def merge_element_lists1(a: Sequence[T1], b: Sequence[T1]) -> Sequence[T1]: - retval: Sequence[T1] = [] - for a_elem in a: - for b_elem in b: - retval.append(a_elem + b_elem) - return retval - - -# This is similar to HasAdd1 except that the class isn't generic. -class HasAdd2(Protocol): - def __add__(self: A, other: A) -> A: ... - - -T2 = TypeVar("T2", bound=HasAdd2) - - -def merge_element_lists2(a: Sequence[T2], b: Sequence[T2]) -> Sequence[T2]: - retval: Sequence[T2] = [] - for a_elem in a: - for b_elem in b: - retval.append(a_elem + b_elem) - return retval diff --git a/packages/vipeye-internal/src/tests/samples/protocol44.py b/packages/vipeye-internal/src/tests/samples/protocol44.py deleted file mode 100644 index 00206023..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol44.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where protocol matching requires that the type -# parameter for the concrete class map to a union of types in the protocol. - -from typing import Iterable, Protocol, TypeVar - -K = TypeVar("K") -V = TypeVar("V") - - -class SpecialDict(Protocol[K, V]): - def items(self) -> Iterable[tuple[K, V | int]]: ... - - def __getitem__(self, __key: K) -> V | int: ... - - def __setitem__(self, __key: K, __value: V | int) -> None: ... - - -def func1(k: K, v: V) -> SpecialDict[K, V]: - x1: SpecialDict[K, V] = {k: v} - x2: SpecialDict[K, V] = {k: v, k: 1} - x3: SpecialDict[K, V] = {k: 0} - return {} diff --git a/packages/vipeye-internal/src/tests/samples/protocol45.py b/packages/vipeye-internal/src/tests/samples/protocol45.py deleted file mode 100644 index 566ffd07..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol45.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests a case where a protocol method has a method-scoped -# type parameter. - -from typing import Callable, Generic, Protocol, TypeVar - -S = TypeVar("S") -T = TypeVar("T") -Input = TypeVar("Input") -Output = TypeVar("Output") - - -class Proto1(Protocol): - def __call__(self, item: S, /) -> S: ... - - -class Impl1: - def __call__(self, item: T, /) -> T: - return item - - -class Wrapper(Generic[Input, Output]): - def __init__(self, f: Callable[[Input], Output]) -> None: - self.__f = f - - def __call__(self, item: Input, /) -> Output: - return self.__f(item) - - -y = Wrapper(Impl1()) -reveal_type(y, expected_text="Wrapper[T@__call__, T@__call__]") -x: Proto1 = y diff --git a/packages/vipeye-internal/src/tests/samples/protocol46.py b/packages/vipeye-internal/src/tests/samples/protocol46.py deleted file mode 100644 index 274c6db0..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol46.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests protocol matching for multiple protocols that refer -# to each other in a recursive fashion. In particular, this sample tests -# the case where a "cls" parameter is annotated with a protocol type. - -from typing import Never, Self, TypeVar, Protocol - -T_contra = TypeVar("T_contra", contravariant=True) -T = TypeVar("T") - - -class ProtoA(Protocol[T_contra, T]): - def method1(self, value: T_contra) -> "ProtoA[T_contra, T]": ... - - @classmethod - def method2(cls, value: T) -> T: ... - - -class ProtoB(Protocol[T_contra, T]): - def method3(self) -> ProtoA[T_contra, T]: ... - - -class ImplA: - def method1(self, value: int) -> Self: ... - - @classmethod - def method2(cls, value: int) -> int: ... - - -class ImplB: - def method3(self) -> ImplA: ... - - def method1(self, value: int) -> Self: ... - - @classmethod - def method2(cls: type[ProtoB[Never, T]], value: list[T]) -> list[T]: ... - - -def func1(x: ProtoA[Never, T]) -> T: ... - - -v1 = func1(ImplB()) -reveal_type(v1, expected_text="list[int]") diff --git a/packages/vipeye-internal/src/tests/samples/protocol47.py b/packages/vipeye-internal/src/tests/samples/protocol47.py deleted file mode 100644 index 57b6eb90..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol47.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests protocol matching for a protocol and an implementation -# that use a mixture of class-scoped and function-scoped TypeVars. - -from typing import Generic, Protocol, TypeVar - -T1 = TypeVar("T1", covariant=True) -T2 = TypeVar("T2") - - -class ProtoA(Protocol[T1]): - def method1(self, __key: str, __default: T2) -> "T1 | T2": ... - - -T3 = TypeVar("T3", covariant=True) -T4 = TypeVar("T4") - - -class A(Generic[T3]): - def method1(self, key: str, default: T4) -> "T3 | T4": - raise NotImplementedError - - -a1: A[str] = A() - - -def func1(storage: ProtoA[str]): ... - - -v1: ProtoA[str] = a1 -func1(a1) - - -def func2(storage: ProtoA[int]): ... - - -# This should generate an error. -v2: ProtoA[int] = a1 - -# This should generate an error. -func2(a1) diff --git a/packages/vipeye-internal/src/tests/samples/protocol48.py b/packages/vipeye-internal/src/tests/samples/protocol48.py deleted file mode 100644 index 9a36e469..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol48.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the handling of the Self type during protocol matching. - -from typing import Protocol, Self, TypeVar - -T = TypeVar("T", covariant=True) - - -class SupportsMethod1(Protocol[T]): - def method1(self) -> T: ... - - -def apply_method1(__x: SupportsMethod1[T]) -> T: ... - - -class A: - def method1(self) -> tuple[Self, Self]: ... - - def method2(self): - x = apply_method1(self) - reveal_type(x, expected_text="tuple[Self@A, Self@A]") - - -def func1(a: A): - x = apply_method1(a) - reveal_type(x, expected_text="tuple[A, A]") diff --git a/packages/vipeye-internal/src/tests/samples/protocol49.py b/packages/vipeye-internal/src/tests/samples/protocol49.py deleted file mode 100644 index 72f5f06c..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol49.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a protocol is matched against a -# dataclass. Dataclass fields need to act as if they are instance -# members rather than class members, which means a callable stored -# in a dataclass member should not be bound to the dataclass itself. - -from dataclasses import dataclass -from typing import Callable, Protocol - - -class HasA(Protocol): - @property - def a(self) -> Callable[[int], int]: ... - - -@dataclass -class A: - a: Callable[[int], int] - - -def func1(a: A): - has_a: HasA = a diff --git a/packages/vipeye-internal/src/tests/samples/protocol5.py b/packages/vipeye-internal/src/tests/samples/protocol5.py deleted file mode 100644 index 3157801c..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol5.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample is taken from PEP 544. It verifies that -# the type checker allows instance variables that are initialized -# in a method to be counted toward conformance to a defined Protocol. - -from typing import Protocol - - -class Template(Protocol): - name: str # This is a protocol member - value: int = 0 # This one too (with default) - - def method(self) -> None: - pass - - -class Concrete: - def __init__(self, name: str, value: int) -> None: - self.name = name - self.value = value - - def method(self) -> None: - return - - -var: Template = Concrete("value", 42) diff --git a/packages/vipeye-internal/src/tests/samples/protocol50.py b/packages/vipeye-internal/src/tests/samples/protocol50.py deleted file mode 100644 index 54627c67..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol50.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where a protocol is used as a type argument -# for itself. - -from typing import Generic, Protocol, TypeVar - -V_co = TypeVar("V_co", covariant=True) - - -class Proto1(Protocol[V_co]): - def f(self, /) -> V_co: ... - - -class Concrete1(Generic[V_co]): - def f(self, /) -> V_co: ... - - -def func1(v0: Concrete1[Concrete1[object]]): - v2: Proto1[Proto1[object]] = v0 diff --git a/packages/vipeye-internal/src/tests/samples/protocol51.py b/packages/vipeye-internal/src/tests/samples/protocol51.py deleted file mode 100644 index f7acb6ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol51.py +++ /dev/null @@ -1,6 +0,0 @@ -# This sample tests a regression case related to the protocol compatibility -# cache. - - -int(round(1.2, 0)) -round(3.4, 2) diff --git a/packages/vipeye-internal/src/tests/samples/protocol52.py b/packages/vipeye-internal/src/tests/samples/protocol52.py deleted file mode 100644 index ebd0437d..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol52.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a protocol includes a callable -# attribute that is an instance variable. It shouldn't be bound -# to the concrete class in this case. - -from typing import Callable, Protocol - - -class A: - def __init__(self, *, p1: int, p2: str) -> None: ... - - -class ProtoB[**P, T](Protocol): - x: Callable[P, T] - - -class B: - x: type[A] - - -def func1[**P, T](v: ProtoB[P, T]) -> Callable[P, T]: ... - - -x1 = func1(B()) -reveal_type(x1, expected_text="(*, p1: int, p2: str) -> A") diff --git a/packages/vipeye-internal/src/tests/samples/protocol53.py b/packages/vipeye-internal/src/tests/samples/protocol53.py deleted file mode 100644 index c3cec832..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol53.py +++ /dev/null @@ -1,212 +0,0 @@ -# This sample tests protocol matching and override compatibility checks -# for cases involving `Self`. - -from typing import Protocol, Self - - -class Proto_CoRecurs(Protocol): - def m(self) -> "Proto_CoRecurs": ... - - -class Proto_CoSelf(Protocol): - def m(self) -> Self: ... - - -class Proto_CoGeneric(Protocol): - def m[T: Proto_CoGeneric](self: T) -> T: ... - - -class Impl_CoRecurs: - def m(self) -> "Impl_CoRecurs": ... - - -class Impl_CoSelf: - def m(self) -> Self: ... - - -class Impl_CoGeneric: - def m[T: Impl_CoGeneric](self: T) -> T: ... - - -class Impl_CoOther: - def m(self) -> Impl_CoSelf: ... - - -class Impl_CoRecursExplicit1(Proto_CoRecurs): - def m(self) -> "Impl_CoRecursExplicit1": ... - - -class Impl_CoSelfExplicit1(Proto_CoRecurs): - def m(self) -> Self: ... - - -class Impl_CoGenericExplicit1(Proto_CoRecurs): - def m[T: Impl_CoGenericExplicit1](self: T) -> T: ... - - -class Impl_CoOtherExplicit1(Proto_CoRecurs): - def m(self) -> Impl_CoSelf: ... - - -class Impl_CoRecursExplicit2(Proto_CoSelf): - def m(self) -> "Impl_CoRecursExplicit2": ... - - -class Impl_CoSelfExplicit2(Proto_CoSelf): - def m(self) -> Self: ... - - -class Impl_CoGenericExplicit2(Proto_CoSelf): - def m[T: Impl_CoGenericExplicit2](self: T) -> T: ... - - -class Impl_CoOtherExplicit2(Proto_CoSelf): - # This should generate a reportIncompatibleMethodOverride error. - def m(self) -> Impl_CoSelf: ... - - -class Impl_CoRecursExplicit3(Proto_CoGeneric): - def m(self) -> "Impl_CoRecursExplicit3": ... - - -class Impl_CoSelfExplicit3(Proto_CoGeneric): - def m(self) -> Self: ... - - -class Impl_CoGenericExplicit3(Proto_CoGeneric): - def m[T: Impl_CoGenericExplicit3](self: T) -> T: ... - - -class Impl_CoOtherExplicit3(Proto_CoGeneric): - # This should generate a reportIncompatibleMethodOverride error - # but does not currently. - def m(self) -> Impl_CoSelf: ... - - -x01: Proto_CoRecurs = Impl_CoRecurs() -x02: Proto_CoRecurs = Impl_CoSelf() -x03: Proto_CoRecurs = Impl_CoGeneric() -x04: Proto_CoRecurs = Impl_CoOther() - -x11: Proto_CoSelf = Impl_CoRecurs() -x12: Proto_CoSelf = Impl_CoSelf() -x13: Proto_CoSelf = Impl_CoGeneric() -# This should generate a reportAsignmentType error. -x14: Proto_CoSelf = Impl_CoOther() - -x21: Proto_CoGeneric = Impl_CoRecurs() -x22: Proto_CoGeneric = Impl_CoSelf() -x23: Proto_CoGeneric = Impl_CoGeneric() -# This should generate a reportAsignmentType error. -x24: Proto_CoGeneric = Impl_CoOther() - - -class Proto_ContraRecurs(Protocol): - def m(self, x: "Proto_ContraRecurs") -> None: ... - - -class Proto_ContraSelf(Protocol): - def m(self, x: Self) -> None: ... - - -class Proto_ContraGeneric(Protocol): - def m[T: Proto_ContraGeneric](self: T, x: T) -> None: ... - - -class Impl_ContraRecurs: - def m(self, x: "Impl_ContraRecurs") -> None: ... - - -class Impl_ContraSelf: - def m(self, x: Self) -> None: ... - - -class Impl_ContraGeneric: - def m[T: Impl_ContraGeneric](self: T, x: T) -> None: ... - - -class Impl_ContraOther: - def m(self, x: Impl_ContraSelf) -> None: ... - - -class Impl_ContraRecursExplicit1(Proto_ContraRecurs): - # This should generate a reportIncompatibleMethodOverride error. - def m(self, x: "Impl_ContraRecursExplicit1") -> None: ... - - -class Impl_ContraSelfExplicit1(Proto_ContraRecurs): - # This should generate a reportIncompatibleMethodOverride error. - def m(self, x: Self) -> None: ... - - -class Impl_ContraGenericExplicit1(Proto_ContraRecurs): - # This should generate a reportIncompatibleMethodOverride error. - def m[T: Impl_ContraGenericExplicit1](self: T, x: T) -> None: ... - - -class Impl_ContraOtherExplicit1(Proto_ContraRecurs): - # This should generate a reportIncompatibleMethodOverride error. - def m(self, x: Impl_ContraSelf) -> None: ... - - -class Impl_ContraRecursExplicit2(Proto_ContraSelf): - def m(self, x: "Impl_ContraRecursExplicit2") -> None: ... - - -class Impl_ContraSelfExplicit2(Proto_ContraSelf): - def m(self, x: Self) -> None: ... - - -class Impl_ContraGenericExplicit2(Proto_ContraSelf): - def m[T: Impl_ContraGenericExplicit2](self: T, x: T) -> None: ... - - -class Impl_ContraOtherExplicit2(Proto_ContraSelf): - # This should generate a reportIncompatibleMethodOverride error. - def m(self, x: Impl_ContraSelf) -> None: ... - - -class Impl_ContraRecursExplicit3(Proto_ContraGeneric): - # This should not generate a reportIncompatibleMethodOverride error - # but does currently. - def m(self, x: "Impl_ContraRecursExplicit3") -> None: ... - - -class Impl_ContraSelfExplicit3(Proto_ContraGeneric): - # This should not generate a reportIncompatibleMethodOverride error - # but does currently. - def m(self, x: Self) -> None: ... - - -class Impl_ContraGenericExplicit3(Proto_ContraGeneric): - # This should not generate a reportIncompatibleMethodOverride error - # but does currently. - def m[T: Impl_ContraGenericExplicit3](self: T, x: T) -> None: ... - - -class Impl_ContraOtherExplicit3(Proto_ContraGeneric): - # This should not generate a reportIncompatibleMethodOverride error - # but does currently. - def m(self, x: Impl_ContraSelf) -> None: ... - - -# This should generate a reportAsignmentType error. -y01: Proto_ContraRecurs = Impl_ContraRecurs() -# This should generate a reportAsignmentType error. -y02: Proto_ContraRecurs = Impl_ContraSelf() -# This should generate a reportAsignmentType error. -y03: Proto_ContraRecurs = Impl_ContraGeneric() -# This should generate a reportAsignmentType error. -y04: Proto_ContraRecurs = Impl_ContraOther() - -y11: Proto_ContraSelf = Impl_ContraRecurs() -y12: Proto_ContraSelf = Impl_ContraSelf() -y13: Proto_ContraSelf = Impl_ContraGeneric() -# This should generate a reportAsignmentType error. -y14: Proto_ContraSelf = Impl_ContraOther() - -y21: Proto_ContraGeneric = Impl_ContraRecurs() -y22: Proto_ContraGeneric = Impl_ContraSelf() -y23: Proto_ContraGeneric = Impl_ContraGeneric() -# This should generate a reportAsignmentType error. -y24: Proto_ContraGeneric = Impl_ContraOther() diff --git a/packages/vipeye-internal/src/tests/samples/protocol6.py b/packages/vipeye-internal/src/tests/samples/protocol6.py deleted file mode 100644 index 880569af..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol6.py +++ /dev/null @@ -1,86 +0,0 @@ -# This sample tests nested protocol definitions. - -from typing import Literal, Protocol, TypeVar - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") -_T3 = TypeVar("_T3") - - -class Animal(Protocol[_T1]): - species: str - attributes: list[_T1] - - -class Mammal(Animal[_T2], Protocol): - pass - - -class Ungulate(Mammal[_T3], Protocol): - type_of_hooves: _T3 - - -class CamelLike(Ungulate[bytes], Protocol): - species: Literal["camel"] # viper: ignore[reportIncompatibleVariableOverride] - - -class Sloth: - species: str - attributes: list[str] - - -class Armadillo: - species: str - attributes: list[bytes] - - -class Tapir: - species: str - - -class Camel: - species: Literal["camel"] - attributes: list[bytes] - type_of_hooves: bytes - - -class Cow: - species: str - attributes: list[str] - type_of_hooves: str - - -a: Mammal[str] = Sloth() - -# This should generate an error because Armadillo -# uses bytes for its attributes, not str. -b: Mammal[str] = Armadillo() - -# This should generate an error because Tapir -# doesn't provide an attributes. -c: Mammal[str] = Tapir() - -# This should generate an error because "species" -# is incompatible. -d: Ungulate[bytes] = Camel() - -e: Ungulate[str] = Cow() -f: CamelLike = Camel() - - -class CallTreeProto(Protocol): - subcalls: list["CallTreeProto"] - - -class MyCallTree: - subcalls: list["MyCallTree"] - - -class OtherCallTree: - subcalls: list["CallTreeProto"] - - -# This should generate an error. -x1: CallTreeProto = MyCallTree() - -x2: CallTreeProto = OtherCallTree() diff --git a/packages/vipeye-internal/src/tests/samples/protocol7.py b/packages/vipeye-internal/src/tests/samples/protocol7.py deleted file mode 100644 index 11fe01a2..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol7.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample verifies that the type checker properly -# flags the use of a protocol class when it's used -# in the second parameter of isinstance. - -from typing import Protocol, runtime_checkable - - -class P1(Protocol): - name: str - - -@runtime_checkable -class P2(Protocol): - name: str - - -def foo(a: int): - # This should generate an error because P1 is not - # runtime_checkable. - if isinstance(a, P1): - return - - if isinstance(a, P2): - return diff --git a/packages/vipeye-internal/src/tests/samples/protocol8.py b/packages/vipeye-internal/src/tests/samples/protocol8.py deleted file mode 100644 index 7c790e10..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol8.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the handling of protocol classes -# that represent callbacks when used with class constructors. - -from typing import Protocol - - -class _BaseClass: ... - - -class _Protocol1(Protocol): - def __call__(self, p1: str, p2) -> _BaseClass: ... - - -def func1(callback: _Protocol1): - pass - - -class _Class1(_BaseClass): - def __init__(self, my_str: str): ... - - -class _Class2(_BaseClass): - def __init__(self, p1: str, p2: str): ... - - -# This should generate an error because the -# parameter types don't match. -func1(_Class1) - -func1(_Class2) diff --git a/packages/vipeye-internal/src/tests/samples/protocol9.py b/packages/vipeye-internal/src/tests/samples/protocol9.py deleted file mode 100644 index f86e3d74..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocol9.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests a recursive protocol class (i.e. a protocol -# that refers to itself). - -from typing import Protocol - - -class TreeLike(Protocol): - value: int - - @property - def left(self) -> "TreeLike | None": ... - - @property - def right(self) -> "TreeLike | None": ... - - -class SimpleTree: - value: int - - @property - def left(self) -> "SimpleTree | None": - return self._left - - @property - def right(self) -> "SimpleTree | None": - return self._right - - def __init__(self, value: int) -> None: - self.value = value - self._left: SimpleTree | None = None - self._right: SimpleTree | None = None - - -root: TreeLike = SimpleTree(0) - - -class ProtoA(Protocol): - def method1(self) -> "ProtoA": ... - - -class ImplA: - class CallableClass: - def __call__(self) -> "ImplA": - return ImplA() - - method1 = CallableClass() - - -v1: ProtoA = ImplA() diff --git a/packages/vipeye-internal/src/tests/samples/protocolExplicit1.py b/packages/vipeye-internal/src/tests/samples/protocolExplicit1.py deleted file mode 100644 index 95c30c2a..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolExplicit1.py +++ /dev/null @@ -1,120 +0,0 @@ -# This sample tests the logic that validates that a concrete class that -# explicitly derives from a protocol class implements the variables -# and functions defined in the protocol. - -from abc import ABC, abstractmethod -from typing import ClassVar, Protocol, final - - -class Protocol1(Protocol): - cm1: ClassVar[int] - cm2: ClassVar[int] = 0 - - im1: int - im2: int = 2 - im3: int - - def __init__(self): - self.im3 = 3 - - -class Protocol2(Protocol): - cm10: int - - -class Protocol3(Protocol2, Protocol): - cm11: int - - -class Concrete1(Protocol1): ... - - -# This should generate an error because some attributes are not implemented. -Concrete1() - - -class Concrete2(Protocol1): - cm1 = 3 - im1 = 0 - - -Concrete2() - - -class Concrete3(Protocol1, Protocol3): - cm1 = 3 - - def __init__(self): - im1 = 0 - - -# This should generate an error. -Concrete3() - - -class Concrete4(Protocol1, Protocol3): - cm1 = 3 - cm10 = 3 - - def __init__(self): - self.im1 = 3 - self.im10 = 10 - self.cm11 = 3 - - -Concrete4() - - -class Protocol5(Protocol): - def method1(self) -> int: ... - - -# This should generate an error because "method1" is -# not implemented and it is marked final. -@final -class Concrete5(Protocol5): - pass - - -class Protocol6(Protocol): - x: int - - -class Mixin: - x = 3 - - -@final -class Concrete6(Mixin, Protocol6): - pass - - -class Protocol7(Protocol): - @abstractmethod - def method1(self): ... - - -class Mixin7(Protocol7, ABC): - def method1(self): - pass - - -# This should generate an error because it -# does not implement method1 and is marked final. -@final -class Concrete7A(Protocol7): - pass - - -@final -class Concrete7B(Mixin7, Protocol7): - pass - - -class Protocol8(Protocol): - x: int - - -class Concrete8(Protocol8): - # This should generate an error because x is a ClassVar. - x: ClassVar = 1 diff --git a/packages/vipeye-internal/src/tests/samples/protocolExplicit2.pyi b/packages/vipeye-internal/src/tests/samples/protocolExplicit2.pyi deleted file mode 100644 index 9ba7e487..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolExplicit2.pyi +++ /dev/null @@ -1,28 +0,0 @@ -# This sample is a stub file used in conjunction with the protocolExplicit3.py test. - -# This sample tests the logic that validates that a concrete class that -# explicitly derives from a protocol class implements the variables -# and functions defined in the protocol. - -from abc import abstractmethod -from typing import ClassVar, Protocol - -class Protocol1(Protocol): - cm1: ClassVar[int] - im1: int - -class Protocol2(Protocol): - cm10: int - -class Protocol3(Protocol2, Protocol): - pass - -class Protocol5(Protocol): - def method1(self) -> int: ... - -class Protocol6(Protocol): - x: int - -class Protocol7(Protocol): - @abstractmethod - def method1(self): ... diff --git a/packages/vipeye-internal/src/tests/samples/protocolExplicit3.py b/packages/vipeye-internal/src/tests/samples/protocolExplicit3.py deleted file mode 100644 index 90eddd55..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolExplicit3.py +++ /dev/null @@ -1,77 +0,0 @@ -# This sample tests the logic that validates that a concrete class that -# explicitly derives from a protocol class implements the variables -# and functions defined in the protocol. Specifically, this tests -# the case where the parent protocol class is implemented in a stub file. - -# viper: reportMissingModuleSource=false - -from abc import ABC -from typing import final -from .protocolExplicit2 import Protocol1, Protocol3, Protocol5, Protocol6, Protocol7 - - -class Concrete1(Protocol1): ... - - -# This should generate an error because some attributes are not implemented. -Concrete1() - - -class Concrete2(Protocol1): - cm1 = 3 - im1 = 0 - - -Concrete2() - - -class Concrete3(Protocol1, Protocol3): - cm1 = 3 - - -# This should generate an error. -Concrete3() - - -class Concrete4(Protocol1, Protocol3): - cm1 = 3 - cm10 = 3 - - def __init__(self): - self.im1 = 3 - self.im10 = 10 - self.cm11 = 3 - - -Concrete4() - - -@final -class Concrete5(Protocol5): - pass - - -class Mixin: - x = 3 - - -@final -class Concrete6(Mixin, Protocol6): - pass - - -class Mixin7(Protocol7, ABC): - def method1(self): - pass - - -# This should generate an error because it -# does not implement method1 and is marked final. -@final -class Concrete7A(Protocol7): - pass - - -@final -class Concrete7B(Mixin7, Protocol7): - pass diff --git a/packages/vipeye-internal/src/tests/samples/protocolModule1.py b/packages/vipeye-internal/src/tests/samples/protocolModule1.py deleted file mode 100644 index ff852f1a..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolModule1.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample is used in conjunction with protocolModule2.py. - - -var_1: int = 3 -var_2: int | str = "hello" - - -def func_1(a: int, b: str) -> str: - return "hi" - - -def func_2() -> str: - return "hi" diff --git a/packages/vipeye-internal/src/tests/samples/protocolModule2.py b/packages/vipeye-internal/src/tests/samples/protocolModule2.py deleted file mode 100644 index d2bd17de..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolModule2.py +++ /dev/null @@ -1,100 +0,0 @@ -# This sample tests protocol matching for modules. - -from typing import Protocol, TypeVar, runtime_checkable -from . import protocolModule1 -import datetime -from importlib import import_module - - -@runtime_checkable -class P1(Protocol): - var_1: int - var_2: int | str - - def func_1(self, a: int, b: str) -> str: ... - - @staticmethod - def func_2() -> str: ... - - -v1: P1 = protocolModule1 - - -@runtime_checkable -class P2(Protocol): - var_1: str - - -# This should generate an error because var_1 has the -# wrong type. -v2: P2 = protocolModule1 - - -class P3(Protocol): - def func_1(self, a: int, b: str) -> int: ... - - -# This should generate an error because func_1 has the -# wrong type. -v3: P3 = protocolModule1 - - -class P4(Protocol): - def func_2(self) -> str: ... - - y: int - - -# This should generate an error because y is missing. -v4: P4 = protocolModule1 - - -_T = TypeVar("_T", bound=P2) - - -class NonProtocol: ... - - -# Test type narrowing of module symbols for isinstance checks. -def func1(x: type[_T]): - if isinstance(datetime, (P1, P2, NonProtocol, x)): - reveal_type(datetime, expected_text="P1 | P2 | _T@func1") - else: - reveal_type(datetime, expected_text='Module("datetime")') - - -def func2(): - if not isinstance(datetime, P1): - reveal_type(datetime, expected_text='Module("datetime")') - else: - reveal_type(datetime, expected_text="P1") - - -def func3(): - my_module = import_module("my_module") - if isinstance(my_module, (P1, NonProtocol)): - reveal_type(my_module, expected_text="P1") - else: - reveal_type(my_module, expected_text="ModuleType") - - -_T1 = TypeVar("_T1") - - -class P5(Protocol[_T1]): - def func_1(self, a: int, b: _T1) -> _T1: ... - - -def func4(x: P5[_T1]) -> _T1: ... - - -v5 = func4(protocolModule1) -reveal_type(v5, expected_text="str") - - -class P6(Protocol): - @property - def var_1(self) -> int: ... - - -v6: P6 = protocolModule1 diff --git a/packages/vipeye-internal/src/tests/samples/protocolModule3.py b/packages/vipeye-internal/src/tests/samples/protocolModule3.py deleted file mode 100644 index 134b0531..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolModule3.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample is used in conjunction with protocolModule4.py. - -from typing import Protocol, TypeVar - -Y = TypeVar("Y", contravariant=True) - - -class Fn(Protocol[Y]): - def __call__(self, y: Y) -> None: ... - - -def x(x: Fn[int]) -> None: - print(x) diff --git a/packages/vipeye-internal/src/tests/samples/protocolModule4.py b/packages/vipeye-internal/src/tests/samples/protocolModule4.py deleted file mode 100644 index ac2e3ed2..00000000 --- a/packages/vipeye-internal/src/tests/samples/protocolModule4.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests protocol matching for modules when using -# a generic protocol class. - -from typing import Protocol, TypeVar - -from . import protocolModule3 -from .protocolModule3 import Fn - -X = TypeVar("X", covariant=True) -Z = TypeVar("Z") - - -class FnHandler(Protocol[X]): - def __call__(self, x: Fn[X]) -> None: ... - - -class ModuleSpec(Protocol[Z]): - x: FnHandler[Z] - - -m1: ModuleSpec[int] = protocolModule3 -m1.x(lambda y: None) - -# This should generate an error. -m2: ModuleSpec[str] = protocolModule3 diff --git a/packages/vipeye-internal/src/tests/samples/pseudoGeneric1.py b/packages/vipeye-internal/src/tests/samples/pseudoGeneric1.py deleted file mode 100644 index 099b970a..00000000 --- a/packages/vipeye-internal/src/tests/samples/pseudoGeneric1.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests type checking scenarios related to "pseudo generic" -# classes - those whose constructors are unannotated. - -_DEFAULT_VALUE = object() - - -class ClassA: - def __init__(self, name, description=_DEFAULT_VALUE): ... - - @classmethod - def create_new(cls): - return cls("", None) - - -a1: list[ClassA] = [ClassA("a", description="b")] -a2: list[ClassA] = [ClassA("c")] -a3: list[ClassA] = a1 + a2 - - -class ClassB: - def __init__(self, a, b, c=None, d=""): - self.a = a - self.b = b - self.c = c - self.d = d - - -b1 = ClassB(1, "") -reveal_type(b1.a, expected_text="int") -reveal_type(b1.b, expected_text="str") -reveal_type(b1.c, expected_text="Unknown | None") -reveal_type(b1.d, expected_text="str") - -b2 = ClassB("", 1.2, 2, "") -reveal_type(b2.a, expected_text="str") -reveal_type(b2.b, expected_text="float") -reveal_type(b2.c, expected_text="Unknown | None") -reveal_type(b2.d, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/pseudoGeneric2.py b/packages/vipeye-internal/src/tests/samples/pseudoGeneric2.py deleted file mode 100644 index 45a80cde..00000000 --- a/packages/vipeye-internal/src/tests/samples/pseudoGeneric2.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the "pseudo-generic class" functionality, -# where a class is made into a generic class in cases where -# it has no annotated constructor parameters. - -# We use "strict" here because we want to ensure that there are -# no "unknown" types remaining in this file. -# viper: strict, reportUnknownParameterType=false, reportMissingParameterType=false - -from logging import Handler, NOTSET - - -class ClassA(Handler): - def __init__(self, a, b="hello", level=NOTSET): - super().__init__(level) - self._foo_a = a - self._foo_b = b - - @property - def value_a(self): - return self._foo_a - - @property - def value_b(self): - return self._foo_b - - -a1 = ClassA(27) -reveal_type(a1.value_a, expected_text="int") -reveal_type(a1.value_b, expected_text="str") - - -a2 = ClassA("hello", "27") -reveal_type(a2.value_a, expected_text="str") -reveal_type(a2.value_b, expected_text="str") - -# This should generate an error because a pseudo-generic -# class is not actually generic. -a3: ClassA[int, str, int] diff --git a/packages/vipeye-internal/src/tests/samples/pseudoGeneric3.py b/packages/vipeye-internal/src/tests/samples/pseudoGeneric3.py deleted file mode 100644 index 4cf33269..00000000 --- a/packages/vipeye-internal/src/tests/samples/pseudoGeneric3.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample is similar to pseudoGeneric2.py in that it tests -# the case where the class's constructor is unannotated. This -# particular case was causing an internal crash. - -import abc - - -class ClassB(metaclass=abc.ABCMeta): - def __init__(self, value=None): - self._cache = {"value": value} - - @property - def cache(self): - return self._cache - - @cache.deleter - def cache(self): - self._cache = {key: None for key in self._cache} - - def __getattr__(self, attr): - cache = self.cache - if attr in cache: - return cache[attr] - else: - return self.__getattribute__(attr) - - -b1 = ClassB("test") -reveal_type(b1.value, expected_text="Unknown | Any | None") -del b1.cache diff --git a/packages/vipeye-internal/src/tests/samples/python2.py b/packages/vipeye-internal/src/tests/samples/python2.py deleted file mode 100644 index 8f01b4fb..00000000 --- a/packages/vipeye-internal/src/tests/samples/python2.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample includes Python 2.x syntax that is illegal -# in Python 3.x. The Pyright parser should flag these as -# errors, but it should exhibit good recovery, preferably -# emitting one error per instance, not a cascade of errors. - -# viper: reportUnusedExpression=false - -# This should generate an error. -print 3 + 3 - -# This should generate an error. -exec 3 + 4 - -try: - bar = 3 -# This should generate one error on Python 3.14 and newer -# and two errors on older versions. -except NameError, 'error caused': - pass - -b = 3 - -# This should generate an error. -a = `b` - -# This should generate an error. -def foo(a, (b, c), d): - pass - -# This should generate two errors. -raise NameError, a > 4, a < 4 - diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias1.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias1.py deleted file mode 100644 index 05cf1f8f..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias1.py +++ /dev/null @@ -1,77 +0,0 @@ -# This sample tests Pyright's handling of recursive type aliases. - -from typing import Mapping, TypeVar, Union - -MyTree = list[Union["MyTree", int]] - -t1: MyTree = [1, 2, 3, [3, 4], [[3], 5]] - -# This should generate an error because a str is not allowed. -t2: MyTree = [3, ""] - -# This should generate an error because a str is not allowed. -t3: MyTree = [1, 2, 3, [3, 4], [3, 4, 5, [3, "4"]]] - -_T = TypeVar("_T") -GenericUnion = Union[int, _T] - -i1: GenericUnion[str] = "hi" -i1 = 3 - -i2: GenericUnion[float] = 3 -# This should generate an error because str isn't compatible. -i2 = "hi" - -Foo = Union[bool, list["Foo"], dict["Foo", "Foo"]] - -bar1: Foo = [True, [True, False]] -bar2: Foo = [True, [True], {True: False}] -bar4: Foo = {True: [False]} - -# These should generate errors. -baz1: Foo = [True, ["True", False]] -baz2: Foo = [True, [True], {True: "False"}] -baz4: Foo = {True: ["False"]} - -Json = Union[None, int, str, float, list["Json"], dict[str, "Json"]] - -# This should generate an error -a1: Json = {"a": 1, "b": 3j} - -# This should generate an error -a2: Json = [2, 3j] - -RecursiveTuple = Union[str | int, tuple["RecursiveTuple", ...]] - - -b1: RecursiveTuple = (1, 1) -b2: RecursiveTuple = (1, "1") -b3: RecursiveTuple = (1, "1", 1, "2") -b4: RecursiveTuple = (1, ("1", 1), "2") -b5: RecursiveTuple = (1, ("1", 1), (1, (1, 2))) - -# This should generate an error -b6: RecursiveTuple = (1, ("1", 1), (1, (1, [2]))) - -# This should generate an error -b6: RecursiveTuple = (1, [1]) - - -RecursiveMapping = Union[str, int, Mapping[str, "RecursiveMapping"]] - - -c1: RecursiveMapping = 1 -c2: RecursiveMapping = "1" -c3: RecursiveMapping = {"1": "1"} -c4: RecursiveMapping = {"1": "1", "2": 1} -c5: RecursiveMapping = {"1": "1", "2": 1, "3": {}} -c6: RecursiveMapping = {"1": "1", "2": 1, "3": {"0": "0", "1": "2", "2": {}}} - -# This should generate an error. -c7: RecursiveMapping = {"1": [1]} - -# This should generate an error. -c8: RecursiveMapping = {"1": "1", "2": 1, "3": [1, 2]} - -# This should generate an error. -c9: RecursiveMapping = {"1": "1", "2": 1, "3": {"0": "0", "1": 1, "2": [1, 2, 3]}} diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias10.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias10.py deleted file mode 100644 index a43a2925..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias10.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the case where two recursive type aliases -# with different definitions overlap. - -from typing import Mapping, Optional, Sequence, Union - -JsonArr1 = Sequence[Optional["JsonVal1"]] -JsonObj1 = Mapping[str, Optional["JsonVal1"]] -JsonVal1 = Union[bool, float, int, str, "JsonArr1", "JsonObj1"] - -JsonArr2 = Sequence[Optional["JsonVal2"]] -JsonObj2 = Mapping[str, Optional["JsonVal2"]] -JsonVal2 = Union[bool, float, int, str, "JsonArr2", "JsonObj2"] - - -def func1(v: JsonVal1): - x: JsonVal2 = v - - return x - - -def func2(v: Optional[JsonVal1]): - # This should generate an error. - x: JsonVal2 = v - - return x - - -def func3(v: Optional[JsonVal1]): - # This should generate an error. - x: Optional[JsonVal2] = v - - return x diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias11.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias11.py deleted file mode 100644 index 40239e92..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias11.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests the case where a recursive type alias makes use of -# a bound or constrained TypeVar. - - -from typing import Any, Generic, TypeVar - -""" Test bound TypeVar """ - - -class ClassA1: - pass - - -T1 = TypeVar("T1", bound=ClassA1) - - -class ClassA2(ClassA1, Generic[T1]): - pass - - -class ClassA3(ClassA1): - pass - - -TA1 = ClassA2["TA1"] | ClassA3 - - -""" Test constrained TypeVar """ - - -class ClassB1: - pass - - -T2 = TypeVar("T2", "ClassB2[Any] | ClassB3", int) - - -class ClassB2(ClassB1, Generic[T2]): - pass - - -class ClassB3(ClassB1): - pass - - -TA2 = ClassB2["TA2"] | ClassB3 diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias12.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias12.py deleted file mode 100644 index 683a7559..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias12.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case where a recursive type alias is evaluated -# for type compatibility with a recursive protocol. We want to make sure -# this doesn't lead to extremely long evaluation times or stack overflows. - -from collections.abc import Callable -from types import FrameType -from typing import Any, Protocol, Self, TypeAlias - - -class TraceFunctionProto(Protocol): - def __call__(self, frame: FrameType, event: str, arg: Any) -> Self | None: ... - - -TraceFunction: TypeAlias = Callable[[FrameType, str, Any], "TraceFunction | None"] - - -def settrace(tf: TraceFunction | None) -> None: ... - - -def func1(frame: FrameType, event: str, arg: Any) -> TraceFunction: ... - - -def func2(tf: TraceFunctionProto | None): - settrace(tf) - settrace(func1) diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias13.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias13.py deleted file mode 100644 index ae00c456..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias13.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a recursive type alias previous -# led to infinite recursion. - -from typing import Iterable, TypeVar, Union - -T = TypeVar("T") -Tree = list[Union["Tree[T]", T]] - - -def _flatten(tree: Union[Tree[T], T]) -> Iterable[T]: - if not isinstance(tree, list): - yield tree - return - for v in tree: - yield from _flatten(v) - - -def flatten(tree: Tree[T]) -> Iterable[T]: - return _flatten(tree) - - -flatten([1, [2, 3]]) diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias14.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias14.py deleted file mode 100644 index 633c6432..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias14.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the case where a recursive type alias contains -# a `Sequence` that potentially overlaps with str (which derives from -# Sequence[str]). - -from typing import Sequence - - -NestedIntList = int | Sequence["NestedIntList"] - - -def func1() -> NestedIntList: - result: NestedIntList = 1 - for _ in range(1): - result = [result] - return result - - -def func2() -> NestedIntList: - # This should generate an error. - result: NestedIntList = "" - for _ in range(1): - result = [result] - return result diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias15.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias15.py deleted file mode 100644 index f7e924f5..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias15.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests that the computed variance for a recursive type -# alias is correct. - -from typing import Callable, TypeAlias, TypeVar - - -type A[T] = Callable[[A[T]], Callable[[T], None]] - - -def testA_co(x: A[int]) -> A[int | str]: - # This should generate an error because A is invariant. - return x - - -def testA_cn(x: A[int | str]) -> A[int]: - # This should generate an error because A is invariant. - return x - - -T = TypeVar("T") - -B: TypeAlias = "Callable[[B[T]], Callable[[T], None]]" - - -def testB_co(x: B[int]) -> B[int | str]: - # This should generate an error because B is invariant. - return x - - -def testB_cn(x: B[int | str]) -> B[int]: - # This should generate an error because B is invariant. - return x diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias16.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias16.py deleted file mode 100644 index d25c5b89..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias16.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests a case that previously resulted in infinite recursion. - -from typing import TypeVar, Generic - -U = TypeVar("U") -T = TypeVar("T") - - -class A(Generic[T]): - pass - - -class B(Generic[T]): - pass - - -class C(Generic[T]): - pass - - -TA1 = A["TA2[U]"] | B["TA2[U]"] -TA2 = TA1[U] | C[TA1[U]] -TA3 = TA2[U] diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias17.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias17.py deleted file mode 100644 index c16172db..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias17.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests that a recursive type alias defined in terms of itself -# via a forward reference resolves correctly without producing Unknown types. -# This is a regression test for https://github.com/microsoft/pyright/issues/10850. -# The bug caused nondeterministic (order-dependent) type evaluation where -# analyzing files in different orders could produce Unknown types. - -from typing import TypeVar - -J = TypeVar("J", bound="JSON") -JSONObjectOf = dict[str, J] -JSON = str | JSONObjectOf["JSON"] -JSONObject = JSONObjectOf[JSON] - - -def identity(json: JSONObjectOf[JSON]) -> JSONObjectOf[JSON]: - return json - - -def identity2(json: JSONObject) -> JSONObject: - return json - - -# These assignments verify that JSON resolved correctly (not to Unknown). -# A str should be assignable to JSON. -v1: JSON = "hello" - -# A nested dict[str, str] should be assignable to JSON. -v2: JSON = {"key": "value"} - -# An int should NOT be assignable to JSON. This should generate an error. -v3: JSON = 42 # This is an error. - -# A dict with int values should NOT be assignable to JSON. This should -# generate an error. -v4: JSONObject = {"key": 42} # This is an error. diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias2.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias2.py deleted file mode 100644 index 3d1146c2..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias2.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests Pyright's handling of recursive type aliases -# that are also generic. - -from typing import TypeVar, Union - -_T1 = TypeVar("_T1", str, int) -_T2 = TypeVar("_T2") - -GenericTypeAlias1 = list[Union["GenericTypeAlias1[_T1]", _T1]] - -SpecializedTypeAlias1 = GenericTypeAlias1[str] - -a1: SpecializedTypeAlias1 = ["hi", ["hi", "hi"]] - -# This should generate an error because int doesn't match the -# constraint of the TypeVar _T1. -SpecializedClass2 = GenericTypeAlias1[float] - -b1: GenericTypeAlias1[str] = ["hi", "bye", [""], [["hi"]]] - -# This should generate an error. -b2: GenericTypeAlias1[str] = ["hi", [2.4]] - - -GenericTypeAlias2 = list[Union["GenericTypeAlias2[_T1, _T2]", _T1, _T2]] - -c2: GenericTypeAlias2[str, int] = [[3, ["hi"]], "hi"] - -c3: GenericTypeAlias2[str, float] = [[3, ["hi", 3.4, [3.4]]], "hi"] - -# This should generate an error because a float is a type mismatch. -c4: GenericTypeAlias2[str, int] = [[3, ["hi", 3, [3.4]]], "hi"] diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias3.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias3.py deleted file mode 100644 index 8d07bec7..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias3.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests Pyright's handling of recursive type aliases. - -from typing import TypeAlias, Union - -# This should generate an error because the forward reference -# type needs to be in quotes. -GenericClass0 = list[GenericClass0 | int] - -# This should generate an error because the type alias directly -# refers to itself. -RecursiveUnion = Union["RecursiveUnion", int] - -# This should generate an error because the type alias refers -# to itself through a mutually-referential type alias. -MutualReference1 = Union["MutualReference2", int] -MutualReference2 = Union["MutualReference1", str] - -# This should generate an error because the type alias refers -# to itself. -MutualReference3: TypeAlias = "MutualReference3" - - -RecursiveType: TypeAlias = list[Union[str, "RecursiveType"]] -reveal_type(RecursiveType, expected_text="type[list[str | RecursiveType]]") diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias4.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias4.py deleted file mode 100644 index e5ef73f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias4.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests the handling of complex recursive types. - -# viper: strict, reportUnusedVariable=false - -from typing import Generator - - -JSONArray = list["JSONType"] -JSONObject = dict[str, "JSONType"] - -JSONPrimitive = str | float | int | bool | None -JSONStructured = JSONArray | JSONObject - -JSONType = JSONPrimitive | JSONStructured - - -# Using type alias checking for list: -def f2(args: JSONStructured): - if isinstance(args, list): - reveal_type( - args, - expected_text="list[str | float | int | bool | list[JSONType] | dict[str, JSONType] | None]", - ) - else: - reveal_type( - args, - expected_text="dict[str, str | float | int | bool | list[JSONType] | dict[str, JSONType] | None]", - ) - dargs: JSONObject = args - - -# Using type alias checking for dict: -def f3(args: JSONStructured): - if isinstance(args, dict): - reveal_type( - args, - expected_text="dict[str, str | float | int | bool | list[JSONType] | dict[str, JSONType] | None]", - ) - else: - reveal_type( - args, - expected_text="list[str | float | int | bool | list[JSONType] | dict[str, JSONType] | None]", - ) - largs: JSONArray = args - - -# Using type alias for "is None" narrowing: -LinkedList = tuple[int, "LinkedList"] | None - - -def g(xs: LinkedList) -> Generator[int, None, None]: - while xs is not None: - x, rest = xs - yield x - xs = rest diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias5.pyi b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias5.pyi deleted file mode 100644 index e1cbf6c4..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias5.pyi +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the case where a recursive type alias -# indirectly refers to itself through either a parameter -# annotation or return type annotation. - -_str = str - -def str(val: float) -> _str: ... - -_int = int - -def int(val: _int) -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias6.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias6.py deleted file mode 100644 index ced16808..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias6.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the handling of recursive type aliases that are generic. - -from __future__ import annotations -from typing import Mapping, Sequence, TypeVar, Union - -S = TypeVar("S") -RecList = Union[Mapping[str, "RecList[S]"], Sequence["RecList[S]"], S] - -T3 = TypeVar("T3", RecList[int], RecList[str]) - - -def f3(x: RecList[int] | RecList[str]) -> None: ... - - -def g3(x: T3): - return f3(x) - - -def f4(x: RecList[str] | RecList[int]) -> None: ... - - -def g4(x: T3): - return f4(x) diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias7.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias7.py deleted file mode 100644 index abde0df3..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias7.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests a recursive type alias used within -# a recursive function. - -from typing import Dict, Union - - -A = Union[str, Dict[str, "A"]] - - -def func1(x: A): - if isinstance(x, str): - print(x) - else: - for _, v in x.items(): - func1(v) diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias8.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias8.py deleted file mode 100644 index 17e71927..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias8.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the case where a recursive type alias is used -# to define a TypedDict that refers to itself in one of its fields. - -from __future__ import annotations - -from typing import TypedDict - - -class ClassA(TypedDict, total=False): - options: list[CorD] - type: int - - -class ClassB(ClassA): - id: int - name: str - - -class ClassC(TypedDict): - type: int - - -class ClassD(TypedDict): - options: list[CorD] - type: int - - -CorD = ClassC | ClassD - - -def foo(a: CorD): - reveal_type(a, expected_text="ClassC | ClassD") - options = a.get("options", []) - reveal_type(options, expected_text="list[ClassC | ClassD] | Any | list[Any]") - - for option in options: - reveal_type(option, expected_text="ClassC | ClassD | Any") - reveal_type(option["type"], expected_text="int | Any") diff --git a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias9.py b/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias9.py deleted file mode 100644 index 3223af60..00000000 --- a/packages/vipeye-internal/src/tests/samples/recursiveTypeAlias9.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests that recursive type aliases work well with -# a generic dataclass constructor. - -from dataclasses import dataclass -from typing import Union, Generic, TypeVar - -A = TypeVar("A") -JSON = Union[str, dict[str, "JSON"]] - - -@dataclass -class Example(Generic[A]): - val: A - - -a: JSON = {"a": "b"} -b: JSON = "a" -c: Example[JSON] = Example(a) -d: Example[JSON] = Example("a") -e: Example[JSON] = Example({}) -f: Example[JSON] = Example({"a": "b"}) -g: Example[JSON] = Example({"a": {"a": "b"}}) diff --git a/packages/vipeye-internal/src/tests/samples/required1.py b/packages/vipeye-internal/src/tests/samples/required1.py deleted file mode 100644 index be86ca7e..00000000 --- a/packages/vipeye-internal/src/tests/samples/required1.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the handling of Required and NotRequired -# (PEP 655) in TypedDict definitions. - -# viper: reportMissingModuleSource=false - -from typing import Annotated, TypedDict -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - NotRequired, - Required, -) - - -class TD1(TypedDict): - a: Required[int] - b: NotRequired[int] - - # This should generate an error because NotRequired can't be - # used in this context. - c: NotRequired[NotRequired[int]] - - # This should generate an error because Required can't be - # used in this context. - d: Required[Required[int]] - - e: NotRequired[Annotated[int, "hi"]] - - # This should generate an error because it's missing type args. - f: Required - - # This should generate an error because it's missing type args. - g: NotRequired - - -# This should generate an error because Required can't be -# used in this context. -x: Required[int] - -# This should generate an error because NotRequired can't be -# used in this context. -y: Required[int] - - -class Foo: - # This should generate an error because Required can't be - # used in this context. - x: Required[int] - - # This should generate an error because NotRequired can't be - # used in this context. - y: Required[int] diff --git a/packages/vipeye-internal/src/tests/samples/required2.py b/packages/vipeye-internal/src/tests/samples/required2.py deleted file mode 100644 index 06c6422b..00000000 --- a/packages/vipeye-internal/src/tests/samples/required2.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the handling of Required and NotRequired -# (PEP 655) in TypedDict definitions. - -# viper: reportMissingModuleSource=false - -from typing import Literal, TypedDict, Annotated -import typing_extensions as te -from typing_extensions import Required, NotRequired - - -class TD1(TypedDict, total=False): - a: Annotated["te.Required[int]", ""] - b: Annotated[te.NotRequired[str], ""] - c: "te.Required[int | str]" - d: te.Required[str | None] - e: Required[Literal[1, 2, 3]] - f: Required[None] - g: Required[type[int]] - - -td1_1: TD1 = {"a": 3, "c": "hi", "d": None, "e": 3, "f": None, "g": int} - -# This should generate an error because a is missing. -td1_2: TD1 = {"c": "hi", "d": None, "e": 3, "f": None, "g": int} - -# This should generate an error because c is missing. -td1_3: TD1 = {"a": 3, "d": None, "e": 3, "f": None, "g": int} - -# This should generate an error because d is missing. -td1_4: TD1 = {"a": 3, "c": "hi", "e": 3, "f": None, "g": int} - -# This should generate an error because e is missing. -td1_5: TD1 = {"a": 3, "c": "hi", "d": None, "f": None, "g": int} - -# This should generate an error because f is missing. -td1_6: TD1 = {"a": 3, "c": "hi", "d": None, "e": 3, "g": int} - -# This should generate an error because g is missing. -td1_7: TD1 = {"a": 3, "c": "hi", "d": None, "e": 3, "f": None} - - -class TD2(TypedDict, total=True): - a: Required[int] - b: NotRequired[str] - c: Required[int | str] - d: NotRequired[str | None] - e: NotRequired[Literal[1, 2, 3]] - f: NotRequired[None] - g: NotRequired[type[int]] - - -td2_1: TD2 = {"a": 3, "c": "hi", "d": None, "e": 3, "f": None, "g": int} - -td2_2: TD2 = {"a": 3, "c": "hi"} - -# This should generate an error because c is missing. -td2_3: TD2 = {"a": 3} diff --git a/packages/vipeye-internal/src/tests/samples/required3.py b/packages/vipeye-internal/src/tests/samples/required3.py deleted file mode 100644 index 0b269f60..00000000 --- a/packages/vipeye-internal/src/tests/samples/required3.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the handling of Required and NotRequired using -# the alternative syntax form of TypedDict. - -from typing import TypedDict -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Required, - NotRequired, -) - -Example1 = TypedDict( - "Example1", {"required": Required[int], "not_required": NotRequired[int]} -) - -v1_0: Example1 = {"required": 1} - -# This should generate an error. -v1_1: Example1 = {"not_required": 1} - -Example2 = TypedDict("Example2", required=Required[int], not_required=NotRequired[int]) - - -v2_0: Example2 = {"required": 1} - -# This should generate an error. -v2_1: Example2 = {"not_required": 1} diff --git a/packages/vipeye-internal/src/tests/samples/returnTypes1.py b/packages/vipeye-internal/src/tests/samples/returnTypes1.py deleted file mode 100644 index b7b82244..00000000 --- a/packages/vipeye-internal/src/tests/samples/returnTypes1.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests basic return type analysis and error reporting. - -from typing import TypeVar - - -T = TypeVar("T") - - -def func1(a: int, b: int) -> int: - c = float(a + b) - # This should generate an error: - # Expression of type 'float' cannot be assigned to return type 'int' - return c - - -def func2(a: float, b: float) -> float: - c = float(a + b) - return c - - -# This should generate an error: -# Argument of type 'float' cannot be assigned to parameter of type 'int' -func1(3.4, 5) - -# This should be fine -func2(3, 5) - - -# This should not produce any error because the function's suite is empty. -def func3() -> bool: - "Doc strings are allowed" - ... - - -# This should not produce any error because not all paths return an int. -def func4() -> int: - pass - - -# This should not produce any error because not all paths return a T. -def func5(x: T) -> T: - pass diff --git a/packages/vipeye-internal/src/tests/samples/returnTypes2.py b/packages/vipeye-internal/src/tests/samples/returnTypes2.py deleted file mode 100644 index 6675cdd9..00000000 --- a/packages/vipeye-internal/src/tests/samples/returnTypes2.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample tests the case where return type inference encounters -# recursion. - - -class Grammar: - @staticmethod - def A(): - return Grammar.B - - @staticmethod - def B(): - return Grammar.C - - @staticmethod - def C(): - return Grammar.D - - @staticmethod - def D(): - return Grammar.E - - @staticmethod - def E(): - return Grammar.F - - @staticmethod - def F(): - return Grammar.G - - @staticmethod - def G(): - return Grammar.H - - @staticmethod - def H(): - return Grammar.I - - @staticmethod - def I(): - return Grammar.J - - @staticmethod - def J(): - return Grammar.K - - @staticmethod - def K(): - return Grammar.L - - @staticmethod - def L(): - return Grammar.B - - -async def func1(a): - if a == 0: - return - r = await func1(a - 1) - return r diff --git a/packages/vipeye-internal/src/tests/samples/revealedType1.py b/packages/vipeye-internal/src/tests/samples/revealedType1.py deleted file mode 100644 index 44418d92..00000000 --- a/packages/vipeye-internal/src/tests/samples/revealedType1.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the special reveal_type call. - -from typing import Literal, Union - -a: Union[str, int] -if 2 + 3: - a = 3 -else: - a = "hello" -reveal_type(a) - -a = 5 -reveal_type(a) - -a = "yup" -reveal_type(a) - - -reveal_type(a, expected_type=Literal["yup"]) -reveal_type(a, expected_text="Literal['yup']") -reveal_type(a, expected_text="Literal['yup']", expected_type=Literal["yup"]) - -# This should generate an error. -reveal_type() - -# This should generate an error. -reveal_type(a, a) - - -reveal_type(a, x=3) diff --git a/packages/vipeye-internal/src/tests/samples/self1.py b/packages/vipeye-internal/src/tests/samples/self1.py deleted file mode 100644 index 6875a694..00000000 --- a/packages/vipeye-internal/src/tests/samples/self1.py +++ /dev/null @@ -1,112 +0,0 @@ -# This sample tests various error conditions for the Self type - -from typing import Callable, Generic, TypeVar -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] - - -T = TypeVar("T") - - -# This should generate an error because Self can't be used in this context. -class A(Self): ... - - -# This should generate an error because Self can't be used in this context. -x: Self - - -def func1() -> None: - # This should generate an error because Self can't be used in this context. - x: Self - - -# This should generate an error because Self can't be used in this context. -def func2(a: Self) -> None: ... - - -# This should generate an error because Self can't be used in this context. -def func3() -> Self: ... - - -def is_self(t: object): - return t is Self - - -class B: - x: Self - - def method1(self) -> Self: - return self - - def method2(self, a: Self) -> None: - x: Self = a - y = Self - - def method3(self: Self) -> Self: - # This should generate an error because Self doesn't accept a type arg. - y: Self[int] - return self - - # This should generate an error because Self can't be used with - # methods that declare a non-Self type for "self". - def method4(self: T, a: Self) -> T: - # This should generate an error because Self can't be used with - # methods that declare a non-Self type for "self". - x: Self - - return self - - @classmethod - def method5(cls) -> type[Self]: - return cls - - @classmethod - def method6(cls, a: Self) -> None: ... - - @classmethod - def method7(cls: type[Self]) -> type[Self]: - return cls - - # This should generate an error because Self can't be used with - # methods that declare a non-Self type for "self". - @classmethod - def method8(cls: type[T], a: Self) -> type[T]: - # This should generate an error because Self can't be used with - # methods that declare a non-Self type for "self". - x: Self - return cls - - # This should generate an error because Self can't be used in - # a static method. - @staticmethod - def stat_method1(a: Self) -> None: - # This should generate an error because Self can't be used in - # a static method. - x: Self - - -class C: - @classmethod - def outer(cls) -> Callable[[int, Self], Self]: - def inner(_: int, bar: Self) -> Self: - return bar - - return inner - - -class D(Generic[T]): ... - - -# This should generate an error because "Self" cannot be used -# within a generic class definition. -class E(D[Self]): ... - - -class MetaA(type): - # This should generate an error because "Self" isn't - # allowed in a metaclass. - def __new__(cls, *args: object) -> Self: ... - - # This should generate an error because "Self" isn't - # allowed in a metaclass. - def __mul__(cls, count: int) -> list[Self]: ... diff --git a/packages/vipeye-internal/src/tests/samples/self10.py b/packages/vipeye-internal/src/tests/samples/self10.py deleted file mode 100644 index feae0657..00000000 --- a/packages/vipeye-internal/src/tests/samples/self10.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests that a class is not assignable to Self@Class. - -from typing import Self - - -class A: - def self_arg(self, other: Self): ... - - def call_self_arg(self): - # This should generate an error. - self.self_arg(A()) - - def get_instance(self) -> Self: - # This should generate an error. - return A() diff --git a/packages/vipeye-internal/src/tests/samples/self11.py b/packages/vipeye-internal/src/tests/samples/self11.py deleted file mode 100644 index 4e9941ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/self11.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests a case where "self" refers to a class with type -# parameters that have default values. This is a case that regressed. - - -class Base: ... - - -class A(Base): ... - - -class B[T: Base = A]: - def __init__(self, x: T) -> None: - self._x = x - - @property - def x(self) -> T: - return self._x diff --git a/packages/vipeye-internal/src/tests/samples/self2.py b/packages/vipeye-internal/src/tests/samples/self2.py deleted file mode 100644 index a8f59253..00000000 --- a/packages/vipeye-internal/src/tests/samples/self2.py +++ /dev/null @@ -1,196 +0,0 @@ -# This sample tests the usage of the Self type. - -from dataclasses import dataclass -from typing import Callable, Generic, ParamSpec, Protocol, TypeVar - -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] - -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -class A(Generic[_P, _R]): - val: _R - - def __init__(self, callback: Callable[_P, _R]) -> None: - self.callback = callback - - def method1(self: Self) -> Self: - return self - - def method2(self) -> Self: - return self - - @classmethod - def method3(cls: type[Self]) -> type[Self]: - return cls - - @classmethod - def method4(cls) -> type[Self]: - return cls - - -_T = TypeVar("_T") - - -class B(Generic[_T]): - def __init__(self, value: _T): - self.value = value - - -class Shape1: - def set_scale(self, scale: float) -> Self: - self.scale = scale - return self - - @classmethod - def from_config(cls, config: dict[str, float]) -> Self: - return cls() - - -class Circle1(Shape1): ... - - -x1 = Shape1().set_scale(3.4) -reveal_type(x1, expected_text="Shape1") - -x2 = Circle1().set_scale(3.4) -reveal_type(x2, expected_text="Circle1") - - -class Shape2: - def set_scale(self: Self, scale: float) -> Self: - self.scale = scale - return self - - @classmethod - def from_config(cls: type[Self], config: dict[str, float]) -> Self: - return cls() - - def difference(self: Self, other: Self) -> float: ... - - def apply(self: Self, f: Callable[[Self], None]) -> None: ... - - -class Circle2(Shape2): ... - - -s2 = Shape2() -x3 = s2.set_scale(3.4) -reveal_type(x3, expected_text="Shape2") - -c2 = Circle2() -x4 = c2.set_scale(3.4) -reveal_type(x4, expected_text="Circle2") - -c2.difference(c2) -s2.difference(c2) -s2.difference(s2) - -# This should generate an error. -c2.difference(s2) - - -@dataclass -class LinkedList(Generic[_T]): - value: _T - next: Self | None = None - - -LinkedList[int](value=1, next=LinkedList[int](value=2)) - - -@dataclass -class OrdinalLinkedList(LinkedList[int]): - def ordinal_value(self) -> str: - return str(self.value) - - -# This should generate an error. -xs = OrdinalLinkedList(value=1, next=LinkedList[int](value=2)) - -if xs.next is not None: - xs.next = OrdinalLinkedList(value=3, next=None) - - # This should generate an error. - xs.next = LinkedList[int](value=3, next=None) - - -class Container(Generic[_T]): - value: _T - - def set_value(self, value: _T) -> Self: ... - - -def object_with_concrete_type( - int_container: Container[int], str_container: Container[str] -) -> None: - reveal_type(int_container.set_value(0), expected_text="Container[int]") - reveal_type(str_container.set_value(""), expected_text="Container[str]") - - -def object_with_generic_type(container: Container[_T], value: _T) -> Container[_T]: - return container.set_value(value) - - -class ShapeProtocol(Protocol): - def set_scale(self, scale: float) -> Self: ... - - -class ReturnSelf: - scale: float = 1.0 - - def set_scale(self, scale: float) -> Self: - self.scale = scale - return self - - -class ReturnConcreteShape: - scale: float = 1.0 - - def set_scale(self, scale: float) -> Self: - self.scale = scale - return self - - -class BadReturnType: - scale: float = 1.0 - - def set_scale(self, scale: float) -> int: - self.scale = scale - return 42 - - -class ReturnDifferentClass: - scale: float = 1.0 - - def set_scale(self, scale: float) -> ReturnConcreteShape: - return ReturnConcreteShape() - - -def accepts_shape(shape: ShapeProtocol) -> None: - y = shape.set_scale(0.5) - reveal_type(y) - - -def main( - return_self_shape: ReturnSelf, - return_concrete_shape: ReturnConcreteShape, - bad_return_type: BadReturnType, - return_different_class: ReturnDifferentClass, -) -> None: - accepts_shape(return_self_shape) - accepts_shape(return_concrete_shape) - - # This should generate an error. - accepts_shape(bad_return_type) - - # This should generate an error. - accepts_shape(return_different_class) - - -class StateManager: - def __init__(self) -> None: - self.state: list[Self] = self.get_state() - - def get_state(self) -> list[Self]: ... diff --git a/packages/vipeye-internal/src/tests/samples/self3.py b/packages/vipeye-internal/src/tests/samples/self3.py deleted file mode 100644 index f2cd9558..00000000 --- a/packages/vipeye-internal/src/tests/samples/self3.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests the special-case handling of Self when comparing -# two functions whose signatures differ only in the Self scope. - - -class SomeClass: - def __str__(self) -> str: ... - - __repr__ = __str__ diff --git a/packages/vipeye-internal/src/tests/samples/self4.py b/packages/vipeye-internal/src/tests/samples/self4.py deleted file mode 100644 index fd8914b3..00000000 --- a/packages/vipeye-internal/src/tests/samples/self4.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a method decorator uses an explicit -# type annotation for the "self" parameter. - -from typing import Callable, Generic, TypeVar, Any - -T = TypeVar("T") -S = TypeVar("S", bound="MyClass[Any]") - - -def my_generic_wrapper(f: Callable[[S], str]) -> Callable[[S], int]: ... - - -class MyClass(Generic[T]): - @my_generic_wrapper - def do_something(self) -> str: ... diff --git a/packages/vipeye-internal/src/tests/samples/self5.py b/packages/vipeye-internal/src/tests/samples/self5.py deleted file mode 100644 index 7d355815..00000000 --- a/packages/vipeye-internal/src/tests/samples/self5.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the use of `Self` when used within a property -# or class property. - -from typing_extensions import Self # viper: ignore[reportMissingModuleSource] - - -class A: - @property - def one(self) -> Self: ... - - @classmethod - @property - def two(cls) -> type[Self]: ... - - -class B(A): ... - - -reveal_type(A().one, expected_text="A") -reveal_type(A.two, expected_text="type[A]") - -reveal_type(B().one, expected_text="B") -reveal_type(B.two, expected_text="type[B]") diff --git a/packages/vipeye-internal/src/tests/samples/self6.py b/packages/vipeye-internal/src/tests/samples/self6.py deleted file mode 100644 index 12b695a0..00000000 --- a/packages/vipeye-internal/src/tests/samples/self6.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that a Self type used within a `__new__` method does -# not preclude the use of a contravariant TypeVar within a generic class. - -from typing import Self, TypeVar, Generic - -T_contra = TypeVar("T_contra", contravariant=True) - - -class MyClass(Generic[T_contra]): - def __new__(cls: type[Self]) -> Self: ... - - -MyClass[int]() diff --git a/packages/vipeye-internal/src/tests/samples/self7.py b/packages/vipeye-internal/src/tests/samples/self7.py deleted file mode 100644 index 3223be8a..00000000 --- a/packages/vipeye-internal/src/tests/samples/self7.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the case where type[Self] is returned but Self -# is expected. - -from typing import Self - - -class Foo: - @classmethod - def bar(cls) -> Self: - # This should generate an error. - return cls diff --git a/packages/vipeye-internal/src/tests/samples/self8.py b/packages/vipeye-internal/src/tests/samples/self8.py deleted file mode 100644 index c42f08e2..00000000 --- a/packages/vipeye-internal/src/tests/samples/self8.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests that a __new__ method allows for the Self -# to be associated with the provided `cls` argument rather than -# the class bound to the `__new__` method. - -import enum -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - Self, - reveal_type, -) - - -class Enum1(enum.IntEnum): - def __new__(cls, value: int, doc: str) -> Self: - member = int.__new__(cls, value) - reveal_type(member, expected_text="Self@Enum1") - member._value_ = value - member.__doc__ = doc - return member - - -class MyStr(str): - pass - - -v1 = str.__new__(MyStr) -reveal_type(v1, expected_text="MyStr") diff --git a/packages/vipeye-internal/src/tests/samples/self9.py b/packages/vipeye-internal/src/tests/samples/self9.py deleted file mode 100644 index c68286f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/self9.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the case where a parent class defines a class variable -# that uses Self and a child class accesses this through self or cls. - -from typing import Self - - -class ParentA: - a: list[Self] - - -class ChildA(ParentA): - b: int - - @classmethod - def method1(cls) -> None: - reveal_type(cls.a, expected_text="list[Self@ChildA]") - reveal_type(cls.a[0], expected_text="Self@ChildA") - print(cls.a[0].b) - - def method2(self) -> None: - reveal_type(self.a, expected_text="list[Self@ChildA]") - reveal_type(self.a[0], expected_text="Self@ChildA") - print(self.a[0].b) diff --git a/packages/vipeye-internal/src/tests/samples/sentinel1.py b/packages/vipeye-internal/src/tests/samples/sentinel1.py deleted file mode 100644 index 2dc1693c..00000000 --- a/packages/vipeye-internal/src/tests/samples/sentinel1.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests the handling of Sentinel as described in PEP 661. - -from typing import Literal, TypeAlias -from typing_extensions import Sentinel, TypeForm # viper: ignore[reportMissingModuleSource] - -# This should generate an error because the names don't match. -BAD_NAME1 = Sentinel("OTHER") - -# This should generate an error because the arg count is wrong. -BAD_CALL1 = Sentinel() - -# This should generate an error because the arg count is wrong. -BAD_CALL2 = Sentinel("BAD_CALL2", 1) - -# This should generate an error because the arg type is wrong. -BAD_CALL3 = Sentinel(1) - -MISSING = Sentinel("MISSING") - -type TA1 = int | MISSING - -TA2: TypeAlias = int | MISSING - -TA3 = int | MISSING - -# This should generate an error because Literal isn't appropriate here. -x: Literal[MISSING] - - -def func1(value: int | MISSING) -> None: - if value is MISSING: - reveal_type(value, expected_text="MISSING") - else: - reveal_type(value, expected_text="int") - - -def func2(value=MISSING) -> None: - pass - - -reveal_type(func2, expected_text="(value: Unknown | MISSING = MISSING) -> None") - - -def test_typeform[T](v: TypeForm[T]) -> TypeForm[T]: ... - - -reveal_type(test_typeform(MISSING), expected_text="TypeForm[MISSING]") - - -def func3(x: Literal[0, 3, "hi"] | MISSING) -> None: - if x: - reveal_type(x, expected_text="MISSING | Literal[3, 'hi']") - else: - reveal_type(x, expected_text="Literal[0]") - - -t1 = type(MISSING) -reveal_type(t1, expected_text="type[MISSING]") diff --git a/packages/vipeye-internal/src/tests/samples/sentinel2.py b/packages/vipeye-internal/src/tests/samples/sentinel2.py deleted file mode 100644 index 9f60714f..00000000 --- a/packages/vipeye-internal/src/tests/samples/sentinel2.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the handling of the sentinel builtin added in Python 3.15. - -from typing import Literal, TypeAlias - -# This should generate an error because the names don't match. -BAD_NAME1 = sentinel("OTHER") - -# This should generate an error because the arg count is wrong. -BAD_CALL1 = sentinel() - -# This should generate an error because the arg count is wrong. -BAD_CALL2 = sentinel("BAD_CALL2", 1) - -# This should generate an error because the arg type is wrong. -BAD_CALL3 = sentinel(1) - - -MISSING = sentinel("MISSING") - -type TA1 = int | MISSING - -TA2: TypeAlias = int | MISSING - -# This should generate an error because Literal isn't appropriate here. -x: Literal[MISSING] - - -def func1(value: int | MISSING) -> None: - if value is MISSING: - reveal_type(value, expected_text="MISSING") - else: - reveal_type(value, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/slice1.py b/packages/vipeye-internal/src/tests/samples/slice1.py deleted file mode 100644 index c5245518..00000000 --- a/packages/vipeye-internal/src/tests/samples/slice1.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the evaluation of slice types. - - -class ClassA: - def __getitem__[T](self, item: T) -> T: - return item - - -a1 = ClassA() - -reveal_type(a1[::], expected_text="slice[None, None, None]") -reveal_type( - a1[1:"a":False], expected_text="slice[Literal[1], Literal['a'], Literal[False]]" -) -reveal_type(a1[:3:5.0], expected_text="slice[None, Literal[3], float]") diff --git a/packages/vipeye-internal/src/tests/samples/slots1.py b/packages/vipeye-internal/src/tests/samples/slots1.py deleted file mode 100644 index d7116514..00000000 --- a/packages/vipeye-internal/src/tests/samples/slots1.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests the type checker's validation of instance -# variables that are declared in the __slots__ attribute. - - -class NoSlots1: - def __init__(self): - self.x = 1 - - -class NoSlots2: - # Only lists and tuples of simple strings are supported, so this - # will be treated as though there are no slots. - __slots__ = {"aaa": 3} - - def __init__(self): - self.x = 1 - - -class NoSlots3: - # Only lists and tuples of simple strings are supported, so this - # will be treated as though there are no slots. - __slots__ = ("aaa", f"test{3 + 4}") - - def __init__(self): - self.x = 1 - - -class Slots1(object): - __slots__ = ("bbb", "ccc") - - def __init__(self): - self.bbb = 1 - self.ccc = 1 - self.prop = 1 - - # This should generate an error - self.ddd = 1 - - @property - def prop(self): - pass - - @prop.setter - def prop(self, val: int): - pass - - -class Slots1_1(Slots1): - __slots__ = ["ddd", "eee"] - - def __init__(self): - self.bbb = 1 - self.ccc = 1 - self.ddd = 1 - - # This should generate an error - self.fff = 1 - - -class NoSlots1_1(Slots1, NoSlots2): - def __init__(self): - self.bbb = 1 - self.fff = 1 diff --git a/packages/vipeye-internal/src/tests/samples/slots2.py b/packages/vipeye-internal/src/tests/samples/slots2.py deleted file mode 100644 index 0062a5d2..00000000 --- a/packages/vipeye-internal/src/tests/samples/slots2.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the type checker's validation of class variables -# whose name conflict with a __slots__ entry. - -from dataclasses import dataclass, field - - -class NoSlots1: - pass - - -class Slots1(NoSlots1): - __slots__ = "aaa", "bbb", "ccc" - - # This should generate an error - aaa = 3 - - # This should generate an error - bbb: int = 3 - - # This should generate an error - (ccc, ddd) = 3, 4 - - eee = 5 - - -class Slots2(Slots1): - __slots__ = () - - aaa = 4 - - -@dataclass -class Slots3: - __slots__ = ("values",) - - # This should not generate an error because class variables - # in a dataclass are replaced by instance variables. - values: list[int] = field(default_factory=list) diff --git a/packages/vipeye-internal/src/tests/samples/slots3.py b/packages/vipeye-internal/src/tests/samples/slots3.py deleted file mode 100644 index 86d5909f..00000000 --- a/packages/vipeye-internal/src/tests/samples/slots3.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the case where a descriptor is assigned to a -# class variable but not included in __slots__. - -from typing import Any - - -class MyDescriptor: - def __init__(self, *, slot: str): ... - - def __set__(self, instance: object, value: object) -> None: ... - - def __get__(self, instance: object, owner: Any) -> Any: ... - - -class ClassA: - foo = MyDescriptor(slot="_foo_descriptor") - __slots__ = "_foo_descriptor" - - def __init__(self, foo: int) -> None: - self.foo = foo - - -class ClassBParent: - __slots__ = ("bar1",) - foo = MyDescriptor(slot="_foo_descriptor") - - -class ClassB(ClassBParent): - __slots__ = ("bar2",) - - def repro(self, foo: int) -> None: - self.foo = foo diff --git a/packages/vipeye-internal/src/tests/samples/slots4.py b/packages/vipeye-internal/src/tests/samples/slots4.py deleted file mode 100644 index 30f9c224..00000000 --- a/packages/vipeye-internal/src/tests/samples/slots4.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the case where a descriptor is assigned to an -# instance variable that is included in __slots__. - -from typing import Self, overload - - -class A: - pass - - -class Descriptor: - name: str - - @overload - def __get__(self, obj: None, objtype: type[A] | None = None) -> Self: ... - - @overload - def __get__(self, obj: A, objtype: type[A] | None = None) -> int: ... - - def __get__(self, obj: A | None, objtype: type[A] | None = None) -> Self | int: ... - - def __set__(self, obj: A, value: int): ... - - -class B: - __slots__ = "descriptor" - - def __init__(self, descriptor: Descriptor): - self.descriptor = descriptor - - -v1 = B(descriptor=Descriptor()) -reveal_type(v1.descriptor.name, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/solver1.py b/packages/vipeye-internal/src/tests/samples/solver1.py deleted file mode 100644 index bce1d339..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver1.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the constraint solver's handling of callables -# whose input parameters are contravariant. - -from typing import TypeVar, Callable - -T = TypeVar("T") -U = TypeVar("U") -V = TypeVar("V") - - -def compose2(f: Callable[[T], U], g: Callable[[U], V]) -> Callable[[T], V]: - def composition(x: T) -> V: - return g(f(x)) - - return composition - - -def add_one(x: int) -> int: - return x + 1 - - -def make_str(x: int) -> str: - return str(x) - - -add_two: Callable[[int], str] = compose2(add_one, make_str) diff --git a/packages/vipeye-internal/src/tests/samples/solver10.py b/packages/vipeye-internal/src/tests/samples/solver10.py deleted file mode 100644 index a2fecdcb..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver10.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample checks the handling of constraint solving -# in the case where list and tuple expressions are being -# matched, and those expressions contain literal values. -# We need to validate that the type inference for lists -# is not over-narrowing when matching these literals. - -from typing import Callable, TypeVar - - -_T = TypeVar("_T") - - -def extend_if(xs: list[_T], ys: list[tuple[_T, bool]]) -> list[_T]: - raise NotImplementedError() - - -extend_if(["foo"], [("bar", True), ("baz", True)]) - - -def func1(value: _T) -> Callable[[_T], None]: ... - - -def func2() -> Callable[[bool], None]: - return func1(True) diff --git a/packages/vipeye-internal/src/tests/samples/solver11.py b/packages/vipeye-internal/src/tests/samples/solver11.py deleted file mode 100644 index 8c53ccec..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver11.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the constraint solver when a callable type is involved. - -# viper: strict - -from typing import Callable, Literal, TypeVar - - -def filter_fn(value: object): ... - - -v1 = filter(filter_fn, [1, 2, 3]) -reveal_type(v1, expected_text="filter[int]") - -v2 = filter(filter_fn, {1, 2}) -reveal_type(v2, expected_text="filter[int]") - -v3 = filter(filter_fn, {1: 2}) -reveal_type(v3, expected_text="filter[int]") - - -_T = TypeVar("_T") -Animal = Literal["cat"] - - -def func(v: Callable[[], _T]) -> _T: ... - - -x1: dict[Animal, int] = func(lambda: {"cat": 0}) - - -def func1(factory: Callable[[], _T]) -> _T: ... - - -x2: set[int] = func1(lambda: set()) diff --git a/packages/vipeye-internal/src/tests/samples/solver12.py b/packages/vipeye-internal/src/tests/samples/solver12.py deleted file mode 100644 index ffd248a0..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver12.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample validates that a generic type can be used to solve a -# TypeVar in a generic method where the "self" parameter is itself generic. - -from typing import TypeVar - -_T1 = TypeVar("_T1", bound="ClassA") -_T2 = TypeVar("_T2", bound="ClassA") - - -class ClassA: - def chain(self: _T1) -> _T1: ... - - -def func1(p1: _T2) -> _T2: - return p1.chain() diff --git a/packages/vipeye-internal/src/tests/samples/solver13.py b/packages/vipeye-internal/src/tests/samples/solver13.py deleted file mode 100644 index 40b50ecb..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver13.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests that type variables chain properly. - -from typing import Generic, Iterable, Iterator, TypeVar -from itertools import chain - -T = TypeVar("T") - - -class ClassA(Iterator[T]): - def __init__(self, it: Iterable[T]) -> None: ... - - def __next__(self) -> T: ... - - def __iter__(self) -> Iterator[T]: ... - - -def func1(val: Iterable[T]) -> Iterator[T]: - return ClassA(val) - - -def func2(val: Iterable[Iterable[T]]) -> Iterator[T]: - return chain(*val) - - -class ClassB(Generic[T]): - def __init__(self, xs: Iterable[T]) -> None: - self.xs = xs - - def indexed(self) -> "ClassB[tuple[int, T]]": - return ClassB(enumerate(self.xs)) diff --git a/packages/vipeye-internal/src/tests/samples/solver14.py b/packages/vipeye-internal/src/tests/samples/solver14.py deleted file mode 100644 index 38508e4c..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver14.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the TypeVar constraint solver in cases where -# generic protocols are used. - -from datetime import timedelta -from typing import Any, Generic, Protocol, TypeVar, overload - -_X_co = TypeVar("_X_co", covariant=True) -_X_contra = TypeVar("_X_contra", contravariant=True) - - -class SupportsDivMod(Protocol, Generic[_X_contra, _X_co]): - def __divmod__(self, __other: _X_contra) -> _X_co: ... - - -class SupportsRDivMod(Protocol[_X_contra, _X_co]): - def __rdivmod__(self, __other: _X_contra) -> _X_co: ... - - -@overload -def divmod(__x: SupportsDivMod[_X_contra, _X_co], __y: _X_contra) -> _X_co: ... - - -@overload -def divmod(__x: _X_contra, __y: SupportsRDivMod[_X_contra, _X_co]) -> _X_co: ... - - -def divmod(__x: Any, __y: Any) -> Any: ... - - -reveal_type( - divmod(timedelta(minutes=90), timedelta(hours=1)), - expected_text="tuple[int, timedelta]", -) -reveal_type(divmod(3, 4), expected_text="tuple[int, int]") -reveal_type(divmod(3.6, 4), expected_text="tuple[float, float]") -reveal_type(divmod(3, 4.5), expected_text="tuple[float, float]") - - -class SupportsLessThan(Protocol): - def __lt__(self, __other: Any) -> bool: ... - - -SupportsLessThanT = TypeVar("SupportsLessThanT", bound=SupportsLessThan) - - -def max2(__arg1: SupportsLessThanT, __arg2: SupportsLessThanT) -> SupportsLessThanT: ... - - -def min2(__arg1: SupportsLessThanT, __arg2: SupportsLessThanT) -> SupportsLessThanT: ... - - -def func1(): - x = max2(1, min2(1, 4.5)) - reveal_type(x, expected_text="float") diff --git a/packages/vipeye-internal/src/tests/samples/solver15.py b/packages/vipeye-internal/src/tests/samples/solver15.py deleted file mode 100644 index 1682cbe4..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver15.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the handling of a bound TypeVar that is used -# in a Type[X] statement. - -from typing import Callable, Generic, TypeVar - - -class Base: ... - - -T = TypeVar("T", bound=Base) - - -def register(state_name: str, state: type[T]): ... - - -def register_state(state_name: str) -> Callable[[type[T]], type[T]]: - def decorator(state: type[T]) -> type[T]: - register(state_name, state) - return state - - return decorator - - -class F: ... - - -E = TypeVar("E", bound=F) - - -def coercer_method(value: E | str, enum: type[E]) -> E: ... - - -class C(Generic[E]): - e_type: type[E] - - def coerce(self, e_type: type[E], value: E | str) -> E: - return coercer_method(value, self.e_type) diff --git a/packages/vipeye-internal/src/tests/samples/solver16.py b/packages/vipeye-internal/src/tests/samples/solver16.py deleted file mode 100644 index a4c0daec..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver16.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests the case where a TypeVar is used in the parameter -# of a callable (and is hence treated as contravariant). - -from typing import Callable, Sequence, TypeVar - -T = TypeVar("T") -U = TypeVar("U") - - -def func1(value: T) -> T: ... - - -def func2(values: Sequence[T]) -> T: ... - - -def func3(value: T, callback: Callable[[T], U]) -> U: ... - - -def func4(values: Sequence[T], callback: Callable[[Sequence[T]], U]) -> U: ... - - -reveal_type(func3(1.0, func1), expected_text="float") -reveal_type(func4([1.0], func1), expected_text="Sequence[float]") -reveal_type(func4([1.0], func2), expected_text="float") - - -def func5(obj: object, cb: Callable[[], Callable[[T], object]]) -> None: - # This should generate an error. - cb()(obj) diff --git a/packages/vipeye-internal/src/tests/samples/solver17.py b/packages/vipeye-internal/src/tests/samples/solver17.py deleted file mode 100644 index fa395cb4..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver17.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where a source and dest type -# are unions and are being compared using invariant constraints -# and the dest type contains a type variable. - -from typing import Pattern, Sequence, TypeVar - - -_T = TypeVar("_T") - - -def func1(v: list[_T | None]) -> _T: ... - - -def func2(v: list[_T | str | None]) -> _T: ... - - -v1: list[int | None] = [1, None] -r1 = func1(v1) -reveal_type(r1, expected_text="int") - -v2: list[int | str | None] = [1, None] -r2_1 = func1(v2) -reveal_type(r2_1, expected_text="int | str") - -r2_2 = func2(v2) -reveal_type(r2_2, expected_text="int") - -v3: list[str | Sequence[Pattern]] = [""] diff --git a/packages/vipeye-internal/src/tests/samples/solver18.py b/packages/vipeye-internal/src/tests/samples/solver18.py deleted file mode 100644 index 5c2e9b1a..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver18.py +++ /dev/null @@ -1,74 +0,0 @@ -# This sample tests the handling of functions that include TypeVars -# within unions, where the TypeVar may not be solved during constraint -# solving. - -from typing import Awaitable, Callable, Generic, ParamSpec, TypeVar - - -_T = TypeVar("_T") -_P = ParamSpec("_P") - - -def func1(x: str | None | _T) -> str | None | _T: ... - - -reveal_type(func1(None), expected_text="str | None") -reveal_type(func1("hi"), expected_text="str | None") -reveal_type(func1(3), expected_text="str | int | None") - - -def func2(x: str | None | _T) -> list[str | None | _T]: ... - - -reveal_type(func2(None), expected_text="list[str | None]") -reveal_type(func2("hi"), expected_text="list[str | None]") -reveal_type(func2(3), expected_text="list[str | int | None]") - - -Callback = Callable[..., Awaitable[None]] -_C = TypeVar("_C", bound=Callback) - - -class ClassA(Generic[_C]): ... - - -def decorator1() -> Callable[[_C | ClassA[_C]], ClassA[_C]]: ... - - -@decorator1() -async def func3() -> None: ... - - -def func4(l: list): - return next(iter(l), None) - - -val = func4([]) -reveal_type(val, expected_text="Unknown | None") - - -def func5() -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: ... - - -def func6(x: int) -> str: ... - - -reveal_type(func5()(func6), expected_text="(x: int) -> str") - - -class ClassB(Generic[_P]): - def method1(self, val: str, *args: _P.args, **kwargs: _P.kwargs) -> None: - pass - - -def decorator2() -> Callable[[Callable[_P, None]], ClassB[_P]]: ... - - -@decorator2() -def func7(y: int) -> None: - pass - - -reveal_type(func7, expected_text="ClassB[(y: int)]") -reveal_type(func7.method1, expected_text="(val: str, y: int) -> None") -reveal_type(func7.method1("", 1), expected_text="None") diff --git a/packages/vipeye-internal/src/tests/samples/solver19.py b/packages/vipeye-internal/src/tests/samples/solver19.py deleted file mode 100644 index 972e6c21..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver19.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the handling of Type[T] matching and replacement. - -from typing import Generator, TypeVar - - -class LI(list[int]): - pass - - -class LS(list[str]): - pass - - -_T1 = TypeVar("_T1") - - -class MyList(list[LI | LS]): - def get_generator(self, *, type_: type[_T1]) -> Generator[_T1, None, None]: - for elem in self: - if isinstance(elem, type_): - yield elem - - -def same(other: LI | LS): - for elem in MyList().get_generator(type_=other.__class__): - for v in elem: - print(v) diff --git a/packages/vipeye-internal/src/tests/samples/solver2.py b/packages/vipeye-internal/src/tests/samples/solver2.py deleted file mode 100644 index 112b47d5..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver2.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample validates constraint solving for protocol -# classes where the protocol is partially specialized with a -# type variable. - -# viper: strict - -from typing import Callable, Iterator, Protocol, TypeVar - -_T = TypeVar("_T", covariant=True) - - -class ProtoA(Iterator[_T], Protocol): - pass - - -def decorator1(func: Callable[..., Iterator[_T]]) -> Callable[..., ProtoA[_T]]: ... - - -@decorator1 -def func1() -> Iterator[str]: - yield "" - - -a = func1() -b: ProtoA[str] = a diff --git a/packages/vipeye-internal/src/tests/samples/solver20.py b/packages/vipeye-internal/src/tests/samples/solver20.py deleted file mode 100644 index e9e9f144..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver20.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where a type variable is bound to a union. - -from typing import Callable, TypeVar - -T = TypeVar("T") -IntStr = str | int -T1 = TypeVar("T1", bound=IntStr) -T2 = TypeVar("T2", bound=IntStr) - - -def custom_eq(x: IntStr, y: IntStr) -> bool: - return True - - -def eq(f: Callable[[T1], T2], x: T1, y: T2) -> bool: - return custom_eq(f(x), y) diff --git a/packages/vipeye-internal/src/tests/samples/solver21.py b/packages/vipeye-internal/src/tests/samples/solver21.py deleted file mode 100644 index cd627e8a..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver21.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests for proper handling of bound TypeVars. - -from typing import Generic, TypeVar - - -class A: ... - - -class B: ... - - -_T3 = TypeVar("_T3", bound=A | B) - - -class Registry(Generic[_T3]): - def __init__(self) -> None: - self.registry = {} - - @property - def registry(self) -> dict[str, _T3]: ... - - @registry.setter - def registry(self, registry: dict[str, _T3]) -> None: ... - - def get(self, _id: str) -> _T3 | None: - return self.registry.get(_id) diff --git a/packages/vipeye-internal/src/tests/samples/solver22.py b/packages/vipeye-internal/src/tests/samples/solver22.py deleted file mode 100644 index 272f322b..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver22.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the special-case handling of "type" when used -# as an assignment for Type[T]. - -from typing import Any, TypeVar - -T = TypeVar("T") - - -def f(x: type[T]) -> T: ... - - -def g() -> type | Any: ... - - -y = g() - -f(y) diff --git a/packages/vipeye-internal/src/tests/samples/solver23.py b/packages/vipeye-internal/src/tests/samples/solver23.py deleted file mode 100644 index defdfed1..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver23.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests that invariant type variables are enforced. - -from typing import Hashable - - -def func1(x: list[Hashable]): ... - - -def func2(x: list[object]): ... - - -v1: list[int] = [1] - -# This should generate an error. -func1(v1) - -# This should generate an error. -func2(v1) diff --git a/packages/vipeye-internal/src/tests/samples/solver24.py b/packages/vipeye-internal/src/tests/samples/solver24.py deleted file mode 100644 index 1f6881ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver24.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests the case where the constraint solver's solution involves -# a union of type variables. - -from os import PathLike -from typing import AnyStr, Generic, Iterable, Iterator, Protocol, TypeAlias, TypeVar - -V = TypeVar("V") -V_co = TypeVar("V_co", covariant=True) -T = TypeVar("T") -U = TypeVar("U") - - -class ClassA(Generic[V_co]): - pass - - -class ClassB(Generic[V_co]): - def __init__(self, x: ClassA[V_co]): - pass - - -def func1(a: ClassA[V], b: ClassA[U], c: bool) -> ClassB[V | U]: - x: ClassA[V | U] = a - reveal_type(x, expected_text="ClassA[V@func1]") - if c: - x = b - reveal_type(x, expected_text="ClassA[U@func1]") - r = ClassB(x) - - reveal_type(r, expected_text="ClassB[U@func1 | V@func1]") - return r - - -class ClassC(Generic[AnyStr]): ... - - -class ClassD(Iterator[ClassC[AnyStr]], Protocol): ... - - -GenericPath: TypeAlias = AnyStr | PathLike[AnyStr] - - -def func2(iter: Iterable[object]) -> bool: ... - - -def func3(path: GenericPath[AnyStr]) -> ClassD[AnyStr]: ... - - -def func4(val: str): - func2(func3(val)) - - -def func5(a: dict[T, U], b: list[T | U]): - pass - - -def func6(a: dict[str, int], b: list[str | int]): - func5(a, b) diff --git a/packages/vipeye-internal/src/tests/samples/solver25.py b/packages/vipeye-internal/src/tests/samples/solver25.py deleted file mode 100644 index 6fee6f15..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver25.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the handling of invariant union type compatibility -# checks that include a callable with a type variable. - -from typing import Callable, TypeVar - - -T = TypeVar("T") - - -def str2int(a: str) -> int: - return int(a) - - -def int2str(b: int) -> str: - return str(b) - - -def func1(cb: Callable[[str], T], val: list[Callable[[T], str] | None]): - pass - - -func1(str2int, [int2str]) -func1(str2int, [None]) -func1(str2int, []) -func1(str2int, [int2str, None]) diff --git a/packages/vipeye-internal/src/tests/samples/solver26.py b/packages/vipeye-internal/src/tests/samples/solver26.py deleted file mode 100644 index a087a2f9..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver26.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that when an unspecialized generic class type is used as -# a constraint in the constraint solver, default type arguments (typically -# `Unknown`) are used. - -from collections import defaultdict - - -def func1() -> None: - d1 = defaultdict(list) - reveal_type(d1, expected_text="defaultdict[Unknown, list[Unknown]]") diff --git a/packages/vipeye-internal/src/tests/samples/solver27.py b/packages/vipeye-internal/src/tests/samples/solver27.py deleted file mode 100644 index f1171bb0..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver27.py +++ /dev/null @@ -1,52 +0,0 @@ -# This sample tests that the assignment of an instantiable generic class -# without supplied type arguments is given default type arguments (typically -# Unknown) when the TypeVar is solved. - -from typing import Any, Callable, Generic, Iterable, TypeVar, reveal_type - -T = TypeVar("T") - - -def deco1(t: type[T], val: Any) -> T: - return val - - -v1 = deco1(dict, {"foo": "bar"}) -reveal_type(v1, expected_text="dict[Unknown, Unknown]") - - -def deco2(t: T, val: Any) -> T: - return val - - -v2 = deco2(dict, {"foo": "bar"}) -reveal_type(v2, expected_text="type[dict[Unknown, Unknown]]") - - -def deco3(t: type[T]) -> type[T]: - return t - - -@deco3 -class ClassA(Generic[T]): - pass - - -reveal_type(ClassA[int], expected_text="type[ClassA[int]]") - - -def deco4() -> Callable[[type[T]], type[T]]: ... - - -@deco4() -class ClassB: - def get_features(self) -> list[str]: ... - - -def func1(specs: Iterable[str] | ClassB) -> None: - if isinstance(specs, ClassB): - features = specs.get_features() - else: - features = specs - - set(features) diff --git a/packages/vipeye-internal/src/tests/samples/solver28.py b/packages/vipeye-internal/src/tests/samples/solver28.py deleted file mode 100644 index 0b78dadd..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver28.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the case where a TypeVar has a bound of `type` and -# is assigned to a `type[T]`. - -from typing import TypeVar - -T = TypeVar("T") -S = TypeVar("S", bound=type) - - -def func1(x: type[T]) -> type[T]: - return x - - -def func2(x: S) -> S: - v1 = func1(x) - reveal_type(v1, expected_text="Unknown") - return v1 - - -def func3[R: int](num: type[R]) -> None: ... - - -class A[T: type[int]](tuple[T]): ... - - -func3(*A[type[int]]()) diff --git a/packages/vipeye-internal/src/tests/samples/solver29.py b/packages/vipeye-internal/src/tests/samples/solver29.py deleted file mode 100644 index e1498c86..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver29.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests the case where a union of two "bare" TypeVars are -# used in the annotation of a function parameter. - -from typing import Any, TypeVar, Callable - -S = TypeVar("S") -T = TypeVar("T") - - -def accepts_bool(b: bool) -> None: ... - - -def accepts_int(i: int) -> None: ... - - -def func1(x: S | T, l2: Callable[[S], Any], l3: Callable[[T], Any]) -> tuple[S, T]: ... - - -def func2(x: T | S, l2: Callable[[S], Any], l3: Callable[[T], Any]) -> tuple[S, T]: ... - - -x1 = func1(0, accepts_int, accepts_bool) -reveal_type(x1, expected_text="tuple[int, bool]") - -x2 = func1(True, accepts_int, accepts_bool) -reveal_type(x2, expected_text="tuple[int, bool]") - -x3 = func1(0, accepts_int, accepts_bool) -reveal_type(x3, expected_text="tuple[int, bool]") - -x4 = func1(True, accepts_int, accepts_bool) -reveal_type(x4, expected_text="tuple[int, bool]") diff --git a/packages/vipeye-internal/src/tests/samples/solver3.py b/packages/vipeye-internal/src/tests/samples/solver3.py deleted file mode 100644 index a9176a3e..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver3.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests constraint solving in a situation -# where the type has a type argument that is -# a union of types that are subclasses of each other. - -from typing import Iterable, Iterator, Literal, TypeVar - -_T = TypeVar("_T") - - -def filter(__function: None, __iterable: Iterable[_T | None]) -> Iterator[_T]: ... - - -# In this case, bool is a subclass of int, so the TypeVar -# matching for _T should evaluate to Iterator[int]. -list_of_bools_and_ints: list[Literal[False] | int] = [] -generator_of_ints = filter(None, list_of_bools_and_ints) - -a: int = next(generator_of_ints) - -# This should generate an error. -b: bool = next(generator_of_ints) diff --git a/packages/vipeye-internal/src/tests/samples/solver30.py b/packages/vipeye-internal/src/tests/samples/solver30.py deleted file mode 100644 index 46a49fa2..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver30.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the case where a deeply nested set of calls requires -# the use of bidirectional type inference to evaluate the type of a lambda. - -from typing import Any, Callable, Iterable, Iterator, Protocol, TypeVar - -X = TypeVar("X") -Y = TypeVar("Y") -Z = TypeVar("Z") - - -class Item: - foo: bool - - -items = [Item()] - - -def func1(a: Iterable[X]) -> X: ... - - -def func2(a: Iterable[Y]) -> Iterable[Y]: ... - - -class func3(Iterator[Z]): - def __init__(self, a: Callable[[Z], Any], b: Iterable[Z]) -> None: ... - - def __next__(self) -> Z: ... - - -def func4(a: Callable[[Z], Any], b: Iterable[Z]) -> Iterator[Z]: ... - - -func1(func2(func3(lambda x: reveal_type(x.foo, expected_text="bool"), items))) - -func1(func2(func4(lambda x: reveal_type(x.foo, expected_text="bool"), items))) diff --git a/packages/vipeye-internal/src/tests/samples/solver31.py b/packages/vipeye-internal/src/tests/samples/solver31.py deleted file mode 100644 index 5209ed76..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver31.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where an expected type contains a union, -# as in the case where the list.__add__ method returns the type -# list[_T | _S]. - -from typing import Generic, Iterable, TypeVar - -T = TypeVar("T") - - -class A(Generic[T]): - def __init__(self, i: Iterable[T]): ... - - -def func1(i: Iterable[T]) -> T: ... - - -reveal_type(func1([0] + [""]), expected_text="str | int") -reveal_type(A([0] + [""]), expected_text="A[str | int]") diff --git a/packages/vipeye-internal/src/tests/samples/solver32.py b/packages/vipeye-internal/src/tests/samples/solver32.py deleted file mode 100644 index 82105b0f..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver32.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests a complex interplay between protocols and bound TypeVars. -# This case involves numpy types and has regressed in the past. - - -from typing import Protocol, Self, TypeVar - -TD = TypeVar("TD", bound="TimeDeltaProto") -DT = TypeVar("DT", bound="DateTimeProto") - - -class TimeDeltaProto(Protocol): - def __pos__(self) -> Self: ... - - -class DateTimeProto(Protocol[TD]): - def __add__(self, other: TD, /) -> Self: ... - - def __sub__(self, other: Self, /) -> TD: ... - - -class TimeDelta: - def __pos__(self) -> Self: ... - - -class DateTime: - def __add__(self, other: bool | int) -> Self: ... - - def __sub__(self, other: "DateTime") -> TimeDelta: ... - - -def func1(__val: DT) -> DT: - return __val - - -dt = DateTime() -reveal_type(func1(dt), expected_text="DateTime") diff --git a/packages/vipeye-internal/src/tests/samples/solver33.py b/packages/vipeye-internal/src/tests/samples/solver33.py deleted file mode 100644 index ab9a16ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver33.py +++ /dev/null @@ -1,9 +0,0 @@ -# This sample tests a case that resulted in a false positive in the past. - -# viper: strict - -import operator - -keys = ("+", "-") -values = (operator.pos, operator.neg) -mapping = dict(zip(keys, values)) diff --git a/packages/vipeye-internal/src/tests/samples/solver34.py b/packages/vipeye-internal/src/tests/samples/solver34.py deleted file mode 100644 index 7af73f07..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver34.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case where a generic function returns a Callable type -# that is specialized with unsolved type variables. - -from collections.abc import Container -from typing import TypeVar, Callable - - -T = TypeVar("T") -VT = TypeVar("VT") - - -def func1(container: Container[T]) -> Callable[[T], bool]: ... - - -def func2(a: T, b: Container[VT]) -> T: - cmp = func1(b) - - # This should generate an error. - cmp(a) - - return a diff --git a/packages/vipeye-internal/src/tests/samples/solver35.py b/packages/vipeye-internal/src/tests/samples/solver35.py deleted file mode 100644 index 1314bb17..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver35.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the case where the constraint solver is asked to -# solve a TypeVar that is in an invariant context. - -from typing import TypeVar - -T1 = TypeVar("T1") -T2 = TypeVar("T2") - - -def func1(v1: T1, v2: T2, v1_list: list[T1], v2_list: list[T2]): ... - - -def func2(v1: int, v2: str, v1_list: list[int], v2_list: list[str]): - func1(v1, v2, v1_list, v2_list) - - # This should generate an error because the last two arguments are swapped. - func1(v2, v1, v1_list, v2_list) - - # This should generate an error because the last two arguments are swapped. - func1(v1_list=v1_list, v2_list=v2_list, v1=v2, v2=v1) diff --git a/packages/vipeye-internal/src/tests/samples/solver36.py b/packages/vipeye-internal/src/tests/samples/solver36.py deleted file mode 100644 index 1a77444d..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver36.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests that upper bound constraints are honored when solving -# a type variable. - -from typing import Generic, SupportsAbs, TypeVar - - -T = TypeVar("T") -P = TypeVar("P", bound=SupportsAbs) - - -class BaseContainer(Generic[T]): - item: T - - -class Container(BaseContainer[P]): - def __init__(self, obj: P) -> None: - self.item = obj - - -def func1(obj: BaseContainer[T]) -> T: - return obj.item - - -func1(Container(1)) - -func1(Container(1.0)) - - -# This should generate an error because str isn't compatible with -# the bound of the TypeVar in Container. -func1(Container("")) diff --git a/packages/vipeye-internal/src/tests/samples/solver37.py b/packages/vipeye-internal/src/tests/samples/solver37.py deleted file mode 100644 index 98881bd7..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver37.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests a complex TypeVar unification scenario. - -from typing import Callable, Generic, TypeVar - -A = TypeVar("A") -B = TypeVar("B") - - -class Gen(Generic[A]): ... - - -def func1(x: A) -> A: ... - - -def func2(x: Gen[A], y: A) -> Gen[Gen[A]]: ... - - -def func3(x: Gen[Gen[A]]) -> Gen[A]: - return func4(x, func1, func2) - - -def func4(x: Gen[A], id_: Callable[[B], B], step: Callable[[A, B], Gen[A]]) -> A: ... diff --git a/packages/vipeye-internal/src/tests/samples/solver38.py b/packages/vipeye-internal/src/tests/samples/solver38.py deleted file mode 100644 index 442bf184..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver38.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests a complex TypeVar unification scenario. - -from typing import Protocol, TypeVar - -A = TypeVar("A", contravariant=True) -B = TypeVar("B", covariant=True) -T = TypeVar("T") -U = TypeVar("U") -V = TypeVar("V") - - -class Getter(Protocol[A, B]): - def __call__(self, x: A, /) -> B: ... - - -class PolymorphicListItemGetter(Protocol): - def __call__(self, l: list[T], /) -> T: ... - - -def compose(get1: Getter[T, U], get2: Getter[U, V]) -> Getter[T, V]: ... - - -class HasMethod(Protocol): - @property - def method(self) -> int: ... - - -def get_value(x: HasMethod) -> int: ... - - -def upcast(x: PolymorphicListItemGetter) -> Getter[list[HasMethod], HasMethod]: - return x - - -def test(poly_getter: PolymorphicListItemGetter): - compose(poly_getter, get_value) - compose(upcast(poly_getter), get_value) diff --git a/packages/vipeye-internal/src/tests/samples/solver39.py b/packages/vipeye-internal/src/tests/samples/solver39.py deleted file mode 100644 index d736f1d0..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver39.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the case where an overloaded function is passed as -# an argument and the overloads cannot be filtered during the first -# pass through the arguments. - -from functools import reduce -from operator import getitem -from typing import Any - - -def deep_getitem(data: dict[str, Any], attr: str) -> Any: - return reduce(getitem, attr.split("."), data) diff --git a/packages/vipeye-internal/src/tests/samples/solver4.py b/packages/vipeye-internal/src/tests/samples/solver4.py deleted file mode 100644 index f2bf2149..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver4.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample validates that the type checker properly -# specializes a type for an unbound method (in this case, -# the "keys" method on "dict") based on the provided "self" -# argument. - -v1: dict[str, str] = {} - -# This should not result in an "Unknown", so no -# error should be generated. -result = dict.keys(v1) -reveal_type(result, expected_text="dict_keys[Unknown, Unknown]") diff --git a/packages/vipeye-internal/src/tests/samples/solver40.py b/packages/vipeye-internal/src/tests/samples/solver40.py deleted file mode 100644 index 8f141719..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver40.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample involves solving type variables that provide a lambda -# its expected type. - -# viper: strict - -from typing import Callable, TypeVar - -T = TypeVar("T") -U = TypeVar("U") - - -def func1(lst: list[T], init: U, f: Callable[[U, T], U]) -> U: ... - - -y = func1([1], 1, lambda x, y: x * y) diff --git a/packages/vipeye-internal/src/tests/samples/solver41.py b/packages/vipeye-internal/src/tests/samples/solver41.py deleted file mode 100644 index 6c3917c3..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver41.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a TypeVar is used in a contravariant -# and covariant position and the contravariant position involves a -# union with other types. - -from typing import Callable -from decimal import Decimal - - -def func1[T, U](func: Callable[[str | T], U], d: T) -> U: ... - - -func1(float, d="1.1") -func1(Decimal, d="1.1") diff --git a/packages/vipeye-internal/src/tests/samples/solver42.py b/packages/vipeye-internal/src/tests/samples/solver42.py deleted file mode 100644 index b20e0b1c..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver42.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the case involving assignment to a union that contains -# multiple instances of the same TypeVar. - -from typing import TypeVar - - -T = TypeVar("T") - - -def func1(x: tuple[T, list[T]] | list[T]) -> None: ... - - -def func2(x: tuple[T, list[T]] | None) -> None: ... - - -def test1(list_of_int: list[int]): - # This should generate an error. - func1((None, list_of_int)) - - # This should generate an error. - func2((None, list_of_int)) diff --git a/packages/vipeye-internal/src/tests/samples/solver43.py b/packages/vipeye-internal/src/tests/samples/solver43.py deleted file mode 100644 index 08cf561a..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver43.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests a case involving nested protocol types that was -# not working in a previous version of the type checker. - -from typing import Protocol - - -class Proto1[T](Protocol): - x: T - - -class Proto2[T](Protocol): - @staticmethod - def a() -> Proto1[T]: ... - @classmethod - def b(cls) -> list[T]: ... - - -class C[T]: - @staticmethod - def a() -> T: ... - @classmethod - def b[S](cls: type[Proto2[S]]) -> list[S]: ... - - -def test[S](x: type[Proto2[S]]): ... - - -test(C[Proto1[int]]) diff --git a/packages/vipeye-internal/src/tests/samples/solver44.py b/packages/vipeye-internal/src/tests/samples/solver44.py deleted file mode 100644 index 31735645..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver44.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where the solver generates an unsolved -# unification variable that has been specialized into a conditional type. - -from typing import Callable, Iterable, Self - - -class map[S]: - def __new__[T](cls, func: Callable[[T], S], iter1: Iterable[T]) -> Self: ... - - -def func(a: list[int | None]): - b = map(lambda x: x or 0, a) - reveal_type(b, expected_text="map[int]") diff --git a/packages/vipeye-internal/src/tests/samples/solver45.py b/packages/vipeye-internal/src/tests/samples/solver45.py deleted file mode 100644 index 6e215d57..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver45.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the case where an expression is assigned to an unpacked -# tuple, and the correctly-inferred type of the expression depends on -# bidirectional type inference. - -from typing import Literal, TypedDict - - -def func1[S, T](v: S | T, s: type[S], t: type[T]) -> tuple[S | None, T | None]: ... - - -def test1(): - a: int | None - b: str | None - - a, b = func1(1, int, str) - - -class TD1(TypedDict): - a: int - - -def test2(): - a: TD1 - b: TD1 - - a, b = ({"a": 1}, {"a": 2}) - - -def test3(): - a: Literal[1] - b: Literal[2] - - a, b = (1, 2) diff --git a/packages/vipeye-internal/src/tests/samples/solver5.py b/packages/vipeye-internal/src/tests/samples/solver5.py deleted file mode 100644 index 1d361e8a..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver5.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests constraint solving where the first -# encounter with the TypeVar is contravariant but later -# encounters are covariant or invariant. - - -def func1(value: object) -> bool: ... - - -v1 = filter(func1, ["b", "a", "r"]) -reveal_type(v1, expected_text="filter[str]") - -v2 = next(v1) -reveal_type(v2, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/solver6.py b/packages/vipeye-internal/src/tests/samples/solver6.py deleted file mode 100644 index 70db5025..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver6.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the type evaluator's handling of -# type vars that span multiple parameters - especially when -# the first parameter is a callable (which has parameters -# that are contravariant). - -from typing import Any, Callable, Iterable, Iterator, TypeVar - -_T = TypeVar("_T") - - -def is_one(x: int) -> bool: - return x == 1 - - -v1 = ["a", "b", "c"] - - -def func1( - __function: Callable[[_T], Any], __iterable: Iterable[_T] -) -> Iterator[_T]: ... - - -# This should be flagged as an error because nums is -# not an int array. -ones = func1(is_one, v1) diff --git a/packages/vipeye-internal/src/tests/samples/solver7.py b/packages/vipeye-internal/src/tests/samples/solver7.py deleted file mode 100644 index d63651e7..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver7.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests constraint solving in methods -# where the type is provided by a default initialization value -# rather than an argument provided directly by the caller. - -# We use "strict" here because we want to ensure that there are -# no "unknown" types remaining in this file. - -# viper: strict - -from typing import Generic, TypeVar -from collections.abc import Generator -from contextlib import contextmanager - -_A = TypeVar("_A") -_B = TypeVar("_B") - - -class ClassA(Generic[_A, _B]): - def __init__(self, a: _A, b: _B = "hello"): - self._foo_a = a - self._foo_b = b - - @property - def value_a(self): - return self._foo_a - - @property - def value_b(self): - return self._foo_b - - -a1 = ClassA(27) - -reveal_type(a1.value_a, expected_text="int") -reveal_type(a1.value_b, expected_text="str") - - -@contextmanager -def func1(default: _A | None = None) -> Generator[_A | str]: - yield "" - - -def func2(): - with func1() as y: - reveal_type(y, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/solver8.py b/packages/vipeye-internal/src/tests/samples/solver8.py deleted file mode 100644 index 67830444..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver8.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the constraint solver's special-case handling of -# Optional[T] within a function. - -from typing import TypeVar - -_T = TypeVar("_T") - - -def func1(v: _T | None) -> _T: - if v is None: - raise ValueError - return v - - -def func2(v: _T) -> _T: - if v is None: - raise ValueError - return v - - -f: int | None = None - -a: int = func1(f) - -# This should generate an error because type var _T -# should be matched to "Optional[int]". -b: int = func2(f) diff --git a/packages/vipeye-internal/src/tests/samples/solver9.py b/packages/vipeye-internal/src/tests/samples/solver9.py deleted file mode 100644 index 486e0c0a..00000000 --- a/packages/vipeye-internal/src/tests/samples/solver9.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests that Optional types can be matched -# to Type[T] expressions by the constraint solver. - -from typing import Callable, Generic, Optional, TypeVar - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2", bound=None) -_T3 = TypeVar("_T3") - - -def func1(a: type[_T1]) -> _T1: - return a() - - -a = func1(int) - - -def func2(a: type[_T2]) -> type[_T2]: - return a - - -b = func2(type(None)) - -# This should generate an error because None is -# not a type; it's an instance of the NoneType class. -c = func2(None) - - -class ClassA(Generic[_T1]): - def __init__(self, value: _T1) -> None: ... - - @classmethod - def get(cls: type[_T3]) -> type[_T3]: - return cls - - -class ClassB(ClassA): - pass - - -def func3(value: _T1) -> type[ClassA[_T1]]: - v1 = ClassA(value) - v2 = type(v1) - reveal_type(v2, expected_text="type[ClassA[_T1@func3]]") - return v2 - - -d = ClassB.get() -reveal_type(d, expected_text="type[ClassB]") -reveal_type(ClassB.get(), expected_text="type[ClassB]") - - -def func4(cls: type[_T1]) -> Callable[..., _T1]: - return cls diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder1.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder1.py deleted file mode 100644 index 475f876c..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder1.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the handling of "higher-order" type -# variables during TypeVar solving. In this example, we -# pass a generic function "identity" to another generic -# function "fmap". - -from typing import TypeVar, Callable - -T1 = TypeVar("T1") -U1 = TypeVar("U1") - - -def identity1(x: T1) -> T1: - return x - - -def fmap(f: Callable[[T1], U1], maybe: T1 | None) -> U1 | None: - return None - - -x1: int | None = 0 -y1 = fmap(identity1, x1) - -if y1 is not None: - # Make sure we can call an int method on y to confirm - # that it is an "int". - y1.conjugate() - - -# In this variant, use a bound type. -T2 = TypeVar("T2", bound=str) - - -def identity2(x: T2) -> T2: - return x - - -x2: int | None = 0 - -# This should generate an error because identity2's TypeVar -# T2 is bound to str, so there is no solution that satisfies -# all of the constraints. -y2 = fmap(identity2, x2) diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder10.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder10.py deleted file mode 100644 index 5cf168e9..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder10.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the handling of a higher-order function -# that accepts a generic function as a callback. - -from typing import Callable, TypeVar - -A = TypeVar("A") -B = TypeVar("B") - - -def func1(fn: Callable[[A, B], A], b: B) -> A: ... - - -def func2(a: A, x: A) -> A: ... - - -def func3(a: A) -> A: - return func1(func2, a) diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder11.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder11.py deleted file mode 100644 index cb6f71ba..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder11.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the case where a higher-order function receives -# a generic function as an argument, and the type of the generic -# function depends on one of the other arguments passed to the -# higher-order function. This shouldn't depend on the order the -# arguments are passed. - - -from typing import Protocol, TypeVar - - -T = TypeVar("T") - - -class Proto1(Protocol[T]): - def method(self, v: T) -> T: ... - - -class Impl1: - def method(self, v: T) -> T: ... - - -def func1(a: Proto1[T], b: T) -> T: ... - - -v1 = func1(a=Impl1(), b="abc") -reveal_type(v1, expected_text="str") - -v2 = func1(b="abc", a=Impl1()) -reveal_type(v2, expected_text="str") - -v3 = func1(a=Impl1(), b=1) -reveal_type(v3, expected_text="int") - -v4 = func1(b=1, a=Impl1()) -reveal_type(v4, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder12.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder12.py deleted file mode 100644 index 9e0e05a3..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder12.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the case involving a higher-order function and a -# class that uses a contravariant type variable. - -from collections.abc import Callable -from typing import TypeVar, Generic - -T = TypeVar("T", contravariant=True) -A = TypeVar("A") -B = TypeVar("B") -C = TypeVar("C") - - -class ClassA(Generic[T]): - pass - - -def func1(c: Callable[[A], None], v: A): - pass - - -def func2(c: ClassA[B]) -> None: - pass - - -def func3(c: ClassA[int]): - func1(func2, c) diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder13.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder13.py deleted file mode 100644 index da4b74dc..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder13.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests a particular situation that regressed. - -from typing import Any, Generic, TypeVar, TypeVarTuple, Callable - -D = TypeVar("D") -S = TypeVarTuple("S") - - -class N(Generic[*S, D]): ... - - -def func1[*S1, D1, *S2, D2, Dim1]( - c: Callable[[N[*S1, D1], N[*S2, D2]], Any], -) -> Callable[[N[Dim1, *S1, D1], N[Dim1, *S2, D2]], Any]: ... - - -def func2[X, Y, Z](x: N[X, Y, Z], y: N[X, Y, Z]): - func1(func3)(x, y) - - -def func3[Dim1, T](x: N[Dim1, T], y: N[Dim1, T]) -> N[T]: ... diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder14.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder14.py deleted file mode 100644 index 426de9af..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder14.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the case where a function with an overload -# is passed to a higher-order function and the return type uses -# a nested Callable type. - -from typing import overload, Callable - - -def func1[A, B](f: Callable[[A], B]) -> Callable[[Callable[[], A]], B]: ... - - -@overload -def func2(v: int) -> None: ... - - -@overload -def func2(v: str) -> None: ... - - -def func2(v: int | str) -> None: - pass - - -def func3() -> int: - return 1 - - -v1 = func1(func2) -reveal_type(v1, expected_text="Overload[(() -> int) -> None, (() -> str) -> None]") - -v2 = v1(func3) -reveal_type(v2, expected_text="None") - -v3 = v1(lambda: 1) -reveal_type(v3, expected_text="None") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder2.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder2.py deleted file mode 100644 index 4b1f5433..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder2.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests the case where a generic function is passed as -# a parameter to another generic function. - -from typing import Any, Callable, Generic, Iterable, TypeVar - -T = TypeVar("T") -U = TypeVar("U") - - -def identity(x: U) -> U: - return x - - -def not_identity(x: Any) -> int: - return 3 - - -class Test(Generic[T]): - def fun(self, x: Iterable[T], f: Callable[[T], T]): ... - - def caller(self, x: Iterable[T]): - self.fun(x, identity) - - # This should generate an error. - self.fun(x, not_identity) diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder3.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder3.py deleted file mode 100644 index 27647565..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder3.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests a case where a generic function is passed as -# an argument to itself, creating a recursive situation that -# caused an infinite loop. - -from random import random -from typing import Any, Callable, TypeVar - -T = TypeVar("T") -U = TypeVar("U") - - -def func1(x: T, y: U) -> T | U: - return x if random() > 0.5 else y - - -def func2(x: T, y: T) -> T: - return x if random() > 0.5 else y - - -reveal_type( - func2(func1, func2), expected_text="(x: T(1)@func2, y: T(1)@func2) -> T(1)@func2" -) - - -S = TypeVar("S", bound=Callable[..., Any]) - - -def func3(x: S) -> S: - return x - - -reveal_type(func3(func3), expected_text="(x: S(1)@func3) -> S(1)@func3") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder4.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder4.py deleted file mode 100644 index d01a7c1a..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder4.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the handling of generic callbacks passed to a higher-order -# function that is also generic. - -from typing import Callable, ParamSpec, Protocol, TypeVar - -_T = TypeVar("_T") -_T1 = TypeVar("_T1") -_T_co = TypeVar("_T_co", covariant=True) -_U = TypeVar("_U") - - -class MyIterable(Protocol[_T_co]): ... - - -class MySupportsAbs(Protocol[_T_co]): ... - - -def my_abs(x: MySupportsAbs[_T], /) -> _T: ... - - -def my_map(a: Callable[[_T], _U], b: MyIterable[_T]) -> MyIterable[_U]: ... - - -def func1(xs: MyIterable[MySupportsAbs[int]]): - ys0 = my_map(a=my_abs, b=xs) - reveal_type(ys0, expected_text="MyIterable[int]") - - ys1 = my_map(b=xs, a=my_abs) - reveal_type(ys1, expected_text="MyIterable[int]") - - -def ident(x: _U) -> _U: - return x - - -def func2(__cb: Callable[[_T1], _T], __arg0: _T1) -> _T: ... - - -x1_0 = func2(ident, "hi") -reveal_type(x1_0, expected_text="str") - -x1_1 = func2(ident, 1) -reveal_type(x1_1, expected_text="int") - - -_P = ParamSpec("_P") -_R = TypeVar("_R") - - -def func3(__obj: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... - - -x2_0 = func3(ident, "hi") -reveal_type(x2_0, expected_text="str") - -x2_1 = func3(ident, 1) -reveal_type(x2_1, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder5.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder5.py deleted file mode 100644 index 23c7d862..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder5.py +++ /dev/null @@ -1,227 +0,0 @@ -# This sample tests the case where a generic function is passed -# as an argument to another generic function multiple times. - -from dataclasses import dataclass -from typing import ( - Any, - Callable, - Generic, - Literal, - ParamSpec, - Protocol, - TypeVar, - TypeVarTuple, - overload, -) - -T = TypeVar("T") -A = TypeVar("A") -B = TypeVar("B") -C = TypeVar("C") -D = TypeVar("D") -X = TypeVar("X") -Y = TypeVar("Y") -Z = TypeVar("Z") -P = ParamSpec("P") -Ts = TypeVarTuple("Ts") - - -def identity(x: T) -> T: - return x - - -def triple_1( - f: Callable[[A], X], g: Callable[[B], Y], h: Callable[[C], Z] -) -> Callable[[A, B, C], tuple[X, Y, Z]]: - def wrapped(a: A, b: B, c: C) -> tuple[X, Y, Z]: - return f(a), g(b), h(c) - - return wrapped - - -def triple_2( - f: tuple[Callable[[A], X], Callable[[B], Y], Callable[[C], Z]], -) -> Callable[[A, B, C], tuple[X, Y, Z]]: - def wrapped(a: A, b: B, c: C) -> tuple[X, Y, Z]: - return f[0](a), f[1](b), f[2](c) - - return wrapped - - -def test_1(f: Callable[[A], X]) -> Callable[[A, B, C], tuple[X, B, C]]: - val = triple_1(f, identity, identity) - - reveal_type( - val, - expected_text="(A@test_1, T@identity, T(1)@identity) -> tuple[X@test_1, T@identity, T(1)@identity]", - ) - - return val - - -def test_2(f: Callable[[A], X]) -> Callable[[A, B, C], tuple[X, B, C]]: - val = triple_2((f, identity, identity)) - - reveal_type( - val, - expected_text="(A@test_2, T@identity, T(1)@identity) -> tuple[X@test_2, T@identity, T(1)@identity]", - ) - - return val - - -class ClassA: - def identity(self, x: T) -> T: - return x - - def test_1(self, f: Callable[[A], X]) -> Callable[[A, B, C], tuple[X, B, C]]: - val = triple_1(f, self.identity, self.identity) - - reveal_type( - val, - expected_text="(A@test_1, T@identity, T(1)@identity) -> tuple[X@test_1, T@identity, T(1)@identity]", - ) - - return val - - def test_2(self, f: Callable[[A], X]) -> Callable[[A, B, C], tuple[X, B, C]]: - val = triple_2((f, self.identity, self.identity)) - - reveal_type( - val, - expected_text="(A@test_2, T@identity, T(1)@identity) -> tuple[X@test_2, T@identity, T(1)@identity]", - ) - - return val - - -@dataclass(frozen=True) -class Pair(Generic[A, B]): - left: A - right: B - - -def func1(f: Callable[[A], B]) -> Callable[[Pair[A, X]], Pair[B, X]]: ... - - -def test_3(pair: Pair[Pair[A, B], C]) -> Pair[Pair[A, B], C]: - val1 = func1(func1(identity)) - reveal_type( - val1, - expected_text="(Pair[Pair[T@identity, X(1)@func1], X@func1]) -> Pair[Pair[T@identity, X(1)@func1], X@func1]", - ) - val2 = val1(pair) - reveal_type(val2, expected_text="Pair[Pair[A@test_3, B@test_3], C@test_3]") - return val2 - - -def test_4(pair: Pair[Pair[Pair[A, B], C], D]) -> Pair[Pair[Pair[A, B], C], D]: - val1 = func1(func1(func1(identity))) - reveal_type( - val1, - expected_text="(Pair[Pair[Pair[T@identity, X(2)@func1], X(1)@func1], X@func1]) -> Pair[Pair[Pair[T@identity, X(2)@func1], X(1)@func1], X@func1]", - ) - val2 = val1(pair) - return val2 - - -@overload -def test_5(a: Callable[P, type[T]], *, b: Literal[0] = ...) -> type[list[type[T]]]: ... - - -@overload -def test_5(a: T, *args: int, b: Literal[False, None] = ...) -> type[list[T]]: ... - - -@overload -def test_5(a: T, *args: int, b: Literal[True] = ...) -> type[list[T]]: ... - - -def test_5(a: Any, *args: int, b: Any = ...) -> Any: ... - - -val3 = test_5(test_5, **{}) -reveal_type( - val3, - expected_text="Unknown", -) - -val4 = test_5(test_5, b=True) -reveal_type( - val4, - expected_text="type[list[Overload[(a: (**P(1)@test_5) -> type[T(1)@test_5], *, b: Literal[0] = ...) -> type[list[type[T(1)@test_5]]], (a: T(1)@test_5, *args: int, b: Literal[False] | None = ...) -> type[list[T(1)@test_5]], (a: T(1)@test_5, *args: int, b: Literal[True] = ...) -> type[list[T(1)@test_5]]]]]", -) - - -def test_6(g: Callable[[B], C]) -> Callable[[Callable[[A], B]], Callable[[A], C]]: ... - - -val5 = test_6(test_6) -reveal_type( - val5, - expected_text="((A@test_6) -> ((B(1)@test_6) -> C(1)@test_6)) -> ((A@test_6) -> ((((A(1)@test_6) -> B(1)@test_6)) -> ((A(1)@test_6) -> C(1)@test_6)))", -) - - -def test_7( - g: Callable[[C], D], -) -> Callable[[Callable[[A], Callable[[B], C]]], Callable[[A], Callable[[B], D]]]: - val6 = test_6(test_6)(test_6)(g) - reveal_type( - val6, - expected_text="((A(1)@test_6) -> ((A(2)@test_6) -> C@test_7)) -> ((A(1)@test_6) -> ((A(2)@test_6) -> D@test_7))", - ) - return val6 - - -def test_8(fn: Callable[[*Ts], Callable[[A], B]]) -> Callable[[A, *Ts], B]: ... - - -def test_9(x: Callable[[bool], Callable[[int], Callable[[str], None]]]): - test_8(test_8(x)) - - -def test_10(func: Callable[[*Ts], Any], *args: *Ts) -> Any: ... - - -def func2() -> None: ... - - -test_10(test_10, func2) - - -def test_11(func: Callable[[*Ts], T], *args: *Ts) -> T: - return func(*args) - - -def func3(num: int, /) -> int: - return num - - -test_11(test_11, func3, 123) - -# This will generate an error, but it should not crash or cause an infinite loop. -test_11(test_11, test_11, func3, 123) - - -class Proto1(Protocol): - def __call__(self, a: T, b: T) -> T: ... - - -def func4(a: T, b: T) -> T: - return a - - -def test_12(p: Proto1) -> Proto1: - return p(func4, func4) - - -reveal_type( - identity((identity, identity)), - expected_text="tuple[(x: T(1)@identity) -> T(1)@identity, (x: T(2)@identity) -> T(2)@identity]", -) - -reveal_type( - identity([identity]), - expected_text="list[(x: T(1)@identity) -> T(1)@identity]", -) diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder6.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder6.py deleted file mode 100644 index 9aa03974..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder6.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the handling of nested calls to generic functions -# when bidirectional type inference is involved. - -from typing import Any, Callable, Generic, Literal, ParamSpec, Protocol, TypeVar - -_T = TypeVar("_T") -_P = ParamSpec("_P") - - -def identity1(x: _T) -> _T: - return x - - -def identity2(x: _T) -> _T: - return x - - -def test1(x: Literal[2]) -> Literal[2]: - return identity1(identity2(x)) - - -v1 = min(1, max(2, 0.5)) -reveal_type(v1, expected_text="float") - - -class Future(Generic[_T]): ... - - -def func1(future: Future[_T]) -> Future[_T]: ... - - -def func2( - __fn: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs -) -> Future[_T]: ... - - -def func3() -> int: ... - - -def func4(a: int, b: int) -> str: ... - - -reveal_type(func1(func2(func3)), expected_text="Future[int]") -reveal_type(func1(func2(func4, 1, 2)), expected_text="Future[str]") -reveal_type(func1(func2(func4, a=1, b=2)), expected_text="Future[str]") - - -class Proto(Protocol): - def __call__(self, func: _T) -> _T: ... - - -def func5(cb: Proto, names: Any): - val1 = cb(cb(names)) - reveal_type(val1, expected_text="Any") - - val2 = cb(cb(1)) - reveal_type(val2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder7.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder7.py deleted file mode 100644 index 19cf05d4..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder7.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the case where a generic class is passed as an -# argument to a function that accepts a generic callable parameter. -# The class-scoped TypeVars for the class must be preserved when -# solving the higher-order TypeVars. - -from itertools import compress -from typing import Any, Iterable - - -def func1(a: Iterable[Iterable[tuple[str, int]]], b: Any) -> None: - c = map(compress, a, b) - reveal_type(c, expected_text="map[compress[tuple[str, int]]]") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder8.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder8.py deleted file mode 100644 index 1d3d6275..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder8.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the case where a higher-order function involves a ParamSpec. - -from typing import TypeVar, Callable, Protocol, ParamSpec - -P = ParamSpec("P") -R = TypeVar("R", covariant=True) -T = TypeVar("T") - - -class Proto1(Protocol[P, R]): - @classmethod - def collect(cls, *args: P.args, **kwargs: P.kwargs) -> R: ... - - -class Class1: - @classmethod - def collect(cls, n: type[T]) -> Callable[[Callable[[T], int]], None]: ... - - -def func1(a: Proto1[P, R], *args: P.args, **kwargs: P.kwargs) -> R: ... - - -reveal_type(func1(Class1, float), expected_text="((float) -> int) -> None") -reveal_type(func1(Class1, int), expected_text="((int) -> int) -> None") diff --git a/packages/vipeye-internal/src/tests/samples/solverHigherOrder9.py b/packages/vipeye-internal/src/tests/samples/solverHigherOrder9.py deleted file mode 100644 index fb929e13..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverHigherOrder9.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the case where a higher-order function accepts -# a callable parameterized by a ParamSpec and a generic function -# is passed to it. - -from typing import Callable, TypeVar, ParamSpec - - -P = ParamSpec("P") -S = TypeVar("S") -T = TypeVar("T") - - -def deco1(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -def func1(val1: T, val2: S, val3: S) -> T: ... - - -reveal_type(deco1(func1, val1=1, val2=3, val3="s"), expected_text="int") -reveal_type(deco1(func1, 1, 3, "s"), expected_text="int") - - -def func2(val1: T, val2: S) -> T | list[S]: ... - - -reveal_type(deco1(func2, val1=1, val2="s"), expected_text="int | list[str]") -reveal_type(deco1(func2, 1, "s"), expected_text="int | list[str]") diff --git a/packages/vipeye-internal/src/tests/samples/solverLiteral1.py b/packages/vipeye-internal/src/tests/samples/solverLiteral1.py deleted file mode 100644 index 9fa3b495..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverLiteral1.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests the case that exercises some of the heuristics that -# determine whether a solved TypeVar should retain a literal type. - -from typing import Callable, Generic, Literal, TypeVar - -FileChanges = dict[str, Literal["created", "edited", "removed"]] - -changes: FileChanges = {} -changes.update({filename: "removed" for filename in ["foo.py", "bar.py"]}) - -_S = TypeVar("_S") -_T = TypeVar("_T") - - -class ClassA(Generic[_T]): - pass - - -TA1 = Callable[[ClassA[_T]], None] - - -def func1(value: _T) -> TA1[_T]: - def ret(ctx: ClassA[_T]) -> None: - pass - - return ret - - -def func2() -> TA1[bool]: - return func1(True) - - -def func3(value: _T) -> Callable[[_T], None]: ... - - -x: Callable[[tuple[bool]], None] = func3((True,)) - - -def func4(v: _T, f: Callable[[_T], None]): ... - - -def func5(v: Literal[1, 2], f: Callable[[Literal[1, 2]], None]): - func4(v, f) - - -class ClassB(Generic[_S, _T]): - left: _S - right: _T - - -def func6(s: _S, t: _T) -> ClassB[_S, _T]: ... - - -def func7(t: _T, f: Callable[[ClassB[_T, Literal[2]]], None]) -> None: - return f(func6(t, 2)) - - -def func8(a: _T, b: Callable[[list[_T]], None]) -> _T: - return a - - -def func9(v: Callable[[list[int]], None]): - func8(b=v, a=1) - - func8(a=1, b=v) diff --git a/packages/vipeye-internal/src/tests/samples/solverLiteral2.py b/packages/vipeye-internal/src/tests/samples/solverLiteral2.py deleted file mode 100644 index 7372805b..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverLiteral2.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample validates that a literal and a non-literal are not considered -# compatible types when in an invariant context. - -from typing import Literal, TypeVar - -T = TypeVar("T") - - -def func1(a: T, b: T) -> T: - return a - - -def func2() -> None: - foo_list: list[Literal["foo"]] = ["foo"] - x = func1(foo_list, [""]) - reveal_type(x, expected_text="list[Literal['foo']] | list[str]") - - # This should generate an error. - x.append("not foo") - print(foo_list) diff --git a/packages/vipeye-internal/src/tests/samples/solverScoring1.py b/packages/vipeye-internal/src/tests/samples/solverScoring1.py deleted file mode 100644 index 00185a9d..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverScoring1.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the type checker's "type var scoring" mechanism -# whereby it attempts to solve type variables with the simplest -# possible solution. - -from typing import Callable, TypeVar - -T = TypeVar("T") - - -def func1(obj_type: type[T], obj: list[T] | T) -> list[T]: - return [] - - -def func2(obj_type: type[T], obj: T | list[T]) -> list[T]: - return [] - - -def func3(input1: list[str]): - val1 = func1(str, input1) - reveal_type(val1, expected_text="list[str]") - - val2 = func2(str, input1) - reveal_type(val2, expected_text="list[str]") - - -def func4( - func: Callable[[], T] | Callable[[T], None] | list[T] | dict[str, T] | T, -) -> T: ... - - -def func5(func: Callable[[], T]) -> T: ... - - -def func6(val: str) -> None: ... - - -def func7() -> str: ... - - -reveal_type(func4([""]), expected_text="str") -reveal_type(func4({"": 1}), expected_text="int") -reveal_type(func4(func6), expected_text="str") -reveal_type(func4(func7), expected_text="str") -reveal_type(func4(str), expected_text="str") -reveal_type(func5(str), expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/solverScoring2.py b/packages/vipeye-internal/src/tests/samples/solverScoring2.py deleted file mode 100644 index e7e134ad..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverScoring2.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample tests the handling of a union that includes both -# T and a generic class parameterized by T. This case is indeterminate -# according to PEP 484, but pyright has code in place to find the -# "least complex" answer. - -from typing import Any, Generic, TypeVar, Union - -T1 = TypeVar("T1") - - -class Wrapper(Generic[T1]): ... - - -def ensure_wrapped(item: Union[T1, Wrapper[T1]]) -> Wrapper[T1]: ... - - -def some_func(x: Wrapper[T1]) -> Wrapper[T1]: - return ensure_wrapped(x) - - -def func1a(value: list[Union[T1, list[T1]]]) -> T1: ... - - -def func2a(value: list[Union[float, list[float]]]): - x = func1a(value) - reveal_type(x, expected_text="float") - - -def func3a(value: list[Union[str, list[float]]]): - # This should generate an error - func1a(value) - - -def func4a(value: list[Union[float, str, list[Union[float, str]]]]): - x = func1a(value) - reveal_type(x, expected_text="float | str") - - -def func1b(value: list[Union[int, list[T1]]]) -> T1: ... - - -def func2b(value: list[Union[int, list[float]]]): - x = func1b(value) - reveal_type(x, expected_text="float") - - -def func3b(value: list[Union[str, list[float]]]): - # This should generate an error - func1b(value) - - -def ensure_list(value: Union[T1, list[T1]]) -> list[T1]: ... - - -def func4( - v1: list, v2: list[Any], v3: list[None], v4: Any, v5: int, v6: T1, v7: list[T1] -) -> T1: - reveal_type(ensure_list(v1), expected_text="list[Unknown]") - reveal_type(ensure_list(v2), expected_text="list[Any]") - reveal_type(ensure_list(v3), expected_text="list[None]") - reveal_type(ensure_list(v4), expected_text="list[Any]") - reveal_type(ensure_list(v5), expected_text="list[int]") - reveal_type(ensure_list(v6), expected_text="list[T1@func4]") - reveal_type(ensure_list(v7), expected_text="list[T1@func4]") - - return v6 diff --git a/packages/vipeye-internal/src/tests/samples/solverScoring3.py b/packages/vipeye-internal/src/tests/samples/solverScoring3.py deleted file mode 100644 index 9f0711f1..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverScoring3.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where the constraint solver can choose one -# of several types that satisfy the constraints. - -from typing import TypeVar - -T = TypeVar("T") - - -def to_list(t: list[T] | T) -> list[T]: ... - - -x = to_list([1, 2, 3]) -reveal_type(x, expected_text="list[int]") diff --git a/packages/vipeye-internal/src/tests/samples/solverScoring4.py b/packages/vipeye-internal/src/tests/samples/solverScoring4.py deleted file mode 100644 index 87861ad9..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverScoring4.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the "complexity" calculation in the constraint -# solver to select the less-complex solution. - -from typing import Callable, Generic, Protocol, TypeVar - -T = TypeVar("T") -S = TypeVar("S") -T_contra = TypeVar("T_contra", contravariant=True) -R = TypeVar("R") - - -class ResolveFunc(Protocol[T_contra]): - def __call__(self, resolve_value: T_contra) -> None: ... - - -TA1 = Callable[[T], R | "Promise[R]"] -TA2 = Callable[[ResolveFunc[T]], None] - - -class Promise(Generic[T]): - @staticmethod - def resolve(resolve_value: S) -> "Promise[S]": ... - - def __init__(self, executor_func: TA2[T]) -> None: ... - - def then(self, onfullfilled: TA1[T, R]) -> "Promise[R]": ... - - -Promise.resolve(1).then(lambda result: reveal_type(result, expected_text="int")) - -Promise.resolve(1).then(lambda result: "abc").then( - lambda result: reveal_type(result, expected_text="str") -) - -Promise.resolve(None).then( - lambda result: Promise.resolve("abc" if 1 < 2 else 123) -).then(lambda result: reveal_type(result, expected_text="str | int")) - -Promise.resolve(None).then(lambda result: "abc" if 1 < 2 else 123).then( - lambda result: reveal_type(result, expected_text="int | str") -) diff --git a/packages/vipeye-internal/src/tests/samples/solverUnknown1.py b/packages/vipeye-internal/src/tests/samples/solverUnknown1.py deleted file mode 100644 index 45e7dd7b..00000000 --- a/packages/vipeye-internal/src/tests/samples/solverUnknown1.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests TypeVar matching when there are multiple sources -# and some of them are Unknown. The TypeVar constraint solver contains -# special heuristics to deal with this case. - - -def func1(u): - b: bool = True - - x = dict(b=b, u=u, x=[]) - reveal_type(x, expected_text="dict[str, bool | list[Any]]") diff --git a/packages/vipeye-internal/src/tests/samples/specialForm1.py b/packages/vipeye-internal/src/tests/samples/specialForm1.py deleted file mode 100644 index e54b4a55..00000000 --- a/packages/vipeye-internal/src/tests/samples/specialForm1.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where the special-form aliases for -# the stdlib collection classes are instantiated. - -# This should generate an error. -from typing import Dict, List, Set, Tuple - -# This should generate an error. -t1 = Dict() - -# This should generate an error. -t2 = List() - -# This should generate an error. -t3 = Set() - -# This should generate an error. -t4 = Tuple() diff --git a/packages/vipeye-internal/src/tests/samples/specialForm2.py b/packages/vipeye-internal/src/tests/samples/specialForm2.py deleted file mode 100644 index 156f5cbc..00000000 --- a/packages/vipeye-internal/src/tests/samples/specialForm2.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests special forms and their use as runtime objects. - -from typing import ( - Annotated, - Any, - Callable, - ClassVar, - Concatenate, - Final, - Generic, - Literal, - LiteralString, - NotRequired, - Optional, - Protocol, - Required, - Self, - TypeAlias, - TypeGuard, - TypedDict, - Union, - Unpack, -) - - -def func1(val: object) -> None: - pass - - -# All of these should be compatible with `object`, and they -# should not generate errors. -func1(Literal) -func1(Literal[0]) -func1(ClassVar) -func1(Unpack) -func1(Required) -func1(NotRequired) -func1(Protocol) -func1(Generic) -func1(Final) -func1(Callable) -func1(Callable[..., Any]) -func1(Union) -func1(Optional) -func1(TypedDict) -func1(LiteralString) -func1(Self) -func1(Concatenate) -func1(TypeAlias) -func1(TypeGuard) -func1(Annotated) -func1(Union[int, str]) -func1(int | str) - - -{Literal[1]: "literal"}[Literal[1]] diff --git a/packages/vipeye-internal/src/tests/samples/specialForm3.py b/packages/vipeye-internal/src/tests/samples/specialForm3.py deleted file mode 100644 index dd266115..00000000 --- a/packages/vipeye-internal/src/tests/samples/specialForm3.py +++ /dev/null @@ -1,48 +0,0 @@ -# This sample tests special forms that are not compatible with type[T], -# type[object] or type[Any]. - -from typing import ( - Annotated, - Any, - Callable, - ClassVar, - Concatenate, - Final, - Generic, - Literal, - LiteralString, - NotRequired, - Optional, - Protocol, - Required, - Self, - TypeAlias, - TypeGuard, - Union, - Unpack, -) -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - -# The following should all generate an error. -Literal() -Literal[0]() -ClassVar() -Unpack() -Required() -NotRequired() -Protocol() -Generic() -Final() -Callable() -Callable[..., Any]() -Union() -Optional() -LiteralString() -Self() -Concatenate() -TypeAlias() -TypeGuard() -Annotated() -ReadOnly() -Union[int, str]() -(int | str)() diff --git a/packages/vipeye-internal/src/tests/samples/specialForm4.py b/packages/vipeye-internal/src/tests/samples/specialForm4.py deleted file mode 100644 index a1e06e2f..00000000 --- a/packages/vipeye-internal/src/tests/samples/specialForm4.py +++ /dev/null @@ -1,116 +0,0 @@ -# This sample tests special forms that are not compatible with type[T], -# type[object] or type[Any]. - -from typing import ( - Annotated, - Any, - Callable, - ClassVar, - Concatenate, - Final, - Generic, - Literal, - LiteralString, - NotRequired, - Optional, - Protocol, - Required, - Self, - TypeAlias, - TypeGuard, - TypeVar, - Union, - Unpack, -) -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - -T = TypeVar("T") - - -def func1(val: type[Any]) -> None: - pass - - -def func2(val: type[object]) -> None: - pass - - -def func3(val: type[T]) -> None: - pass - - -# The following should all generate an error. -func1(Literal) -func1(Literal[0]) -func1(ClassVar) -func1(Unpack) -func1(Required) -func1(NotRequired) -func1(Protocol) -func1(Generic) -func1(Final) -func1(Callable) -func1(Callable[..., Any]) -func1(Union) -func1(Optional) -func1(Optional[Any]) -func1(LiteralString) -func1(Self) -func1(Concatenate) -func1(TypeAlias) -func1(TypeGuard) -func1(Annotated) -func1(ReadOnly) -func1(Union[int, str]) -func1(int | str) -func1(Any) - -func2(Literal) -func2(Literal[0]) -func2(ClassVar) -func2(Unpack) -func2(Required) -func2(NotRequired) -func2(Protocol) -func2(Generic) -func2(Final) -func2(Callable) -func2(Callable[..., Any]) -func2(Union) -func2(Optional) -func2(Optional[Any]) -func2(LiteralString) -func2(Self) -func2(Concatenate) -func2(TypeAlias) -func2(TypeGuard) -func2(Annotated) -func2(ReadOnly) -func2(Union[int, str]) -func2(int | str) -func2(Any) - -func3(Literal) -func3(Literal[0]) -func3(ClassVar) -func3(Unpack) -func3(Required) -func3(NotRequired) -func3(Protocol) -func3(Generic) -func3(Final) -func3(Callable) -func3(Callable[..., Any]) -func3(Union) -func3(Optional) -func3(Optional[Any]) -func3(LiteralString) -func3(Self) -func3(Concatenate) -func3(TypeAlias) -func3(TypeGuard) -func3(Annotated) -func3(ReadOnly) -func3(Union[int, str]) -func3(int | str) -func3(Any) diff --git a/packages/vipeye-internal/src/tests/samples/specialization1.py b/packages/vipeye-internal/src/tests/samples/specialization1.py deleted file mode 100644 index 482ee9db..00000000 --- a/packages/vipeye-internal/src/tests/samples/specialization1.py +++ /dev/null @@ -1,77 +0,0 @@ -# This sample tests specification of generic types. - -from typing import Generic, Iterable, List, TypeVar - - -class A: - pass - - -class B(A): - pass - - -class C(A): - pass - - -_T1 = TypeVar("_T1", A, B) - - -class Moo(Generic[_T1]): - pass - - -class Foo: - def __init__(self) -> None: ... - - def m1(self, a: Moo[A]) -> None: ... - - def m2(self, b: Moo[B]) -> None: ... - - -a = Moo[A]() -b = Moo[B]() - -y = Foo() - -y.m1(a) - -# This should generate an error: -# Argument of type 'Moo[B]' cannot be assigned to parameter of type 'Moo[A]' -y.m1(b) - -# This should generate an error: -# Argument of type 'Moo[A]' cannot be assigned to parameter of type 'Moo[B]' -y.m2(a) - -y.m2(b) - - -def m3(c: Moo[C]): - pass - - -# This should generate an error: -# Type argument 'List[C]' cannot be assigned to type variable '_T1' -def m4(c: Moo[List[C]]): - pass - - -class D(Generic[_T1]): - # This should generate an error: - # TypeVar constraint types can't be generic. - _T2 = TypeVar("_T2", Iterable[_T1], int) - - # This should generate an error: - # TypeVar bound types can't be generic. - _T3 = TypeVar("_T3", bound=Iterable[_T1]) - - -# This should generate an error: -# TypeVars can't be bound and constrained. -_T4 = TypeVar("_T4", str, int, bound=int) - -# This should generate an error: -# TypeVar must include more than one constraint. -_T5 = TypeVar("_T5", str) diff --git a/packages/vipeye-internal/src/tests/samples/specialization2.py b/packages/vipeye-internal/src/tests/samples/specialization2.py deleted file mode 100644 index 5720652b..00000000 --- a/packages/vipeye-internal/src/tests/samples/specialization2.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests the special case of specializing a Union -# type that has generic parameters. - -from typing import Any, TypeVar, Generic, Union, Callable -from dataclasses import dataclass - -E = TypeVar("E") -A = TypeVar("A") -B = TypeVar("B") - - -@dataclass -class Left(Generic[E]): - left: E - - -@dataclass -class Right(Generic[A]): - right: A - - -Either = Union[Left[E], Right[A]] - - -def fmap(f: Callable[[A], B], either: Either[E, A]) -> Either[E, B]: - if isinstance(either, Right): - return Right(f(either.right)) - else: - return either - - -def square(x: int) -> int: - return x * x - - -def accepts_only_left_str(p: Left[Any]): - pass - - -def accepts_only_right_int(p: Right[Any]): - pass - - -aa = fmap(square, Left("s")) - -if isinstance(aa, Left): - accepts_only_left_str(aa) -else: - accepts_only_right_int(aa) diff --git a/packages/vipeye-internal/src/tests/samples/staticExpression1.py b/packages/vipeye-internal/src/tests/samples/staticExpression1.py deleted file mode 100644 index 400bb154..00000000 --- a/packages/vipeye-internal/src/tests/samples/staticExpression1.py +++ /dev/null @@ -1,76 +0,0 @@ -# This sample tests static expression forms that are supported -# in the binder. - -import sys -import os - -x: int - -if sys.platform == "linux": - x = 1 -else: - x = "error!" - -if sys.version_info >= (3, 9): - x = 1 -else: - x = "error!" - -if os.name == "posix": - x = 1 -else: - x = "error!" - -if True: - x = 1 -else: - x = "error!" - -if not False: - x = 1 -else: - x = "error!" - -DEFINED_TRUE = True -DEFINED_FALSE = False - -if DEFINED_TRUE: - x = 1 -else: - x = "error!" - -if not DEFINED_FALSE: - x = 1 -else: - x = "error!" - -DEFINED_STR = "hi!" - -if DEFINED_STR == "hi!": - x = 1 -else: - x = "error!" - - -class Dummy: - DEFINED_FALSE: bool - DEFINED_TRUE: bool - DEFINED_STR: str - - -dummy = Dummy() - -if dummy.DEFINED_TRUE: - x = 1 -else: - x = "error!" - -if not dummy.DEFINED_FALSE: - x = 1 -else: - x = "error!" - -if dummy.DEFINED_STR == "hi!": - x = 1 -else: - x = "error!" diff --git a/packages/vipeye-internal/src/tests/samples/staticExpression2.py b/packages/vipeye-internal/src/tests/samples/staticExpression2.py deleted file mode 100644 index 011c1074..00000000 --- a/packages/vipeye-internal/src/tests/samples/staticExpression2.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests a special form of a sys.version_info check. - -import sys -from datetime import datetime, timezone, timedelta -from typing import overload, Optional - -# Overload was broken before 3.5.2. -# This sort of hack is seen in some type-annotated code to prevent crashes. -if sys.version_info < (3, 5, 2): - - def overload(f): - return f - - -@overload -def from_json_timestamp(ts: int) -> datetime: ... - - -@overload -def from_json_timestamp(ts: None) -> None: ... - - -def from_json_timestamp(ts: Optional[int]) -> Optional[datetime]: - return ( - None - if ts is None - else (datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(milliseconds=ts)) - ) - - -result1: datetime = from_json_timestamp(2418049) -result3: None = from_json_timestamp(None) diff --git a/packages/vipeye-internal/src/tests/samples/staticExpressionLiteral1.py b/packages/vipeye-internal/src/tests/samples/staticExpressionLiteral1.py deleted file mode 100644 index dc9677d4..00000000 --- a/packages/vipeye-internal/src/tests/samples/staticExpressionLiteral1.py +++ /dev/null @@ -1,154 +0,0 @@ -# This sample tests the static evaluation of literal truthiness - -from typing import Literal, assert_type - - -# The literal condition is statically known -def positive() -> None: - x: int - - while not 1: - x = "unreachable" - - # Falsy literals - if 0: - x = "unreachable" - - if 0.0: - x = "unreachable" - - if 0j: - x = "unreachable" - - if "": - x = "unreachable" - - if b"": - x = "unreachable" - - if (): - x = "unreachable" - - if []: - x = "unreachable" - - if {}: - x = "unreachable" - - if None: - x = "unreachable" - - # Truthy literals - if 1: - x = 1 - else: - x = "unreachable" - - if "x": - x = 1 - else: - x = "unreachable" - - if b"ad": - x = 1 - else: - x = "unreachable" - - if (1,): - x = 1 - else: - x = "unreachable" - - if [1]: - x = 1 - else: - x = "unreachable" - - if {1}: - x = 1 - else: - x = "unreachable" - - if {1: 2}: - x = 1 - else: - x = "unreachable" - - if ...: - x = 1 - else: - x = "unreachable" - - # Boolean operators applied to literal operands - if 1 and 0: - x = "unreachable" - - if 0 or "x": - x = 1 - else: - x = "unreachable" - - if not 1: - x = "unreachable" - - if not []: - x = 1 - else: - x = "unreachable" - - if not not 1: - x = 1 - else: - x = "unreachable" - - -# The literal truthiness is not statically determinable -# Both branches are analyzed and the incompatible assignment is reported as an error -def negative(items: list[int], text: str, mapping: dict[str, int]) -> None: - v: int - - # An unpacked element may expand to nothing, so `[*items]` may be empty - if [*items]: - v = "error" - else: - v = 1 - - # The value of an f-string with a field depends on a runtime value - if f"{text}": - v = "error" - else: - v = 1 - - # A comprehension may yield nothing - if [i for i in items]: - v = "error" - else: - v = 1 - - # A dict built only from "**" expansion may be empty - if {**mapping}: - v = "error" - else: - v = 1 - - -# `not` always forces a truthiness context -def strict_not_folding() -> None: - a = not None - assert_type(a, Literal[True]) - b = not 0 - assert_type(b, Literal[True]) - c = not 1 - assert_type(c, Literal[False]) - d = not [] - assert_type(d, Literal[True]) - e = not not None - assert_type(e, Literal[False]) - f = not {} - assert_type(f, Literal[True]) - g = not {1, 2} - assert_type(g, Literal[False]) - h = not [1] - assert_type(h, Literal[False]) - i = not {1: 2} - assert_type(i, Literal[False]) diff --git a/packages/vipeye-internal/src/tests/samples/strings1.py b/packages/vipeye-internal/src/tests/samples/strings1.py deleted file mode 100644 index a6f117b5..00000000 --- a/packages/vipeye-internal/src/tests/samples/strings1.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the reportImplicitStringConcatenation diagnostic check. - - -def func1(val: str): - pass - - -func1("first argument" "second argument") - -func1( - "This is the first argument, which contains " - "especially long text that could not fit into " - "one single line thus should be spread." -) - -func1( - ( - "This is the first argument, which contains " - "especially long text that could not fit into " - "one single line thus should be spread." - ) -) diff --git a/packages/vipeye-internal/src/tests/samples/strings2.py b/packages/vipeye-internal/src/tests/samples/strings2.py deleted file mode 100644 index 7604d278..00000000 --- a/packages/vipeye-internal/src/tests/samples/strings2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests string concatenation. - -v1 = "a" "b" r"c" R"""d""" "e" "f" -reveal_type(v1, expected_text="Literal['abcdef']") - -v2 = b"a" b"b" rb"c" Rb"d" -reveal_type(v2, expected_text='Literal[b"abcd"]') - -# This should generate an error. -v3 = "a" b"b" - -# This should generate an error. -v4 = b"a" f"" - -# This should generate a warning. -v5 = b"\u00FF" diff --git a/packages/vipeye-internal/src/tests/samples/structUnpack1.py b/packages/vipeye-internal/src/tests/samples/structUnpack1.py deleted file mode 100644 index 991d1241..00000000 --- a/packages/vipeye-internal/src/tests/samples/structUnpack1.py +++ /dev/null @@ -1,99 +0,0 @@ -# This sample tests the synthesized return type of `struct.unpack`, -# `struct.unpack_from` and `struct.iter_unpack` when the format string -# is a literal. - -import struct -from typing import Any, Iterator, assert_type - -buffer = b"\x00" * 64 - - -# Basic numeric format codes with a repeat count. -assert_type(struct.unpack("<2i", buffer), tuple[int, int]) - -# A mix of element kinds. -assert_type(struct.unpack("P", buffer), tuple[Any, ...]) - - -# An unrecognized format code falls back to the declared return type. -assert_type(struct.unpack("<2z", buffer), tuple[Any, ...]) - - -# A non-literal format string falls back to the declared return type. -def func1(fmt: str) -> None: - assert_type(struct.unpack(fmt, buffer), tuple[Any, ...]) diff --git a/packages/vipeye-internal/src/tests/samples/subscript1.py b/packages/vipeye-internal/src/tests/samples/subscript1.py deleted file mode 100644 index fdedad97..00000000 --- a/packages/vipeye-internal/src/tests/samples/subscript1.py +++ /dev/null @@ -1,80 +0,0 @@ -# This sample tests the reporting of builtin types that -# will generate exceptions when subscripted in older -# versions of Python. - -from queue import Queue -from collections import OrderedDict, deque -from asyncio import Future, Task - - -# These should generate errors for Python 3.8 and older. -def func1( - a1: Queue[int], - b1: OrderedDict[str, str], - d1: list[int], - e1: dict[str, int], - f1: set[int], - g1: deque[int], - h1: frozenset[int], - # These previously generated errors, but no longer do because of - # changes in the typeshed stubs. - c1: Future[int], - i1: Task[None], -) -> None: - pass - - -def func2( - a1: "Queue[int]", - b1: "OrderedDict[str, str]", - c1: "Future[int]", - d1: "list[int]", - e1: "dict[str, int]", - f1: "set[int]", - g1: "deque[int]", - h1: "frozenset[int]", - i1: "Task[None]", -) -> None: - pass - - -# These should generate errors because they are used -# in variable types, but they appear outside of a function. -class A: - a1: Queue[int] = Queue() - b1: OrderedDict[str, str] = OrderedDict() - d1: list[int] = [] - e1: dict[str, int] = {} - f1: set[int] = set() - g1: deque[int] = deque() - h1: frozenset[int] = frozenset() - - # These previously generated errors, but no longer do because of - # changes in the typeshed stubs. - c1: Future[int] = Future() - i1: Task[None] - - -class B: - a2: "Queue[int]" = Queue() - b2: "OrderedDict[str, str]" = OrderedDict() - c2: "Future[int]" = Future() - d2: "list[int]" = [] - e2: "dict[str, int]" = {} - f2: "set[int]" = set() - g2: "deque[int]" = deque() - h2: "frozenset[int]" = frozenset() - i1: "Task[None]" - - -def func3(): - # These should not generate errors. - a1: Queue[int] = Queue() - b1: OrderedDict[str, str] = OrderedDict() - c1: Future[int] = Future() - d1: list[int] = [] - e1: dict[str, int] = {} - f1: set[int] = set() - g1: deque[int] = deque() - h1: frozenset[int] = frozenset() - i1: Task[None] diff --git a/packages/vipeye-internal/src/tests/samples/subscript2.py b/packages/vipeye-internal/src/tests/samples/subscript2.py deleted file mode 100644 index 78aa8ff2..00000000 --- a/packages/vipeye-internal/src/tests/samples/subscript2.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests various forms of subscript expressions for -# syntax and semantic (type) errors. - -from typing import TypeVar - - -_T = TypeVar("_T", list, tuple) - -def func1(p1: list[int], p2: _T): - a1 = p1[0] - reveal_type(a1, expected_text="int") - - a2 = p1[:] - reveal_type(a2, expected_text="list[int]") - - a3 = p1[1:] - reveal_type(a3, expected_text="list[int]") - - a4 = p1[1:2] - reveal_type(a4, expected_text="list[int]") - - a5 = p1[0:1:3] - reveal_type(a5, expected_text="list[int]") - - a6 = p1[:3] - reveal_type(a6, expected_text="list[int]") - - a7 = p1[::] - reveal_type(a7, expected_text="list[int]") - - a8 = p1[::2] - reveal_type(a8, expected_text="list[int]") - - # This should generate a syntax error. - b1 = p1[0:1:3:4] - - # This should generate a syntax error. - b2 = p1[0:::] - - # This should generate a type error. - c1 = p1[:,] - reveal_type(c1, expected_text="Unknown") - - # This should generate a type error. - c2 = p1[:,:] - reveal_type(c2, expected_text="Unknown") - - # This should generate a type error. - c3 = p1[1,] - reveal_type(c3, expected_text="Unknown") - - d1 = p2[0] - reveal_type(d1, expected_text="Unknown") - - diff --git a/packages/vipeye-internal/src/tests/samples/subscript3.py b/packages/vipeye-internal/src/tests/samples/subscript3.py deleted file mode 100644 index d28acef7..00000000 --- a/packages/vipeye-internal/src/tests/samples/subscript3.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the handling of a subscript in a loop that includes -# a del statement. - -# viper: strict - - -def func1(lst: list[tuple[int, int]]): - for _ in range(1): - lst[-1] = lst[-1][1], lst[-1][0] - del lst[-1] diff --git a/packages/vipeye-internal/src/tests/samples/subscript4.py b/packages/vipeye-internal/src/tests/samples/subscript4.py deleted file mode 100644 index 458d30b7..00000000 --- a/packages/vipeye-internal/src/tests/samples/subscript4.py +++ /dev/null @@ -1,36 +0,0 @@ -# This sample tests the handling of unpack operators within -# a subscript. - -from typing import NamedTuple - - -class Recorder[T]: - def __getitem__(self, item: T) -> T: - return item - - -class OneInt(NamedTuple): - value: int - - -class IntStrPair(NamedTuple): - first: int - second: str - - -recorder_pair: Recorder[tuple[int, str]] = Recorder() -pair = IntStrPair(1, "value") -result1 = recorder_pair[*pair] -reveal_type(result1, expected_text="tuple[int, str]") - -recorder_order: Recorder[tuple[int, str]] = Recorder() -tail_value: str = "tail" -result2 = recorder_order[*OneInt(2), tail_value] -reveal_type(result2, expected_text="tuple[int, str]") - -recorder_multi: Recorder[tuple[int, *tuple[int | str, ...]]] = Recorder() -values1: list[int] = [] -values2: list[str] = [] -first_value: int = 0 -result3 = recorder_multi[first_value, *values1, *values2] -reveal_type(result3, expected_text="tuple[int, *tuple[int | str, ...]]") diff --git a/packages/vipeye-internal/src/tests/samples/super1.py b/packages/vipeye-internal/src/tests/samples/super1.py deleted file mode 100644 index d1513b09..00000000 --- a/packages/vipeye-internal/src/tests/samples/super1.py +++ /dev/null @@ -1,97 +0,0 @@ -# This sample tests the type analyzer's handling of the super() call. - - -from typing import Generic, NamedTuple, TypeVar - -T = TypeVar("T") - - -class ClassA: - @staticmethod - def method1(): - pass - - def method5(self) -> type: - return ClassA - - -class ClassB(ClassA): - def __init__(self): - pass - - def method2(self): - pass - - -class ClassC(ClassA): - def __init__(self): - pass - - def method3(self): - return self.__class__() - - @staticmethod - def aaa(): - # This should generate an error because the zero-arg form - # of super is illegal in a static method. - super().method1() - - -class ClassD(ClassB, ClassC): - def __init__(self): - super().method2() - super().method3() - - # This should generate an error - super().non_method1() - - def method(self): - def inner(): - super().method1() - - -super(ClassD) - -# This should generate an error -super(ClassD).non_method2() - - -super(ClassB, ClassD).method1() - -# This should generate an error because Foo2 -# is not a subclass of Foo1. -super(ClassB, ClassC).method1() - -v1 = ClassD() -super(ClassB, v1).method1() - -v2 = ClassC() -# This should generate an error because Foo2 -# is not a subclass of Foo1. -super(ClassB, v2).method1() - - -class ClassE(ClassA): - def method5(self): - class ClassDInner(super().method5()): - # This should generate an error. - x = super().method5() - - return ClassDInner - - -class ClassF(Generic[T]): - def __init__(self, val: T): - pass - - -class ClassG(ClassF[T]): - def __init__(self, val: T) -> None: - super().__init__(val) - - -class ClassH(NamedTuple("NT1", [("y", int), ("x", int)])): - def method(self, v: tuple[int, int]): - cls = type(self) - v = super().__new__(cls, *v) - return type(self)(self.y + v.y, self.x + v.x) diff --git a/packages/vipeye-internal/src/tests/samples/super10.py b/packages/vipeye-internal/src/tests/samples/super10.py deleted file mode 100644 index 967908e2..00000000 --- a/packages/vipeye-internal/src/tests/samples/super10.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests that super() calls use Self for binding. - - -class A: - def clone(self): - return self - - -class B(A): - def clone(self): - return super().clone() - - -class C(B): - def clone(self): - return super().clone() - - -reveal_type(A().clone(), expected_text="A") -reveal_type(B().clone(), expected_text="B") -reveal_type(C().clone(), expected_text="C") diff --git a/packages/vipeye-internal/src/tests/samples/super11.py b/packages/vipeye-internal/src/tests/samples/super11.py deleted file mode 100644 index ae3b4c2a..00000000 --- a/packages/vipeye-internal/src/tests/samples/super11.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the case where a protocol class is used within a mixin -# class method that calls super(). - -from typing import Protocol, overload - - -class MixinProt(Protocol): - def method1(self) -> int: - """This is not implemented""" - raise NotImplementedError - - def method2(self) -> int: - return 1 - - @overload - def method3(self, x: int) -> int: ... - - @overload - def method3(self, x: str) -> str: ... - - @overload - def method4(self, x: int) -> int: ... - - @overload - def method4(self, x: str) -> str: ... - - def method4(self, x: int | str) -> int | str: - return "" - - -class MyMixin: - def get(self: MixinProt) -> None: - m1 = super().method1() - reveal_type(m1, expected_text="int") - - m2 = super().method2() - - m3 = super().method3(1) - - m4 = super().method4(2) diff --git a/packages/vipeye-internal/src/tests/samples/super12.py b/packages/vipeye-internal/src/tests/samples/super12.py deleted file mode 100644 index a4d20d9a..00000000 --- a/packages/vipeye-internal/src/tests/samples/super12.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a class derives from a protocol -# and calls through super() to the protocol class to a method that is -# not implemented. - -from typing import Protocol - - -class BaseProto(Protocol): - def method1(self) -> None: ... - - -class ProtoImpl(BaseProto): - def method1(self) -> None: - # This should generate an error. - return super().method1() diff --git a/packages/vipeye-internal/src/tests/samples/super13.py b/packages/vipeye-internal/src/tests/samples/super13.py deleted file mode 100644 index 3b624b52..00000000 --- a/packages/vipeye-internal/src/tests/samples/super13.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the use of `super` outside of a method. - - -def func1(t: type) -> super: - return super(t, t) - - -class ClassA: - pass - - -func1(ClassA) diff --git a/packages/vipeye-internal/src/tests/samples/super2.py b/packages/vipeye-internal/src/tests/samples/super2.py deleted file mode 100644 index 50f11b8b..00000000 --- a/packages/vipeye-internal/src/tests/samples/super2.py +++ /dev/null @@ -1,100 +0,0 @@ -# This sample tests the handling of the "super" call when -# used with a two-argument form that specifies the "bind to" type. - -from typing import TypeVar - -T = TypeVar("T", bound="A") - - -class A: - def __init__(self, **kw: object) -> None: - pass - - @classmethod - def factoryA(cls: type[T]) -> T: - return cls() - - @classmethod - def get(cls: type[T], key: str) -> T: - return cls() - - -class B(A): - @classmethod - def factoryB(cls): - return super(B, cls).factoryA() - - @classmethod - def get(cls, key: str = ""): - return super(B, cls).get(key) - - -class BChild(B): - pass - - -a1 = A.factoryA() -reveal_type(a1, expected_text="A") - -b1 = B.factoryA() -reveal_type(b1, expected_text="B") - -b2 = B.factoryB() -reveal_type(b2, expected_text="B") - -g1 = B.get() -reveal_type(g1, expected_text="B") - -g2 = BChild.get() -reveal_type(g2, expected_text="BChild") - - -def test_a(cls: type[T]) -> T: - return super(A, cls).__new__(cls) - - -class C: - def __init__(self) -> None: ... - - -class CChild(C): - def __init__(self, name: str) -> None: ... - - -class D: - def __init__(self, name: str, num: int): ... - - -class DChild1(CChild, D): - def __init__(self, name: str, num: int) -> None: - super(C, self).__init__(name, num) - - -class DChild2(CChild, D): - def __init__(self, name: str) -> None: - super(DChild2, self).__init__(name) - - -class DChild3(CChild, D): - def __init__(self) -> None: - super(CChild, self).__init__() - - -d1 = DChild1("", 1) -d2 = DChild2("") -d3 = DChild3() - - -class E: - def __new__(cls) -> "E": - return super(type, cls).__new__(cls) - - -class F: ... - - -class FChild1(F): ... - - -def func1(cls: type[F | FChild1]): - super(F, cls) diff --git a/packages/vipeye-internal/src/tests/samples/super3.py b/packages/vipeye-internal/src/tests/samples/super3.py deleted file mode 100644 index be9539a7..00000000 --- a/packages/vipeye-internal/src/tests/samples/super3.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the case where super() is used for a class -# whose base classes are of unknown types. - -from some_module import ClassUnknown # type: ignore - - -class Class1(ClassUnknown): - def __init__(self, x: int): - # This should not generate an error. - super(Class1, self).__init__(x, 1, 2, 3) diff --git a/packages/vipeye-internal/src/tests/samples/super4.py b/packages/vipeye-internal/src/tests/samples/super4.py deleted file mode 100644 index f3a7eb58..00000000 --- a/packages/vipeye-internal/src/tests/samples/super4.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the handling of super() with no parameters -# and a base class with an annotated cls or self parameter that -# relies on the subclass being passed as a parameter. - -from typing import Generic, TypeVar - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2", bound="Parent2") - - -class Parent1(Generic[_T1]): - @classmethod - def construct(cls: type[_T1]) -> _T1: - return cls() - - -class Child1(Parent1["Child1"]): - @classmethod - def construct(cls) -> "Child1": - return super().construct() - - -reveal_type(Child1.construct(), expected_text="Child1") - - -class Parent2: - @classmethod - def construct(cls: type[_T2]) -> _T2: ... - - -class Child2(Parent2): - @classmethod - def construct(cls: type[_T2]) -> _T2: - return super().construct() - - -reveal_type(Child2.construct(), expected_text="Child2") diff --git a/packages/vipeye-internal/src/tests/samples/super5.py b/packages/vipeye-internal/src/tests/samples/super5.py deleted file mode 100644 index d57526cf..00000000 --- a/packages/vipeye-internal/src/tests/samples/super5.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests the case where super() is called from a class or -# instance method where the cls or self parameter is explicitly -# annotated. - -from typing import TypeVar, Type - -A_T = TypeVar("A_T", bound="A") - - -class A: - @classmethod - def construct(cls: Type[A_T]) -> A_T: - return cls() - - def construct2(self: A_T) -> A_T: - return type(self)() - - -B_T = TypeVar("B_T", bound="B") - - -class B(A): - @classmethod - def construct(cls: Type[B_T]) -> B_T: - return super().construct() - - def construct2(self: B_T) -> B_T: - return super().construct2() diff --git a/packages/vipeye-internal/src/tests/samples/super6.py b/packages/vipeye-internal/src/tests/samples/super6.py deleted file mode 100644 index aedafcd6..00000000 --- a/packages/vipeye-internal/src/tests/samples/super6.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the case where super().__new__(cls) is called -# and there is an inferred return type based on the cls type. - -from typing import NamedTuple - -FooBase = NamedTuple("FooBase", [("x", int)]) - - -class Foo(FooBase): - def __new__(cls): - obj = super().__new__(cls, x=1) - reveal_type(obj, expected_text="Self@Foo") - return obj - - -f = Foo() -reveal_type(f, expected_text="Foo") - - -class FirstLevelMeta(type): - def __new__(cls, name: str, bases, dct): - new_class = super().__new__(cls, name, bases, dct) - reveal_type(new_class, expected_text="Self@FirstLevelMeta") - return new_class - - -class SecondLevelMeta(FirstLevelMeta): - def __new__(cls, name: str, bases, dct): - new_class = super().__new__(cls, name, bases, dct) - reveal_type(new_class, expected_text="Self@SecondLevelMeta") - return new_class - - -class ThirdLevelMeta(SecondLevelMeta): - def __new__(cls, name: str, bases, dct): - new_class = super().__new__(cls, name, bases, dct) - reveal_type(new_class, expected_text="Self@ThirdLevelMeta") - return new_class diff --git a/packages/vipeye-internal/src/tests/samples/super7.py b/packages/vipeye-internal/src/tests/samples/super7.py deleted file mode 100644 index 34cae1bf..00000000 --- a/packages/vipeye-internal/src/tests/samples/super7.py +++ /dev/null @@ -1,87 +0,0 @@ -# This sample tests the use of super() with two arguments where the second -# argument is an instance. - -from typing import Generic, TypeVar - - -T = TypeVar("T") - - -class BaseClass: - def my_method(self, value: int) -> int: ... - - -class SubClass(BaseClass): - def method_plain_super(self, value: int) -> int: - reveal_type(super(), expected_text="BaseClass") - return super().my_method(value) - - def method_super(self, value: int) -> int: - reveal_type(super(__class__, self), expected_text="BaseClass") - return super(__class__, self).my_method(value) - - def method_super_extra_arg(self, value: int) -> int: - reveal_type(super(__class__, self), expected_text="BaseClass") - - # This should generate an error because the method is already bound. - return super(__class__, self).my_method(self, value) - - @classmethod - def classmethod_super(cls, value: int) -> int: - self = cls() - reveal_type(super(__class__, self), expected_text="BaseClass") - return super(__class__, self).my_method(value) - - @classmethod - def classmethod_super_extra_arg(cls, value: int) -> int: - self = cls() - reveal_type(super(__class__, self), expected_text="BaseClass") - - # This should generate an error. - return super(__class__, self).my_method(self, value) - - @staticmethod - def staticmethod_super(value: int) -> int: - self = SubClass() - reveal_type(super(__class__, self), expected_text="BaseClass") - - return super(__class__, self).my_method(value) - - @staticmethod - def staticmethod_super_extra_arg(value: int) -> int: - self = SubClass() - reveal_type(super(__class__, self), expected_text="BaseClass") - - # This should generate an error. - return super(__class__, self).my_method(self, value) - - -class A(Generic[T]): ... - - -class B(Generic[T]): ... - - -class C(A[int], B[T]): - pass - - -c = C[str]() -super_obj_c = super(C, c) -reveal_type(super_obj_c, expected_text="A[int]") - -super_obj_a = super(A, c) -reveal_type(super_obj_a, expected_text="B[str]") - -super_obj_b = super(B, c) -reveal_type(super_obj_b, expected_text="object") - - -super_cls_c = super(C, C) -reveal_type(super_cls_c, expected_text="A[int]") - -super_cls_a = super(A, C) -reveal_type(super_cls_a, expected_text="B[Unknown]") - -super_cls_b = super(B, C) -reveal_type(super_cls_b, expected_text="object") diff --git a/packages/vipeye-internal/src/tests/samples/super8.py b/packages/vipeye-internal/src/tests/samples/super8.py deleted file mode 100644 index a214f543..00000000 --- a/packages/vipeye-internal/src/tests/samples/super8.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests the case where super() is used within a metaclass -# __init__ method. - - -class Metaclass(type): - def __init__(self, name, bases, attrs): - super().__init__(name, bases, attrs) diff --git a/packages/vipeye-internal/src/tests/samples/super9.py b/packages/vipeye-internal/src/tests/samples/super9.py deleted file mode 100644 index 9b21ff73..00000000 --- a/packages/vipeye-internal/src/tests/samples/super9.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the case where a super() call is used with a class -# whose constructor uses a default argument value with a parameter -# whose type is a specialized TypeVar. - -from typing import Generic, TypeVar - -_T = TypeVar("_T") - - -class Foo(Generic[_T]): - def __init__(self, x: _T = 1) -> None: ... - - -class Bar(Foo[int]): ... - - -class Baz(Bar): - def __init__(self) -> None: - super().__init__() - - -class Baz2(Bar): - def __init__(self) -> None: - super().__init__(x=1) - - -class Bar2(Foo[int]): - def __init__(self) -> None: - super().__init__() - - -class Bar3(Foo[int]): - def __init__(self) -> None: - super().__init__(x=1) diff --git a/packages/vipeye-internal/src/tests/samples/totalOrdering1.py b/packages/vipeye-internal/src/tests/samples/totalOrdering1.py deleted file mode 100644 index 7b9f6489..00000000 --- a/packages/vipeye-internal/src/tests/samples/totalOrdering1.py +++ /dev/null @@ -1,72 +0,0 @@ -# This sample tests the support for functools.total_ordering. - -from functools import total_ordering - - -@total_ordering -class ClassA: - val1: int - - def __gt__(self, other: object) -> bool: ... - - -a = ClassA() -b = ClassA() -v1 = a < b -v2 = a <= b -v3 = a > b -v4 = a >= b -v5 = a == b -v6 = a != b - - -# This should generate an error because it doesn't declare -# any of the required ordering functions. -@total_ordering -class ClassB: - val1: int - - -@total_ordering -class ClassC: - def __eq__(self, other: object) -> bool: - return False - - def __lt__(self, other: "ClassC") -> bool: - return False - - -reveal_type(ClassC() < ClassC(), expected_text="bool") -reveal_type(ClassC() <= ClassC(), expected_text="bool") -reveal_type(ClassC() == ClassC(), expected_text="bool") -reveal_type(ClassC() > ClassC(), expected_text="bool") -reveal_type(ClassC() >= ClassC(), expected_text="bool") - -_ = ClassC() == 1 -_ = ClassC() != 1 - -# The following four lines should each produce an error. -_ = ClassC() < 1 -_ = ClassC() <= 1 -_ = ClassC() > 1 -_ = ClassC() >= 1 - - -@total_ordering -class ClassD: - def __init__(self) -> None: - self.value: int = 0 - - def __eq__(self, other: object) -> bool: - if not isinstance(other, ClassD): - return NotImplemented - - reveal_type(other, expected_text="ClassD") - - return self.value == other.value - - def __le__(self, other: object) -> bool: - if not isinstance(other, ClassD): - return NotImplemented - - return self.value <= other.value diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept1.py b/packages/vipeye-internal/src/tests/samples/tryExcept1.py deleted file mode 100644 index 3f6a27fb..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept1.py +++ /dev/null @@ -1,79 +0,0 @@ -# This sample tests the name binder's handling of -# try/except/raise statements - - -from typing import TypeVar - - -def func1(): - try: - pass - except: - raise - - raise - - -def func2(x, y) -> bool: - try: - z = x / y - except (RuntimeError, NameError) as e: - reveal_type(e, expected_text="RuntimeError | NameError") - return False - except Exception as e: - reveal_type(e, expected_text="Exception") - return False - except: - raise Exception() - else: - return True - - # This should not generate an error - # because this code is unreachable. - return "hello" - - -def func3(): - # This should generate an error because there is no - # except or finally clause. - try: - pass - -class Exception1(BaseException): ... - -base_exceptions = (RuntimeError, NameError) - -class Exception2(*base_exceptions): ... - -def func4(): - try: - pass - except Exception1: - pass - except Exception2: - pass - - -def func5(): - try: - return 1 - # This should generate an error. - except int: - pass - # This should generate an error. - except (NotImplementedError, str): - pass - # This should generate an error. - except [Exception, ValueError]: - pass - except BaseException: - pass - - -T = TypeVar("T", bound=BaseException) - -def func6(*errors: type[T]): - try: - return 1 - except errors as e: - return e diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept10.py b/packages/vipeye-internal/src/tests/samples/tryExcept10.py deleted file mode 100644 index 15b474a4..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept10.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that type errors within a finally clause are -# property detected. - - -def func1() -> None: - file = None - try: - raise ValueError() - except Exception: - return None - finally: - # This should generate an error. - file.name diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept11.py b/packages/vipeye-internal/src/tests/samples/tryExcept11.py deleted file mode 100644 index 35f9bdc9..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept11.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the case where a variable is initialized before -# a try/except and is referenced within the finally clause. This ensures -# that the "finally gate" logic is reentrant. - - -def func1(): - func2() - - -def func2(): - a = A() - - try: - with open("path"): - return - finally: - a.method1() - - -class A: - def method1(self): - pass diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept12.py b/packages/vipeye-internal/src/tests/samples/tryExcept12.py deleted file mode 100644 index 01a8bdc2..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept12.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests that multi-exception lists are parsed correctly -# based on PEP 758 in Python 3.14. - -def func1(): - try: - pass - # This should generate an error for Python 3.13 or earlier. - except ZeroDivisionError, TypeError: - raise - -def func2(): - try: - pass - # This should generate an error because an "as" clause always requires parens. - except ZeroDivisionError, TypeError as e: - raise diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept2.py b/packages/vipeye-internal/src/tests/samples/tryExcept2.py deleted file mode 100644 index 6beebf81..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests basic handling of nested finally clauses. - - -def func1(i: int) -> None: - pass - - -def func2(): - aaa = 3 - try: - try: - return - finally: - pass - finally: - func1(aaa) diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept3.py b/packages/vipeye-internal/src/tests/samples/tryExcept3.py deleted file mode 100644 index d265387f..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept3.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample verifies that the exception type validation -# handles the case where the exception type is a Type[X] object. - -exc: type[Exception] = Exception - - -try: - v = 1 / 0 -except exc: - print("exc") diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept4.py b/packages/vipeye-internal/src/tests/samples/tryExcept4.py deleted file mode 100644 index 5e2246d0..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept4.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample validates that the exception type provided -# within a raise statement is valid. - -from random import random - - -a: bool = True if random() > 0.5 else False - - -class CustomException1(BaseException): - def __init__(self, code: int): - pass - - -# This should generate an error because CustomException1 -# requires an argument to instantiate. -if a or 2 > 1: - raise CustomException1 - -if a or 2 > 1: - raise CustomException1(3) - - -class CustomException2: - pass - - -# This should generate an error because -# the exception doesn't derive from BaseException. -if a or 2 > 1: - raise CustomException2 - - -def func1(x1: type[BaseException], x2: type[BaseException]): - if 2 > 1: - raise x1 from None - - if 2 > 1: - raise x1 from x2 - - if 2 > 1: - # This should generate an error because the exception - # type doesn't derive from BaseException. - raise 1 from x2 - - if 2 > 1: - # This should generate an error because the exception - # type doesn't derive from BaseException. - raise ValueError from 1 diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept5.py b/packages/vipeye-internal/src/tests/samples/tryExcept5.py deleted file mode 100644 index d8b12fcd..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept5.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests a try statement with no except clauses -# but a finally clause. - -from typing import Any -import asyncio - - -class MyJob: - async def do_stuff(self): - try: - while True: - await asyncio.sleep(1) - my_var = 3 - finally: - # This should generate an error because - # my_var may be unbound at this point. - print(my_var) - self.cleanup() - - def cleanup(self): - pass - - -async def main(): - c = asyncio.create_task(MyJob().do_stuff()) - await asyncio.sleep(5) - c.cancel() - - -asyncio.run(main()) diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept6.py b/packages/vipeye-internal/src/tests/samples/tryExcept6.py deleted file mode 100644 index 30b91dcb..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept6.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests for the proper detection of -# an unbound variable within a finally statement -# in cases where a "bare" exception clause is used -# and not used. - - -def func1(): - try: - _ = "text".index("a") - except: - var = 1 - else: - var = 2 - finally: - print(var) - - -def func2(): - try: - _ = "text".index("a") - except NameError: - var = 1 - else: - var = 2 - finally: - # This should generate a "possibly unbound" error. - print(var) diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept7.py b/packages/vipeye-internal/src/tests/samples/tryExcept7.py deleted file mode 100644 index 7cf6b0b1..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept7.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the syntax handling for Python 3.11 exception groups -# as described in PEP 654. - - -def func1(): - - try: - pass - - # This should generate an error if using Python 3.10 or earlier. - except* ValueError as e: - reveal_type(e, expected_text="BaseExceptionGroup[ValueError]") - pass - - # This should generate an error if using Python 3.10 or earlier. - except*: - pass diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept8.py b/packages/vipeye-internal/src/tests/samples/tryExcept8.py deleted file mode 100644 index 6ad77b0a..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept8.py +++ /dev/null @@ -1,71 +0,0 @@ -# This sample tests the detection of inaccessible exception handlers. - - -from typing import Union - - -def func1() -> None: - pass - - -def func2(): - try: - func1() - except OSError: - pass - except Exception: - pass - except (): - pass - # This should generate an error. - except PermissionError: - pass - - -def func3(): - try: - func1() - except OSError: - pass - # This should generate an error. - except (PermissionError, ProcessLookupError): - pass - # This should generate an error. - except (PermissionError, ConnectionAbortedError): - pass - - -def func4(): - try: - func1() - except OSError: - pass - except (UnboundLocalError, ConnectionAbortedError): - pass - - -def func5(): - try: - func1() - except OSError: - pass - except: - pass - - -def func6(u: Union[type[Exception], tuple[type[Exception], ...]]): - try: - ... - except ValueError as e: - ... - except u as e: - ... - - -def func7(u: type[Exception]): - try: - ... - except ValueError as e: - ... - except u as e: - ... diff --git a/packages/vipeye-internal/src/tests/samples/tryExcept9.py b/packages/vipeye-internal/src/tests/samples/tryExcept9.py deleted file mode 100644 index d93a4406..00000000 --- a/packages/vipeye-internal/src/tests/samples/tryExcept9.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the case where a finally clause contains some conditional -# logic that narrows the type of an expression. This narrowed type should -# persist after the finally clause. - - -def func1(): - file = None - try: - file = open("test.txt") - except Exception: - return None - finally: - if file: - file.close() - - # This should evaluate to "TextIOWrapper", but the current - # logic is not able to evaluate different types for file - # based on whether it's an exception or non-exception case. - reveal_type(file, expected_text="TextIOWrapper[_WrappedBuffer] | None") - - -def func2(): - file = None - try: - file = open("test.txt") - except Exception: - pass - finally: - if file: - file.close() - - reveal_type(file, expected_text="TextIOWrapper[_WrappedBuffer] | None") - - -def func3(): - file = None - try: - file = open("test.txt") - finally: - pass - - reveal_type(file, expected_text="TextIOWrapper[_WrappedBuffer]") diff --git a/packages/vipeye-internal/src/tests/samples/tstring1.py b/packages/vipeye-internal/src/tests/samples/tstring1.py deleted file mode 100644 index b126b840..00000000 --- a/packages/vipeye-internal/src/tests/samples/tstring1.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests error handling for template strings. - - -# This should generate an error if using Python 3.13 or earlier. -t1 = t'Hello {"World"}' - -t2 = tr"""Test""" -t3 = rt"Test\n" - - -# This should generate two errors because tf is not a valid string type. -t4 = tf"{1}" - -# This should generate two errors because ft is not a valid string type. -t5 = ft"{1}" - -# This should generate two errors because tu is not a valid string type. -t6 = tu"{1}" - -# This should generate two errors because ut is not a valid string type. -t7 = ut"{1}" - diff --git a/packages/vipeye-internal/src/tests/samples/tstring2.py b/packages/vipeye-internal/src/tests/samples/tstring2.py deleted file mode 100644 index 0cec4f07..00000000 --- a/packages/vipeye-internal/src/tests/samples/tstring2.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests basic template string type functionality. - - -# This should result in an error because x is not defined. -t1 = t"Hello {x=}" - -age = 30 -t2 = t'''Age = {age}''' -reveal_type(t2, expected_text="Template") - -t3 = Tr"" -reveal_type(t3, expected_text="Template") - -t4 = "" tR"" T"" r"" RT"""{age}""" """x""" -reveal_type(t4, expected_text="Template") - -t4.strings -t4.interpolations -t4.values - diff --git a/packages/vipeye-internal/src/tests/samples/tuple1.py b/packages/vipeye-internal/src/tests/samples/tuple1.py deleted file mode 100644 index 1c42b82b..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple1.py +++ /dev/null @@ -1,312 +0,0 @@ -# This sample file tests various aspects of type analysis for tuples. - -import os -from typing import Any, Callable, Never - -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -Ts = TypeVarTuple("Ts") - - -def func1() -> tuple[int, int, int]: - a = 1, 2, 3 - - # This should generate an error because - # of a tuple size mismatch. - b, c = a - - b, c, d = a - - # This should generate an error because - # of a tuple size mismatch. - ( - b, - c, - d, - e, - ) = a - - return a - - -def func2() -> tuple[int, int, str]: - a = 1, 2, 3 - - # This should generate an error because the - # item types don't match. - return a - - -def func3() -> tuple[str, ...]: - a = "1", 2, 3 - - # This should generate an error because the - # heterogeneous tuple can't be assigned to - # the homogeneous tuple type. - return a - - -def func4() -> tuple[str, ...]: - a = (1,) - - # This should generate an error because the first - # item in the tuple isn't a string. - return a - - -def func6(): - a = 1, 2, "hello" - a.index("1") - - -def func7(a: tuple) -> tuple[()]: - return () - - -def func7_1(a: tuple): - a.index("1") - - -# Test the tuple specialization code. This -# should generate no error because split should -# be specialized to return a tuple of str values. -def func8() -> str: - dirname, fname = os.path.split("dir/file") - return dirname - - -def func9(param1: tuple[int, ...]): - pass - - -def func10() -> tuple[int, ...]: - return ( - 3, - 4, - 5, - ) - - -func9(func10()) -func9((2, 3, 4)) -func9((2,)) - - -# Tests for tuple assignments with unpack expressions. -def func10_1() -> int: - a = (3, 4, 5) - - c, *d = a - if c: - # This should generate an error because - # d should be an iterable type, not compatible - # with the declared return type. - return d - - # This should generate an error because - # there are not enough elements to populate - # the variable h. - e, f, g, h, *i = a - - return e - - -# Tests for tuple assignments with unpack expressions. -def func11() -> float: - b = ("hello", 3, 6.7) - - c, *d = b - if c: - # This should generate an error because - # d should be an iterable type, not compatible - # with the declared return type. - return d - - return 3 - - -# Tests for assignment of tuple list that includes star -# operator both with and without type annotations. -def func12(): - data = ["a", "b"] - data1 = (*map(str.split, data),) - data2: tuple[list[str], ...] = (*map(str.split, data),) - data3 = (*map(str.split, data),) - data4: tuple[list[str], ...] = (*map(str.split, data),) - - -# Tests for index-out-of-range error. -def func13( - a: tuple[int, str], - b: tuple[()], - c: tuple[int, ...], - d: tuple[int] | tuple[str, str] | tuple[int, ...], - e: tuple[int, Unpack[tuple[str, ...]], float], - f: tuple[int, Unpack[Ts], float], - g: tuple[Unpack[Ts]], -): - v1 = a[0] - reveal_type(v1, expected_text="int") - - v2 = a[1] - reveal_type(v2, expected_text="str") - - # This should generate an error. - v3 = a[2] - - # This should generate an error. - v4 = b[0] - - v5 = c[100] - reveal_type(v5, expected_text="int") - - v6 = a[-2] - reveal_type(v6, expected_text="int") - - v7 = a[-1] - reveal_type(v7, expected_text="str") - - # This should generate an error. - v8 = a[-3] - reveal_type(v8, expected_text="int | str") - - v9 = c[-100] - reveal_type(v9, expected_text="int") - - v10 = d[0] - - # This should generate an error. - v11 = d[1] - - # This should generate two errors. - v12 = d[2] - - v13: tuple[()] = () - # This should generate an error. - v13[0] - - v14 = e[0] - reveal_type(v14, expected_text="int") - - v15 = e[1] - reveal_type(v15, expected_text="int | str | float") - - v16 = f[0] - reveal_type(v16, expected_text="int") - - v17 = f[1] - reveal_type(v17, expected_text="int | Union[*Ts@func13] | float") - - v18 = f[-1] - reveal_type(v18, expected_text="float") - - -def func14(): - list1 = [1, 2, 3] - v1 = tuple(list1) - reveal_type(v1, expected_text="tuple[int, ...]") - - -def func15(var: tuple[()]) -> str: - raise NotImplementedError - - -def func16(var: tuple[int, int]) -> str: - raise NotImplementedError - - -def func17(var: tuple[int, ...]) -> str: - raise NotImplementedError - - -f1: Callable[[tuple[int, ...]], str] - -# This should generate an error. -f1 = func15 - -# This should generate an error. -f1 = func16 - -f1 = func17 - - -def func18(a: tuple[int, *tuple[Any, ...], str], b: tuple[Any, ...]): - a1: tuple[int, str] = a - a2: tuple[int, int, str] = a - a3: tuple[int, int, str, str] = a - a4: tuple[int, *tuple[int, ...], str] = a - - # This should generate an error. - a5: tuple[str, int, str, str] = a - - # This should generate an error. - a6: tuple[int, int, str, int] = a - - b1: tuple[()] = b - b2: tuple[int, int, str] = b - b3: tuple[int, *tuple[int, ...], str] = b - - -def func19(a: tuple[int, ...], b: tuple[int, *tuple[int, ...]]): - a1: tuple[*tuple[int, ...]] = a - - # This should generate an error. - a2: tuple[int, *tuple[int, ...]] = a - - # This should generate an error. - a3: tuple[int, *tuple[int, ...], int] = a - - # This should generate an error. - a4: tuple[*tuple[int, ...], int] = a - - b1: tuple[int, ...] = b - b2: tuple[int, *tuple[int, ...]] = b - b3: tuple[*tuple[int, ...], int] = b - - # This should generate an error. - b4: tuple[str, *tuple[int, ...]] = b - - # This should generate an error. - b5: tuple[int, int, *tuple[int, ...]] = b - - -def func20(v: tuple[Never]): - # This should generate an error. - x1: tuple[Never] = (1,) - - # This should generate an error. - x2: tuple[Never] = () - - x3: tuple[Never] = v - - -def func21(x: tuple[Any, ...], *args: *Ts) -> tuple[*Ts]: - args = x - return args - - -def func22(x: tuple[*tuple[int, ...], float, str]): - reveal_type(x[0], expected_text="int | float | str") - reveal_type(x[-1], expected_text="str") - reveal_type(x[-2], expected_text="float") - reveal_type(x[-3], expected_text="int") - - -def func31(a: tuple[int, int, *tuple[Any, ...]]) -> tuple[int, int]: - return a - - -def func32(a: tuple[int, int, *tuple[Any, ...]]) -> tuple[int, ...]: - return a - - -def func33(a: tuple[int, int, int, *tuple[Any, ...]]) -> tuple[int, ...]: - return a - - -def func34(a: tuple[int, int, *tuple[Any, ...]]) -> tuple[int]: - # This should generate an error. - return a diff --git a/packages/vipeye-internal/src/tests/samples/tuple10.py b/packages/vipeye-internal/src/tests/samples/tuple10.py deleted file mode 100644 index fe2a4234..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple10.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests that inferred types for tuples strip -# literals under the appropriate circumstances. - - -from typing import Literal - - -a1 = (1, 2) -reveal_type(a1, expected_text="tuple[Literal[1], Literal[2]]") - -a2 = list((1, 2)) -reveal_type(a2, expected_text="list[Literal[1, 2]]") - -a3: list[Literal[1]] = list((1,)) -reveal_type(a3, expected_text="list[Literal[1]]") - - -def func1(v1: tuple[Literal[1], ...], v2: tuple[Literal[1]]): - a4 = set(v1) - reveal_type(a4, expected_text="set[Literal[1]]") - - a5 = set(v2) - reveal_type(a5, expected_text="set[Literal[1]]") - - -a6 = (1, "hi") -reveal_type(a6, expected_text="tuple[Literal[1], Literal['hi']]") - -v4 = set(a6) -reveal_type(v4, expected_text="set[Literal[1, 'hi']]") diff --git a/packages/vipeye-internal/src/tests/samples/tuple11.py b/packages/vipeye-internal/src/tests/samples/tuple11.py deleted file mode 100644 index 70d50e3d..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple11.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the handling of magic methods on -# the tuple class. - -# viper: strict - - -def func1(t1: tuple[int, ...], t2: tuple[int, ...]) -> bool: - return t1 >= t2 - - -def func2(t1: tuple[int, ...], t2: tuple[str, int]) -> bool: - return t1 < t2 - - -def func3(t1: tuple[int, int], t2: tuple[int, ...]) -> bool: - return t1 > t2 - - -def func4(t1: tuple[int, ...], t2: tuple[str, ...]) -> bool: - # This should generate an error - return t1 <= t2 # viper: ignore[reportUnknownVariableType] - - -def func5(t1: tuple[str | int, ...]) -> tuple[str | int, ...]: - while len(t1) < 4: - t1 = t1 + (0,) - return t1 diff --git a/packages/vipeye-internal/src/tests/samples/tuple12.py b/packages/vipeye-internal/src/tests/samples/tuple12.py deleted file mode 100644 index e87eacd0..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple12.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests type inference for tuples that contain unpack -# operators. - - -def func1(a: int, *args: int): - v1 = (a, *args) - reveal_type(v1, expected_text="tuple[int, *tuple[int, ...]]") - - -def func2(a: int, *args: str): - v1 = (a, *args) - reveal_type(v1, expected_text="tuple[int, *tuple[str, ...]]") - - -def func3(a: int, b: str, *args: str): - v1 = (a, b, *(a, b, a), *args, a, *args, b, *(a, b, a)) - reveal_type( - v1, expected_text="tuple[int, str, int, str, int, *tuple[str | int, ...]]" - ) - - -def func4(a: int, b: str, *args: str): - v1 = (b, *args, *(b, a)) - reveal_type(v1, expected_text="tuple[str, *tuple[str, ...], str, int]") - - -def func5(): - a = 3.4 - b = [1, 2, 3] - v1 = (a, *b) - reveal_type(v1, expected_text="tuple[float, *tuple[int, ...]]") diff --git a/packages/vipeye-internal/src/tests/samples/tuple13.py b/packages/vipeye-internal/src/tests/samples/tuple13.py deleted file mode 100644 index 73adfc0d..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple13.py +++ /dev/null @@ -1,99 +0,0 @@ -# This sample tests indexing of tuples with slice expressions. - - -from typing import TypeVarTuple - - -def func1(val1: tuple[int, str, None], val2: tuple[int, ...]): - x1 = val1[:2] - reveal_type(x1, expected_text="tuple[int, str]") - - x2 = val1[-3:2] - reveal_type(x2, expected_text="tuple[int, str]") - - x3 = val1[1:] - reveal_type(x3, expected_text="tuple[str, None]") - - x4 = val1[1:-1] - reveal_type(x4, expected_text="tuple[str]") - - x5 = val1[:-2] - reveal_type(x5, expected_text="tuple[int]") - - x6 = val1[0:100] - reveal_type(x6, expected_text="tuple[int, str, None]") - - x7 = val2[:2] - reveal_type(x7, expected_text="tuple[int, ...]") - - x8 = val1[1:3] - reveal_type(x8, expected_text="tuple[str, None]") - - -def func2(val1: tuple[str, *tuple[int, ...], None]): - x1 = val1[:2] - reveal_type(x1, expected_text="tuple[str | int | None, ...]") - - x2 = val1[:1] - reveal_type(x2, expected_text="tuple[str]") - - x3 = val1[1:] - reveal_type(x3, expected_text="tuple[*tuple[int, ...], None]") - - x4 = val1[1:2] - reveal_type(x4, expected_text="tuple[str | int | None, ...]") - - x5 = val1[1:-1] - reveal_type(x5, expected_text="tuple[int, ...]") - - x6 = val1[:-1] - reveal_type(x6, expected_text="tuple[str, *tuple[int, ...]]") - - x7 = val1[:] - reveal_type(x7, expected_text="tuple[str, *tuple[int, ...], None]") - - x8 = val1[2:0] - reveal_type(x8, expected_text="tuple[str | int | None, ...]") - - -Ts = TypeVarTuple("Ts") - - -def func3(val1: tuple[str, *Ts, None]): - x1 = val1[:2] - reveal_type(x1, expected_text="tuple[str | Union[*Ts@func3] | None, ...]") - - x2 = val1[:1] - reveal_type(x2, expected_text="tuple[str]") - - x3 = val1[1:] - reveal_type(x3, expected_text="tuple[*Ts@func3, None]") - - x4 = val1[1:2] - reveal_type(x4, expected_text="tuple[str | Union[*Ts@func3] | None, ...]") - - x5 = val1[1:-1] - reveal_type(x5, expected_text="tuple[*Ts@func3]") - - x6 = val1[:-1] - reveal_type(x6, expected_text="tuple[str, *Ts@func3]") - - x7 = val1[:] - reveal_type(x7, expected_text="tuple[str, *Ts@func3, None]") - - x8 = val1[2:0] - reveal_type(x8, expected_text="tuple[str | Union[*Ts@func3] | None, ...]") - - -def func4(val1: tuple[str, int]): - x1 = val1[2:] - reveal_type(x1, expected_text="tuple[()]") - - x2 = val1[-4:] - reveal_type(x2, expected_text="tuple[str, int]") - - x3 = val1[-4:-3] - reveal_type(x3, expected_text="tuple[()]") - - x4 = val1[:-3] - reveal_type(x4, expected_text="tuple[()]") diff --git a/packages/vipeye-internal/src/tests/samples/tuple15.py b/packages/vipeye-internal/src/tests/samples/tuple15.py deleted file mode 100644 index 446cf047..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple15.py +++ /dev/null @@ -1,33 +0,0 @@ -# This sample tests the special-case handling of the __add__ operator -# when two tuples of known types are added together. - -v1 = () + () -reveal_type(v1, expected_text="tuple[()]") - - -def func1(a: tuple[int, int, int], b: tuple[str, str]): - reveal_type(a + b, expected_text="tuple[int, int, int, str, str]") - - -def func2(a: tuple[int, int, int], b: tuple[str, ...]): - reveal_type(a + b, expected_text="tuple[int, int, int, *tuple[str, ...]]") - - -def func3(a: tuple[int, ...], b: tuple[str, ...]): - reveal_type(a + b, expected_text="tuple[int | str, ...]") - - -def func4(a: tuple[str, *tuple[int, ...]], b: tuple[str, int]): - reveal_type(a + b, expected_text="tuple[str, *tuple[int, ...], str, int]") - - -def func5(input_list): - output_tuple = () - - for _, value in enumerate([]): - if value is None: - output_tuple += (None,) - continue - output_tuple += (input_list[value],) - - return output_tuple diff --git a/packages/vipeye-internal/src/tests/samples/tuple16.py b/packages/vipeye-internal/src/tests/samples/tuple16.py deleted file mode 100644 index 68928289..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple16.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests the handling of bidirectional type inference -# for unions of tuples. - -# The following two unions are the same but declared in different orders. -TupleUnion1 = tuple[int, str] | tuple[int, str, dict[str, str | int]] -TupleUnion2 = tuple[int, str, dict[str, str | int]] | tuple[int, str] - -v1: TupleUnion1 = 1, "two", {"hey": "three"} -v2: TupleUnion2 = 1, "two", {"hey": "three"} -v3: TupleUnion1 = 1, "two" -v4: TupleUnion2 = 1, "two" diff --git a/packages/vipeye-internal/src/tests/samples/tuple17.py b/packages/vipeye-internal/src/tests/samples/tuple17.py deleted file mode 100644 index 6aa75932..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple17.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests a limiter that prevents infinite recursion -# in the tuple inference logic. - - -def func1(val: int): - t = None - while True: - t = (val or t, val) - val += 1 - if val > 1000: - break - return t diff --git a/packages/vipeye-internal/src/tests/samples/tuple18.py b/packages/vipeye-internal/src/tests/samples/tuple18.py deleted file mode 100644 index c92bc475..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple18.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the case where the tuple constructor is called -# explicitly with bidirectional type inference. - -from typing import Any, Iterable - -# This should generate an error. -v1: tuple[float] = tuple([1.0, 2.0]) - -# This should generate an error. -v2: tuple[float] | tuple[float, float] = tuple([1.0, 2.0]) - -v3: tuple[float, ...] = tuple([1, 2]) - - -def f(x: Iterable[Any], y: Iterable): - a: tuple[int, int] = tuple(x) - b: tuple[int, int] = tuple(y) diff --git a/packages/vipeye-internal/src/tests/samples/tuple19.py b/packages/vipeye-internal/src/tests/samples/tuple19.py deleted file mode 100644 index 761c487a..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple19.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests a case where the constraint solver generates a very -# "deep" tuple type. Previously, this caused a hang in the evaluator. - -from typing import Callable - - -def func1[T](c: Callable[[T], T]): ... - - -# This should generate an error, not hang. -func1(lambda v: (v, v)) diff --git a/packages/vipeye-internal/src/tests/samples/tuple2.py b/packages/vipeye-internal/src/tests/samples/tuple2.py deleted file mode 100644 index e5e60ced..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple2.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample file tests various aspects of type analysis for tuples. - -no_args: tuple = () -zero_length: tuple[()] = () -all_ints1: tuple[int, ...] = () -all_ints2: tuple[int, ...] = (1,) -all_ints3: tuple[int, ...] = (1, 3, 4) - -all_ints1 = all_ints2 -all_ints2 = all_ints3 -all_ints3 = all_ints2 - -# This should generate an error. -bad_ellipsis1: tuple[...] - -# This should generate an error. -bad_ellipsis2: tuple[int, int, ...] - -# This should generate an error. -bad_ellipsis3: tuple[int, ..., int] - -# This should generate an error. -bad_ellipsis4: tuple[*tuple[int], ...] - -# This should generate an error. -bad_ellipsis5: tuple[*tuple[int, ...], ...] diff --git a/packages/vipeye-internal/src/tests/samples/tuple3.py b/packages/vipeye-internal/src/tests/samples/tuple3.py deleted file mode 100644 index ffaf610c..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple3.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the assignment of heterogeneous tuples -# to homogeneous tuple types. - -from typing import Callable - - -def func1(values: tuple[str, ...]): ... - - -# This should generate an error. -func1(("", False)) - -# This should generate an error. -func1((False, "")) - - -def func2(x: tuple[int]) -> None: ... - - -def func3(x: tuple[()]) -> None: ... - - -def func4(x: tuple[int, ...]) -> None: ... - - -c1: Callable[[tuple[int]], None] - -c1 = func2 -c1 = func3 # This should generate an error. -c1 = func4 - - -c2: Callable[[tuple[int, ...]], None] - -c2 = func2 # This should generate an error. -c2 = func3 # This should generate an error. -c2 = func4 diff --git a/packages/vipeye-internal/src/tests/samples/tuple4.py b/packages/vipeye-internal/src/tests/samples/tuple4.py deleted file mode 100644 index af783ec3..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple4.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the translation of a heterogeneous tuple -# into an Iterable. - -from typing import Iterable, TypeVar - -_T = TypeVar("_T") - - -def foo(x: Iterable[_T]) -> Iterable[_T]: - return x - - -def bar(x: Iterable[int | str]): - pass - - -my_tuple = (3, "hello") - -# The type of my_iterable should be Iterable[Union[int, str]]. -my_iterable = foo(my_tuple) -bar(my_iterable) diff --git a/packages/vipeye-internal/src/tests/samples/tuple5.py b/packages/vipeye-internal/src/tests/samples/tuple5.py deleted file mode 100644 index 8b2a4936..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple5.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the type checker's handling of -# empty tuples and assignment to empty tuples. - -from typing import Sequence, TypeVar - - -T = TypeVar("T") - -a: tuple[()] = () - -# This should generate an error because the assigned -# tuple has one element, but the destination is -# expecting zero. -b: tuple[()] = (1,) - -# This should generate an error because the assigned -# tuple has zero elements, but the destination is -# expecting two. -c: tuple[int, str] = () - - -def test_seq(x: Sequence[T]) -> Sequence[T]: - return x - - -def func1(t1: tuple[()]): - reveal_type(test_seq(t1), expected_text="Sequence[Never]") diff --git a/packages/vipeye-internal/src/tests/samples/tuple6.py b/packages/vipeye-internal/src/tests/samples/tuple6.py deleted file mode 100644 index 361157ed..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple6.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample tests tuple parameter matching for -# cases where an unpack operator is used in the target. - -from typing import Iterable - -a: int -b: int -c: str -d: str -e: Iterable[int] -f: Iterable[str | int] - -# This should generate an error because an unpack -# operator must be within a tuple. -*e = 3, 4, 5, 6 - -(*e,) = 3, 4, 5, 6 - -a, b, *e, c, d = 3, 4, "a", "b" - -a, b, *f, c, d = 3, 4, 5, "a", "b", "c" - -*f, a, b, c, d = 3, 4, "a", "b" -a, *f, b, c, d = 3, 4, "a", "b" -a, b, *f, c, d = 3, 4, "a", "b" -a, b, c, *f, d = 3, 4, "a", "b" -a, b, c, d, *f = 3, 4, "a", "b" - -a, b, c, *f = 3, 2, "" - -# This should generate an error because there are -# not enough source values. -*f, a, b, c = 3, 2 -a, *f, b, c = 3, 2 -a, b, *f, c = 3, 2 -a, b, c, *f = 3, 2 - -# This should generate an error because there are -# too many source values. -a, b = 3, 2, 3 - -# This should generate an error because e can't -# accommodate both int and str types. -a, b, *e, c, d = 3, 4, 5, "a", "b", "c" - - -def func1(p1: tuple[str, ...]): - global a, b, c, d - - c, d = p1 - - # This should generate an error because - # p1 is an incompatible type. - a, b = p1 - - c, d, *f = p1 - - -def func2(p1: tuple[str, ...], p2: tuple[str, *tuple[str, ...]]): - () = p1 - (_,) = p1 - (_, _) = p1 - - # This should generate an error. - () = p2 - (_,) = p2 diff --git a/packages/vipeye-internal/src/tests/samples/tuple7.py b/packages/vipeye-internal/src/tests/samples/tuple7.py deleted file mode 100644 index 09197779..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple7.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample tests handling of tuples and tracking -# of specific types within a tuple. - -from typing import Generic, TypeVar, Self - -_T = TypeVar("_T") - - -class ClassA(tuple[int, str, int, _T]): - def __new__(cls) -> Self: ... - - -objA = ClassA[complex]() - -(a, b, c, d) = objA - -aa1: int = a -bb1: str = b -cc1: int = c -dd1: complex = d - -reveal_type(objA[0], expected_text="int") -reveal_type(objA[1], expected_text="str") -reveal_type(objA[2], expected_text="int") -reveal_type(objA[3], expected_text="complex") - -# This should generate an error because the trailing -# comma turns the index value into a tuple. -e = objA[0,] - -for aaa in objA: - print(aaa) - - -class ClassB(tuple[_T, ...]): - def __new__(cls) -> Self: ... - - -objB = ClassB[complex]() - -(x, y, z) = objB - -reveal_type(x, expected_text="complex") -reveal_type(y, expected_text="complex") -reveal_type(z, expected_text="complex") - -xx2: complex = objB[0] -yy2: complex = objB[1] -zz2: complex = objB[2] - - -def func1(lst: list[str] | None) -> None: - for item in lst or (): - reveal_type(item, expected_text="str") - - -class X(Generic[_T]): - def __init__(self): - self._x: tuple[_T, ...] = () diff --git a/packages/vipeye-internal/src/tests/samples/tuple8.py b/packages/vipeye-internal/src/tests/samples/tuple8.py deleted file mode 100644 index 48acf2d0..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple8.py +++ /dev/null @@ -1,97 +0,0 @@ -# This sample verifies that the "tuple" type is treated -# analogously to "Tuple" type. - -from typing import Iterable, TypeVar, Self - - -_T = TypeVar("_T") - - -class ClassA(tuple[int, str, int, _T]): - def __new__(cls) -> Self: ... - - -objA = ClassA[complex]() - -(a, b, c, d) = objA - -aa1: int = a -bb1: str = b -cc1: int = c -dd1: complex = d - -aa2: int = objA[0] -bb2: str = objA[1] -cc2: int = objA[2] -dd2: complex = objA[3] - -# These should generate errors because -# these are not the correct types. -aa3: str = a -bb3: complex = b -cc3: str = c -dd3: int = d - -for aaa in objA: - print(aaa) - - -class ClassB(tuple[_T, ...]): - def __new__(cls) -> Self: ... - - -objB = ClassB[complex]() - -(x, y, z) = objB - -xx1: complex = x -yy1: complex = y -zz1: complex = z - -xx2: complex = objB[0] -yy2: complex = objB[1] -zz2: complex = objB[2] - -# These should generate errors because -# these are not the correct types. -xx3: int = x -yy3: int = y -zz3: int = z - -TupleTypeAlias1 = tuple[str, int, float] - -t1_1: TupleTypeAlias1 = ("hi", 2, 3.4) - -# This should generate an error. -t1_2: TupleTypeAlias1 = ("hi", 2) - -# This should generate an error. -t1_3: TupleTypeAlias1 = ("hi", 2.3, 4) - -TupleTypeAlias2 = tuple[str, ...] - -t2_1: TupleTypeAlias2 = ("hi", "", "") -t2_2: TupleTypeAlias2 = () - -# This should generate an error. -t2_3: TupleTypeAlias2 = ("hi", 2) - -TupleTypeAlias3 = tuple[()] - -t3_1: TupleTypeAlias2 = () - -# This should generate an error. -t3_2: TupleTypeAlias2 = (3, 4) - - -T = TypeVar("T") - - -def baz(v: Iterable[T]) -> tuple[T]: ... - - -def qux() -> None: - foo = ["foo"] - quux = baz(foo) - for s in quux: - reveal_type(s, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/tuple9.py b/packages/vipeye-internal/src/tests/samples/tuple9.py deleted file mode 100644 index 2359fe20..00000000 --- a/packages/vipeye-internal/src/tests/samples/tuple9.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests the special-case logic for the "tuple" -# constructor. Rather than generating type "tuple[T]" as -# would be expected from the constructor, we actually -# generate "tuple[T, ...]". - -# viper: strict - -str_list = ["1", "2", "3"] -left, right = tuple(str_list) - -check1: tuple[str, str] = (left, right) - -# This should generate an error -check2: tuple[str, int] = (left, right) diff --git a/packages/vipeye-internal/src/tests/samples/tupleUnpack1.py b/packages/vipeye-internal/src/tests/samples/tupleUnpack1.py deleted file mode 100644 index f51c88b2..00000000 --- a/packages/vipeye-internal/src/tests/samples/tupleUnpack1.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests the handling of Unpack[Tuple[...]] as described -# in PEP 646. - -from typing import Union -from typing_extensions import Unpack # viper: ignore[reportMissingModuleSource] - - -def func1(v1: tuple[int, Unpack[tuple[bool, bool]], str]): - reveal_type(v1, expected_text="tuple[int, bool, bool, str]") - - -def func2(v2: tuple[int, Unpack[tuple[bool, bool]], str, Unpack[tuple[bool, bool]]]): - reveal_type(v2, expected_text="tuple[int, bool, bool, str, bool, bool]") - - -def func3(v3: tuple[int, Unpack[tuple[bool, ...]], str]): - reveal_type(v3, expected_text="tuple[int, *tuple[bool, ...], str]") - - -# This should generate an error because there are multiple unbounded tuples. -def func4(v4: tuple[Unpack[tuple[bool, ...]], ...]): - pass - - -# This should generate an error because there are multiple unbounded tuples. -def func5(v5: tuple[Unpack[tuple[Unpack[tuple[bool, ...]]]], ...]): - pass - - -def func6(v6: tuple[Unpack[tuple[bool]]]): - reveal_type(v6, expected_text="tuple[bool]") - - -def func7(v7: tuple[Unpack[tuple[bool, Unpack[tuple[int, float]]]]]): - reveal_type(v7, expected_text="tuple[bool, int, float]") - - -def func8(v8: tuple[Unpack[tuple[bool, Unpack[tuple[int, ...]]]]]): - reveal_type(v8, expected_text="tuple[bool, *tuple[int, ...]]") - - -# This should generate an error because unpack isn't allowed for simple parameters. -def func9(v9: Unpack[tuple[int, int]]): - pass - - -# This should generate an error because unpack isn't allowed for **kwargs parameters. -def func10(**v10: Unpack[tuple[int, int]]): - pass - - -def func11(*v11: Unpack[tuple[int, ...]]): - pass - - -def func12(*v11: Unpack[tuple[int, int]]): - pass - - -def func13(t: type): - if t is Unpack: - ... - - -def func14( - *args: Unpack[tuple[int]], - other: str, -) -> None: ... - - -func14(1, other="hi") - -# This should generate an error because the second argument -# corresponds to a keyword-only parameter. -func14(1, "hi") diff --git a/packages/vipeye-internal/src/tests/samples/tupleUnpack2.py b/packages/vipeye-internal/src/tests/samples/tupleUnpack2.py deleted file mode 100644 index 69e4e0d6..00000000 --- a/packages/vipeye-internal/src/tests/samples/tupleUnpack2.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests the handling of *tuple[...] as described -# in PEP 646. This test is the same as tupleUnpack1.py but -# it uses the * syntax instead of the backward compatibility -# "Unpack" form. - -def func1(v1: tuple[int, *tuple[bool, bool], str]): - reveal_type(v1, expected_text="tuple[int, bool, bool, str]") - - -def func2(v2: tuple[int, *tuple[bool, bool], str, *tuple[bool, bool]]): - reveal_type(v2, expected_text="tuple[int, bool, bool, str, bool, bool]") - - -def func3(v3: tuple[int, *tuple[bool, ...], str]): - reveal_type(v3, expected_text="tuple[int, *tuple[bool, ...], str]") - - -# This should generate an error because there are multiple unbounded tuples. -def func4(v4: tuple[*tuple[bool, ...], ...]): - pass - - -# This should generate an error because there are multiple unbounded tuples. -def func5(v5: tuple[*tuple[*tuple[bool, ...]], ...]): - pass - - -def func6(v6: tuple[*tuple[bool]]): - reveal_type(v6, expected_text="tuple[bool]") - - -def func7(v7: tuple[*tuple[bool, *tuple[int, float]]]): - reveal_type(v7, expected_text="tuple[bool, int, float]") - - -def func8(v8: tuple[*tuple[bool, *tuple[int, ...]]]): - reveal_type(v8, expected_text="tuple[bool, *tuple[int, ...]]") - -# This should generate an error because unpack isn't allowed for simple parameters. -def func9(v9: *tuple[int, int]): - pass - -# This should generate an error because unpack isn't allowed for **kwargs parameters. -def func10(**v10: *tuple[int, int]): - pass - -def func11(*v11: *tuple[int, ...]): - pass - -def func12(*v11: *tuple[int, int]): - pass - -def func13(v12: "tuple[str, *tuple[int, ...], str]"): - pass - diff --git a/packages/vipeye-internal/src/tests/samples/tupleUnpack3.py b/packages/vipeye-internal/src/tests/samples/tupleUnpack3.py deleted file mode 100644 index 5eed230f..00000000 --- a/packages/vipeye-internal/src/tests/samples/tupleUnpack3.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample verifies that a unpacked tuple that contains TypeVars -# and is later specialized is honored. - -from typing import Protocol, TypeVar, Callable, Protocol, Any -from typing_extensions import Unpack # viper: ignore[reportMissingModuleSource] - - -class SupportsSum(Protocol): - def __add__(self, __x: Any) -> Any: ... - - -T = TypeVar("T", bound=SupportsSum) - - -def wrapped_summation(start: T) -> Callable[[Unpack[tuple[T, ...]]], T]: - def inner_func(*values: T): - return sum(values, start=start) - - return inner_func - - -int_sum = wrapped_summation(3) - -reveal_type(int_sum, expected_text="(*tuple[int, ...]) -> int") - -# This should generate an error. -int_sum(3.14) diff --git a/packages/vipeye-internal/src/tests/samples/tupleUnpack4.py b/packages/vipeye-internal/src/tests/samples/tupleUnpack4.py deleted file mode 100644 index c0307f77..00000000 --- a/packages/vipeye-internal/src/tests/samples/tupleUnpack4.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the handling of a TypeVar whose upper bound is -# a tuple when used for an *args parameter. - -from typing import TypeVar, Unpack - - -T = TypeVar("T", bound="tuple[int, ...]") - - -def func1(*args: Unpack[T]) -> tuple[int, ...]: - a, *v = args - - reveal_type(a, expected_text="*T@func1") - - b: int = a - - # This should generate an error. - c: str = a - - reveal_type(v, expected_text="list[*T@func1]") - - return args - - -S = TypeVar("S", bound=list[int]) - - -# This should generate an error. -def func2(*args: Unpack[S]) -> int: - return 0 diff --git a/packages/vipeye-internal/src/tests/samples/tupleUnpack5.py b/packages/vipeye-internal/src/tests/samples/tupleUnpack5.py deleted file mode 100644 index 84d2a47e..00000000 --- a/packages/vipeye-internal/src/tests/samples/tupleUnpack5.py +++ /dev/null @@ -1,29 +0,0 @@ -# This sample tests cases where an unpacked tuple is used in -# an overload. - - -from typing import Callable, Concatenate, overload - - -@overload -def func1[**P, R](func: Callable[P, R], /, *args: *tuple[()]) -> Callable[P, R]: ... -@overload -def func1[**P, R]( - func: Callable[Concatenate[int, P], R], /, *args: *tuple[int] -) -> Callable[P, R]: ... -@overload -def func1[**P, R]( - func: Callable[Concatenate[int, int, P], R], /, *args: *tuple[int, int] -) -> Callable[P, R]: ... - - -def func1[**P, R](func: Callable[..., R], /, *args: object) -> Callable[..., R]: ... - - -@overload -def func2(*args: *tuple[int]) -> int: ... -@overload -def func2(*args: *tuple[int, int, int]) -> int: ... - - -def func2(*args: *tuple[int, *tuple[int, ...]]) -> int: ... diff --git a/packages/vipeye-internal/src/tests/samples/type1.py b/packages/vipeye-internal/src/tests/samples/type1.py deleted file mode 100644 index 0afcac63..00000000 --- a/packages/vipeye-internal/src/tests/samples/type1.py +++ /dev/null @@ -1,135 +0,0 @@ -# This sample tests the handling of type[T] and Type[T]. - -from typing import Any, Callable, Generic, Type, TypeVar - - -def func1(t1: Type, t2: Type[Any], t3: type, t4: type[Any]): - reveal_type(t1.x, expected_text="Unknown") - reveal_type(t2.x, expected_text="Any") - reveal_type(t3.x, expected_text="Unknown") - reveal_type(t4.x, expected_text="Any") - - reveal_type(t1.__name__, expected_text="str") - reveal_type(t2.__name__, expected_text="str") - reveal_type(t3.__name__, expected_text="str") - reveal_type(t4.__name__, expected_text="str") - - reveal_type(t1.__sizeof__, expected_text="() -> int") - reveal_type(t2.__sizeof__, expected_text="() -> int") - reveal_type(t3.__sizeof__, expected_text="() -> int") - reveal_type(t4.__sizeof__, expected_text="() -> int") - - -def func2(t1: Type[object], t2: type[object]): - # This should generate an error. - t1.x - - # This should generate an error. - t2.x - - reveal_type(t1.__name__, expected_text="str") - reveal_type(t2.__name__, expected_text="str") - - reveal_type(t1.__sizeof__, expected_text="(self: object) -> int") - reveal_type(t2.__sizeof__, expected_text="(self: object) -> int") - - -TA1 = Type -reveal_type(TA1, expected_text="type[Type[Unknown]]") - -# This should generate an error. -TA1.x - -TA2 = Type[Any] -reveal_type(TA2, expected_text="type[Type[Any]]") - -# This should generate an error. -TA2.x - -TA3 = type -reveal_type(TA3, expected_text="type[type]") - -# This should generate an error. -TA3.x - -TA4 = type[Any] -reveal_type(TA4, expected_text="type[type[Any]]") - -# This should generate an error. -TA4.x - - -def func3(t1: TA1, t2: TA2, t3: TA3, t4: TA4): - reveal_type(t1.x, expected_text="Unknown") - reveal_type(t2.x, expected_text="Any") - reveal_type(t3.x, expected_text="Unknown") - reveal_type(t4.x, expected_text="Any") - - reveal_type(t1.__name__, expected_text="str") - reveal_type(t2.__name__, expected_text="str") - reveal_type(t3.__name__, expected_text="str") - reveal_type(t4.__name__, expected_text="str") - - reveal_type(t1.__sizeof__, expected_text="() -> int") - reveal_type(t2.__sizeof__, expected_text="() -> int") - reveal_type(t3.__sizeof__, expected_text="() -> int") - reveal_type(t4.__sizeof__, expected_text="() -> int") - - -TA5 = Type[object] -TA6 = type[object] - - -def func4(t1: TA5, t2: TA6): - # This should generate an error. - t1.x - - # This should generate an error. - t2.x - - reveal_type(t1.__name__, expected_text="str") - reveal_type(t2.__name__, expected_text="str") - - reveal_type(t1.__sizeof__, expected_text="(self: object) -> int") - reveal_type(t2.__sizeof__, expected_text="(self: object) -> int") - - -T = TypeVar("T") - -TA7 = type[T] -TA8 = Type[T] - - -def func5(t1: TA7[T]) -> T: - return t1() - - -def func6(t1: TA8[T]) -> T: - return t1() - - -reveal_type(func5(int), expected_text="int") -reveal_type(func6(int), expected_text="int") - - -def func7(v: type): - x1: Callable[..., Any] = v - x2: Callable[[int, int], int] = v - x3: object = v - x4: type = v - x5: type[int] = v - x6: type[Any] = v - - -class Class1(Generic[T]): - def method1(self, v: type) -> type[T]: - return v - - -class Class2: - x1: type - x2: type[Any] - - -reveal_type(Class2.x1, expected_text="type") -reveal_type(Class2.x2, expected_text="type[Any]") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias1.py b/packages/vipeye-internal/src/tests/samples/typeAlias1.py deleted file mode 100644 index 57df5ff5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias1.py +++ /dev/null @@ -1,67 +0,0 @@ -# This sample tests that type aliasing works. - -from typing import Any, Literal - -# Make sure it works with and without forward references. -TupleAlias = tuple["int", int] - -v1: tuple[int, int] -v2: TupleAlias - -v1 = (1, 2) -v2 = (1, 2) - - -AnyAlias = Any - -v3: AnyAlias = 3 - - -class A: - Value1 = Literal[1] - - Value2 = 1 - - -reveal_type(A.Value1, expected_text="type[Literal[1]]") -reveal_type(A.Value2, expected_text="int") - - -def func1(x: A.Value1): - reveal_type(x, expected_text="Literal[1]") - - -Alias1 = Literal[0, 1] - -v4: dict[Alias1, Any] = {} - -if v4: - pass - -v5: list[Alias1] = [] - - -Alias2 = int | str -Alias3 = int -Alias4 = type[int] - - -def func2(x: Alias2): - reveal_type(type(x), expected_text="type[int] | type[str]") - - -def func3(v2: type[Alias2], v3: type[Alias3], v4: type[Alias4]): - reveal_type(v2, expected_text="type[int] | type[str]") - reveal_type(v3, expected_text="type[int]") - reveal_type(v4, expected_text="type[type[int]]") - - -class B: - TA1 = list - - def __init__(self) -> None: - self.val = self.TA1 - - -b = B() -reveal_type(b.val, expected_text="type[list[Unknown]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias10.py b/packages/vipeye-internal/src/tests/samples/typeAlias10.py deleted file mode 100644 index ebd8d418..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias10.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the handling of generic type alias where a type -# argument is not provided. - -# viper: reportMissingTypeArgument=true - -from typing import Any, Generic, TypeAlias, TypeVar - -_T = TypeVar("_T") - - -class A(Generic[_T]): ... - - -# This should generate an error if reportMissingTypeArgument is enabled. -B: TypeAlias = A - - -v1: B = A() - -# This should generate an error because B is already specialized. -v2: B[int] = A() - -# This should generate an error if reportMissingTypeArgument is enabled. -v3: A = A() - - -C = A[str] - - -# This should generate an error because C is already specialized. -v4: C[int] - - -class D(Generic[_T]): - def __getitem__(self, key: Any) -> int: ... - - -D_Alias = D[_T] - -d: D_Alias[Any] = D() -item = d[0] - -x: int = D_Alias[Any]()[0] - -E: TypeAlias = _T - -e1: E[int] = 3 - -# This should generate an error if reportMissingTypeArgument is enabled. -e2: E = 3 diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias11.py b/packages/vipeye-internal/src/tests/samples/typeAlias11.py deleted file mode 100644 index b6340081..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias11.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests the simple aliasing of a generic class with no -# type arguments. - -from typing import Generic, TypeVar -import collections -from collections import OrderedDict - - -_T = TypeVar("_T") - - -class ClassA(Generic[_T]): - def __init__(self, x: _T): - pass - - -A = ClassA -reveal_type(A(3), expected_text="ClassA[int]") - - -TA1 = collections.OrderedDict -TA2 = OrderedDict - - -TA1[int, int] -TA2[int, int] - -TA3 = TA1 - -TA3[int, int] - - -TA4 = dict | OrderedDict - -# This should generate two errors because the two types in TA4 -# are already specialized. - -x: TA4[int, int] diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias12.py b/packages/vipeye-internal/src/tests/samples/typeAlias12.py deleted file mode 100644 index 5c2d9faf..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias12.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the handling of a generic type alias that uses -# a union that collapses to a single type when specialized. - -from typing import TypeVar - -V = TypeVar("V") -U = TypeVar("U") - -Alias = V | U - - -def func1(x: Alias[V, V]) -> V: - return x - - -def func2(x: list[Alias[V, V]]) -> list[V]: - return x - - -def func3(x: Alias[int, int]): - reveal_type(x, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias13.py b/packages/vipeye-internal/src/tests/samples/typeAlias13.py deleted file mode 100644 index 0c959840..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias13.py +++ /dev/null @@ -1,55 +0,0 @@ -# This sample tests a complex generic type alias that uses ParamSpecs -# and several layers of nested type aliases. - -from typing import Any, Callable, Concatenate, Coroutine, TypeVar, Union -from typing_extensions import ParamSpec # viper: ignore[reportMissingModuleSource] - -T = TypeVar("T") -U = TypeVar("U") -P = ParamSpec("P") - - -Method = Callable[Concatenate[T, P], U] -MaybeMethod = Union[Method[T, P, U], Callable[P, U]] -Co = Coroutine[Any, Any, T] -MaybeCo = Union[T, Co[T]] -CoFunc = Callable[P, Co[T]] -CoMethod = Method[T, P, Co[U]] -CoMaybeMethod = Union[CoMethod[T, P, U], CoFunc[P, U]] - - -class D: ... - - -class E(Exception): ... - - -class F: ... - - -DT = TypeVar("DT", bound=D) - -Error = CoMaybeMethod[DT, [F, E], Any] -reveal_type( - Error, - expected_text="type[(DT@Error, F, E) -> Coroutine[Any, Any, Any]] | type[(F, E) -> Coroutine[Any, Any, Any]]", -) - - -class A: ... - - -class B: ... - - -class C: ... - - -BT = TypeVar("BT", bound=B) - - -Something = CoMaybeMethod[A, [BT, C], Any] -reveal_type( - Something, - expected_text="type[(A, BT@Something, C) -> Coroutine[Any, Any, Any]] | type[(BT@Something, C) -> Coroutine[Any, Any, Any]]", -) diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias14.py b/packages/vipeye-internal/src/tests/samples/typeAlias14.py deleted file mode 100644 index f0d96312..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias14.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the case where a generic alias refers to a Callable -# type and the alias is used without type arguments. - -from typing import Callable, ParamSpec, TypeVar - -T = TypeVar("T") -P = ParamSpec("P") - -TA1 = Callable[[T], T] -TA2 = Callable[[T], T] | Callable[P, T] - - -def f1() -> TA1: ... - - -reveal_type(f1(), expected_text="(Unknown) -> Unknown") - - -def f2() -> TA2: ... - - -g2 = f2() -reveal_type( - g2, - expected_text="((Unknown) -> Unknown) | ((...) -> Unknown)", -) -reveal_type(g2(42), expected_text="Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias15.py b/packages/vipeye-internal/src/tests/samples/typeAlias15.py deleted file mode 100644 index 0be124dd..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias15.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the case where a generic type alias is specialized -# with an instantiable class rather than a class instance. - -from typing import TypeVar, Sequence - -T = TypeVar("T", bound=type[Exception]) -MaybeSequence = T | Sequence[T] - - -class HttpError(Exception): - pass - - -def func1(errs: MaybeSequence[type[Exception]]): - pass - - -func1(HttpError) -func1(Exception) - - -def func2(x: MaybeSequence[type[HttpError]]): - reveal_type(x, expected_text="type[HttpError] | Sequence[type[HttpError]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias16.py b/packages/vipeye-internal/src/tests/samples/typeAlias16.py deleted file mode 100644 index 783e918d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias16.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests that a generic type alias retains a literal type argument -# when it is specialized. - -from typing import Literal, TypeAlias, TypeVar - -Mode = Literal["read", "write"] -T = TypeVar("T") -Entry: "TypeAlias" = dict[T, int] -Entry2: TypeAlias = dict[Mode, int] - - -def f() -> Entry[Mode]: - return {"read": 0} - - -def g() -> Entry2: - return {"read": 0} - - -def main() -> None: - d1 = f() - reveal_type(d1, expected_text="dict[Literal['read', 'write'], int]") - d2 = g() - reveal_type(d2, expected_text="dict[Literal['read', 'write'], int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias17.py b/packages/vipeye-internal/src/tests/samples/typeAlias17.py deleted file mode 100644 index 428ecdde..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias17.py +++ /dev/null @@ -1,60 +0,0 @@ -# This sample tests reporting of type argument count mismatch when -# used with generic type aliases. - -from typing import Callable, ParamSpec, TypeVar, TypeVarTuple, Unpack - - -T1 = TypeVar("T1") -T2 = TypeVar("T2") -P = ParamSpec("P") -Tv1 = TypeVarTuple("Tv1") - -TA1 = dict[T1, T2] - -# This should generate an error if reportMissingTypeArgument is enabled. -a1: TA1 -# This should generate an error because of too few type arguments. -a2: TA1[str] -a3: TA1[str, str] -# This should generate an error because of too many type arguments. -a4: TA1[str, str, str] - -TA2 = Callable[P, T1] - -# This should generate an error if reportMissingTypeArgument is enabled. -b1: TA2 -# This should generate an error because of too few type arguments. -b2: TA2[...] -b3: TA2[..., int] -# This should generate an error because of too many type arguments. -b4: TA2[..., int, int] - -TA3 = Callable[P, int] - -# This should generate an error if reportMissingTypeArgument is enabled. -c1: TA3 -c2: TA3[int] -c3: TA3[int, int] -c4: TA3[int, int, int] - - -TA4 = list[T1] | tuple[Unpack[Tv1]] - -# This should generate an error if reportMissingTypeArgument is enabled. -d1: TA4 -d2: TA4[int] -d3: TA4[int, int] -d4: TA4[int, int, int] - - -_T = TypeVar("_T") -TA5 = dict[_T, _T] - -# This should generate an error if reportMissingTypeArgument is enabled -TA6 = TA5 | None - -# This should generate an error if reportMissingTypeArgument is enabled -TA7 = list | str - -# This should generate an error if reportMissingTypeArgument is enabled -TA8 = str | dict diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias18.py b/packages/vipeye-internal/src/tests/samples/typeAlias18.py deleted file mode 100644 index b44b3549..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias18.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the case where a type alias is used in a class -# declaration. We want to ensure that the variance of type variables -# is compatible with the usage within the type alias. - -from typing import Generic, TypeVar, TypeAlias - -T1 = TypeVar("T1") -T2 = TypeVar("T2", covariant=True) -T3 = TypeVar("T3", contravariant=True) - - -class A(Generic[T1]): - pass - - -A_Alias_1: TypeAlias = A[T2] - -A_Alias_2: TypeAlias = A_Alias_1[T2 | int] - - -# This should generate an error because the variance is incompatible. -class A_1(A_Alias_1[T2]): ... - - -# This should generate an error because the variance is incompatible. -class A_2(A_Alias_2[T2]): ... - - -# This should generate an error because the variance is incompatible. -class A_3(A[T2]): ... - - -class B(Generic[T1, T2]): - pass - - -B_Alias_1 = B[T2, T3] - - -# This should generate an error because the variance is incompatible. -class C(B_Alias_1[T3, T2]): ... diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias19.py b/packages/vipeye-internal/src/tests/samples/typeAlias19.py deleted file mode 100644 index 2547b43f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias19.py +++ /dev/null @@ -1,4 +0,0 @@ -# This sample is used to test that TypeAlias can be aliased -# and re-exported. It is used with typeAlias20.py. - -from typing import TypeAlias as TA diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias2.py b/packages/vipeye-internal/src/tests/samples/typeAlias2.py deleted file mode 100644 index 23750034..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias2.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests that forward references to type aliases work. - -from typing import Any, Union - - -class Base: - @staticmethod - def create(data: dict[str, Any]) -> "Mix": - return A() - - -class A(Base): - pass - - -class B(Base): - pass - - -Mix = Union[A, B] - - -class S: - @staticmethod - def create(data: dict[str, Any]) -> "Mix": - return A() diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias20.py b/packages/vipeye-internal/src/tests/samples/typeAlias20.py deleted file mode 100644 index 5b17d778..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias20.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample is used to test that TypeAlias can be aliased -# and re-exported. It is used with typeAlias19.py. - -from .typeAlias19 import TA as TA2 - -TA3 = TA2 - -x: TA2 = dict[str, str] - -y: x = {"": ""} diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias21.py b/packages/vipeye-internal/src/tests/samples/typeAlias21.py deleted file mode 100644 index ce3799ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias21.py +++ /dev/null @@ -1,14 +0,0 @@ -# This sample tests that a generic type alias can use -# a compatible bound TypeVar. - -from typing import Generic, TypeVar - -D = TypeVar("D", bool, int, float, object) -E = TypeVar("E", bool, int, float, object) - - -class Gen(Generic[D]): - pass - - -GenAlias = Gen[E] diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias22.py b/packages/vipeye-internal/src/tests/samples/typeAlias22.py deleted file mode 100644 index 8b203355..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias22.py +++ /dev/null @@ -1,135 +0,0 @@ -# This sample tests handling of type aliases. - -from datetime import datetime -from typing import Any, Callable, Generic, TypeVar, Union - - -from typing import TypeVar, Union, Optional - -S = TypeVar("S") - -Response1 = Optional[Union[S, int]] - - -def f1_1() -> Response1[str]: - return None - - -def f1_2() -> Response1[str]: - return "s" - - -def f1_3() -> Response1[float]: - # This should generate an error. - return "s" - - -Response2 = Union[S, int] - - -def f2_1() -> Response2[Any]: - return "s" - - -def f2_2() -> Response2[str]: - return "s" - - -def f2_3() -> Response2[float]: - return 3.4 - - -def f2_4() -> Response2[datetime]: - # This should generate an error - return 3.4 - - -Response3 = Callable[[S], S] - - -def response2(query: str) -> Response3[int]: - return lambda x: x + 2 - - -def response3(query: str) -> Response3[datetime]: - # This should generate an error because datetime doesn't support + - return lambda x: x + 2 - - -Response4 = Union[S, int, str] - - -class Foo1: - pass - - -class Foo2: - pass - - -class Foo3: - pass - - -T = TypeVar("T") - -Response5 = Union[T, Foo1, Foo2] - -# Test nested type aliases -Response6 = Response5[Response4[Foo3]] - - -def f6_1() -> Response6: - return Foo1() - - -def f6_2() -> Response6: - return Foo2() - - -def f6_3() -> Response6: - return Foo3() - - -def f6_4() -> Response6: - return 3 - - -def f6_5() -> Response6: - # This should generate an error - return None - - -class InnerA: - pass - - -class InnerB: - pass - - -T = TypeVar("T", bound=InnerA) - - -class A(Generic[T]): - pass - - -class B: - pass - - -U = Union[A[T], B] - -a: U[InnerA] - -# This should generate an error because InnerB is not -# compatible with the type bound to TypeVar T. -b: U[InnerB] - - -V = Union[A[T], T] - -# This should generate an error because too many type -# arguments are provided. -c: V[InnerA, int] diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias3.py b/packages/vipeye-internal/src/tests/samples/typeAlias3.py deleted file mode 100644 index 389b3a1b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias3.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests that type aliases can consist of -# partially-specialized classes that can be further -# specialized. - -# viper: reportMissingModuleSource=false - -from typing import Callable, Generic, Optional -from typing_extensions import ParamSpec, TypeVar - -T = TypeVar("T") -P = ParamSpec("P") -TStr = TypeVar("TStr", default=str) - -ValidationResult = tuple[bool, Optional[T]] - - -def foo() -> ValidationResult[str]: - return False, "valid" - - -class ClassA(Generic[T]): - def __new__(cls, value: T) -> "ClassA[T]": ... - - -TypeAliasA1 = ClassA[T] - -a1 = ClassA(3.0) -reveal_type(a1, expected_text="ClassA[float]") - -a2 = TypeAliasA1(3) -reveal_type(a2, expected_text="ClassA[Unknown]") - -a3 = TypeAliasA1[int](3) -reveal_type(a3, expected_text="ClassA[int]") - - -TypeAliasA2 = ClassA[TStr] - -# This should generate an error. -b1 = TypeAliasA2(1) - -b2 = TypeAliasA2("") -reveal_type(b2, expected_text="ClassA[str]") - -b3 = TypeAliasA2[float](1.0) -reveal_type(b3, expected_text="ClassA[float]") - -Func = Callable[P, T] -AnyFunc = Func[P, int] -x: AnyFunc[...] diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias4.py b/packages/vipeye-internal/src/tests/samples/typeAlias4.py deleted file mode 100644 index 9b201310..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias4.py +++ /dev/null @@ -1,78 +0,0 @@ -# This sample tests the handling of the Python 3.9 -# TypeAlias feature as documented in PEP 613. - -import sys -from typing import Type, TypeAlias as TA, Union, cast - -type1: TA = Union[int, str] - -type2: TA = "ClassA" - - -class ClassA: - pass - - -not_a_type = "ClassA" - - -def requires_string(a: str): - pass - - -requires_string(not_a_type) - -# This should generate an error because type2 should -# not be interpreted as a string. -requires_string(type2) - -# This should generate an error because the symbol -# is later declared as a TypeAlias. -my_type3 = int - -# This should generate an error because it is obscured -# by another type alias declaration. -my_type3: "TA" = Union[int, str] - -# This should generate an error because the symbol -# was previously declared as a TypeAlias. -my_type3: TA = int - -# This should generate an error because the expression -# on the RHS evaluates to an object, not a class. -my_type4: TA = 3 - -# This should generate an error because the expression -# on the RHS evaluates to an object, not a class. -my_type5: TA = True - -# This should generate an error because the expression -# on the RHS evaluates to an object, not a class. -my_type7: TA = list() - -# Verify that variables with declarations (other than explicit TypeAlias) -# are not treated as a type alias. -SimpleAlias = int -ExplicitAlias: TA = int -SimpleNonAlias: Type[int] = int - -if sys.version_info > (3, 9): - reveal_type(SimpleAlias, expected_text="type[int]") - reveal_type(ExplicitAlias, expected_text="type[int]") - reveal_type(SimpleNonAlias, expected_text="type[int]") - - -class ClassB: - my_type1: TA = int - - -def func1(): - # This should generate an error because type aliases are allowed - # only in classes or modules. - my_type1: TA = int - - -_Obj = cast(type[object], object) -# This should generate an error because _Obj is a variable, -# which isn't allowed in a TypeAlias statement. -Obj: TA = _Obj diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias5.py b/packages/vipeye-internal/src/tests/samples/typeAlias5.py deleted file mode 100644 index cc6e670f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias5.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests type aliases that are unions that include -# TypeVars. - -from datetime import datetime -from typing import IO, Generic, Literal, TypeVar, Union - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - -MyUnion1 = Union[int, _T1, str, _T2, list[_T1]] - -MyUnion2 = Union[float, datetime] - -# This should generate an error because two type arguments are -# expected, but only one was provided. -MyUnion3 = MyUnion1[MyUnion2] - -MyUnion4 = MyUnion1[MyUnion2, IO] - -# This should generate an error because only two type -# arguments are expected. -MyUnion5 = MyUnion1[MyUnion2, IO, str] - -MyUnion6 = MyUnion1[Literal[0], Literal["a"]] -reveal_type( - MyUnion6, - expected_text="type[int] | type[str] | type[list[Literal[0]]] | type[Literal[0, 'a']]", -) - - -class Foo: - def __int__(self) -> int: - return 0 - - -FooT = TypeVar("FooT", bound=Foo) -FooIsh = Union[int, FooT] - - -class Bar(Foo): - def __int__(self) -> int: - return super().__int__() + 1 - - -v1: FooIsh[Bar] = 42 -v2: FooIsh[Bar] = Bar() - -# This should generate an error. -v3: FooIsh[type[Bar]] = 42 - - -MyTypeAlias = dict[_T1, _T2] - - -class MyClass1(Generic[_T1, _T2]): - # This should generate an error because S and T are bound - # type variables. - MyTypeAlias = dict[_T1, _T2] diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias6.py b/packages/vipeye-internal/src/tests/samples/typeAlias6.py deleted file mode 100644 index a5b6cd8e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias6.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests that certain type aliases cannot be used within -# call expressions. - -from typing import Callable, TypeVar - - -T_Union = int | float - -# This should generate an error -T_Union(3) - -T_Callable = Callable[[int], None] - -# This should generate an error -T_Callable(1) - - -T_Type1 = type[int] - -# This should generate an error -T_Type1(object) - -T_Type2 = type -T_Type2(object) - -T_Optional = str | None - -# This should generate an error -T_Optional(3) - - -T_TypeVar = TypeVar("T_TypeVar") - -# This should generate an error -T_TypeVar() - - -I = int - -I(3) - - -T_Tuple2 = tuple[int, ...] - -T_Tuple2([3, 4, 5]) diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias7.py b/packages/vipeye-internal/src/tests/samples/typeAlias7.py deleted file mode 100644 index d3441961..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias7.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests the handling of generic type aliases that are -# defined in terms of other generic type aliases in a nested manner. - -from typing import Awaitable, Callable, Generic, Literal, TypeAlias, TypeVar - -TSource = TypeVar("TSource") -TError = TypeVar("TError") -TResult = TypeVar("TResult") -TNext = TypeVar("TNext") - - -class Context(Generic[TResult]): - Response: TResult - - -class Result(Generic[TResult, TError]): - def map( - self, mapper: Callable[[Context[TResult]], TResult] - ) -> "Result[TResult, TError]": - return Result() - - -HttpFuncResult = Result[Context[TResult], TError] -HttpFuncResultAsync = Awaitable[Result[Context[TResult], TError]] - -HttpFunc = Callable[ - [Context[TNext]], - HttpFuncResultAsync[TResult, TError], -] - -HttpHandler = Callable[ - [ - HttpFunc[TNext, TResult, TError], - Context[TSource], - ], - HttpFuncResultAsync[TResult, TError], -] - - -async def run_async( - ctx: Context[TSource], - handler: HttpHandler[str, TResult, TError, TSource], -) -> Result[TResult, TError]: - result = Result[TResult, TError]() - - def mapper(x: Context[TResult]) -> TResult: - return x.Response - - return result.map(mapper) - - -T1 = TypeVar("T1", bound=Literal["a", "b", "c"]) -T2 = TypeVar("T2", bound=Literal["b", "c"]) - -TA2: TypeAlias = list[T1] -TA3: TypeAlias = TA2[T2] diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias8.py b/packages/vipeye-internal/src/tests/samples/typeAlias8.py deleted file mode 100644 index 6891dc26..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias8.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample verifies that a generic type alias with a Callable -# works correctly. - -# viper: reportInvalidTypeVarUse=false - -from typing import Callable, TypeVar - -T = TypeVar("T") -F = Callable[[T], T] - - -def func1() -> F[T]: - def g(x: T) -> T: ... - - return g - - -func2 = func1() -v1 = func2("foo") -reveal_type(v1, expected_text="str") - -v2 = func2(1) -reveal_type(v2, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeAlias9.py b/packages/vipeye-internal/src/tests/samples/typeAlias9.py deleted file mode 100644 index b615bc04..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAlias9.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests that generic type aliases are properly flagged as -# partially-unknown types if their type arguments are omitted. - -# viper: reportUnknownParameterType=true, reportMissingTypeArgument=false - -from typing import TypeVar - -T = TypeVar("T") -TA1 = list[T] - - -# This should generate an error because Foo is missing a type argument, -# so the type of `f` is partially unknown. -def func1(f: TA1) -> None: - pass - - -TA2 = TA1 - - -# This should generate an error because Bar doesn't specialize -# Foo appropriately. -def func2(f: TA2) -> None: - pass - - -K = TypeVar("K") -V = TypeVar("V") - -TA3 = dict[K, V] - - -# This should generate two errors because Baz is only partially specialized. -def func3(f: TA3[int]) -> None: - pass diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasStatement1.py b/packages/vipeye-internal/src/tests/samples/typeAliasStatement1.py deleted file mode 100644 index f81a22a6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasStatement1.py +++ /dev/null @@ -1,91 +0,0 @@ -# This sample tests error cases associated with the "type" statement -# introduced in PEP 695. - -from typing import Any, Callable - - -T1 = 0 - -type TA1[T1] = int - -reveal_type(TA1, expected_text="TypeAliasType") - - -class ClassA[T2]: - type TA2 = int - type TA3 = str - - type TA4 = int - - T2 = 4 - - -T2 = 4 - -type TA5[S1, *S2, **S3] = Callable[S3, S1] | tuple[*S2] - -X1 = TA5[int, tuple[int, str], ...] - -type TA6 = TA5[int, tuple[int, str], ...] - -val1: TA5 -val2: TA6 - -if 1 < 2: - # This should generate an error because it is obscured. - type TA7 = int -else: - type TA7 = int - - -def func1() -> type[int]: ... - - -# This should generate an error because a call expression is not -# allowed in a type alias definition. -type TA8 = func1() - -# This should generate two errors because a tuple and index expression is not -# allowed in a type alias definition. -type TA9 = (int, str, str)[0] - - -type TA10 = int - -# This should generate an error. -TA10.bit_count(1) - -# This should generate an error. -TA10(0) - -list[TA10]() - - -# This should generate an error. -class DerivedInt(TA10): - pass - - -def func2(x: object): - # This should generate an error. - if isinstance(x, TA10): - reveal_type(x) - - -type TA11 = Callable[..., Any] - - -def func3(cb: TA11): - cb() - - -def func4(): - # This should generate an error. - type TA12 = int - - -type TA12[T] = "list[T]" -ta12: TA12[int] = [1, 2, 3] - -# This should generate an error. -type TA13[T] = ... diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasStatement2.py b/packages/vipeye-internal/src/tests/samples/typeAliasStatement2.py deleted file mode 100644 index eb0e2c01..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasStatement2.py +++ /dev/null @@ -1,5 +0,0 @@ -# This sample tests that "type" statements (introduced in PEP 695) -# are illegal prior to Python 3.12. - -# This should generate an error if less than Python 3.12. -type TA1[T1] = int diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasStatement3.py b/packages/vipeye-internal/src/tests/samples/typeAliasStatement3.py deleted file mode 100644 index 70ba52f3..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasStatement3.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the error case where traditional type variables -# are used in a new-style type alias statement introduced in PEP 695. - -from typing import TypeVar - - -V = TypeVar("V") - -# This should generate an error because it combines old and -# new type variables. -type TA1[K] = dict[K, V] - - -T1 = TypeVar("T1") - -# This should generate an error because it uses old type -# variables in a type alias statement. -type TA2 = list[T1] diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasStatement4.py b/packages/vipeye-internal/src/tests/samples/typeAliasStatement4.py deleted file mode 100644 index 988970ab..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasStatement4.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the use of recursive (self-referencing) type aliases, -# which are allowed in PEP 695. - -from typing import Callable - - -type TA1[T] = T | list[TA1[T]] - -x1: TA1[int] = 1 -x2: TA1[int] = [1] - -type TA2[S: int, T: str, **P] = Callable[P, T] | list[S] | list[TA2[S, T, P]] - - -# This should generate an error because str isn't compatible with S bound. -x3: TA2[str, str, ...] - -x4: TA2[int, str, ...] - -# This should generate an error because int isn't compatible with T bound. -x5: TA2[int, int, ...] - -x6: TA2[int, str, [int, str]] - -# This should generate an error because it is unresolvable. -type TA3 = TA3 - -# This should generate an error because it is unresolvable. -type TA4[T] = T | TA4[str] - -type TA5[T] = T | list[TA5[T]] - -# This should generate an error because it is unresolvable. -type TA6 = "TA7" -type TA7 = TA6 - -type JSONNode = list[JSONNode] | dict[str, JSONNode] | str | float - -# This should generate an error because it is unresolvable. -type TA8[**P] = TA8[P, int] diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasStatement5.py b/packages/vipeye-internal/src/tests/samples/typeAliasStatement5.py deleted file mode 100644 index c4c28d9e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasStatement5.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the interaction between a traditional type alias -# and a PEP 695 type alias. - -from typing import Annotated, TypeVar - - -T = TypeVar("T") - -TA1 = Annotated[T, "metadata"] -TA2 = list[T] - -type TA1_1 = TA1[int] -type TA1_2[T] = TA1[T] - -type TA2_1 = TA2[int] -type TA2_2[T] = TA2[T] diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasType1.py b/packages/vipeye-internal/src/tests/samples/typeAliasType1.py deleted file mode 100644 index baff967a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasType1.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests error cases for calls to the TypeAliasType constructor. - -from typing import TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeAliasType, -) - -# This should generate an error because arguments are missing. -TA1 = TypeAliasType() - -# This should generate two errors because 1 isn't a legal name or str. -TA2 = TypeAliasType(1, int) - -my_str = "" - -# This should generate an error because my_str isn't a string literal. -TA3 = TypeAliasType(my_str, int) - -# This should generate an error because name doesn't match. -TA4 = TypeAliasType("TA3", int) - -# This should generate an error because it's not part of an assignment statement. -TypeAliasType("TA3", int) - -# This should generate an error because it has an extra argument. -TA5 = TypeAliasType("TA5", int, x=3) - -# This should generate an error because it has an extra argument. -TA6 = TypeAliasType("TA6", int, 3) - -# This should generate two errors because type_params is not a tuple. -TA7 = TypeAliasType("TA7", int, type_params=[1]) - -# This should generate two errors because type_params is not a tuple of TypeVars. -TA8 = TypeAliasType("TA8", int, type_params=(int,)) - - -S = TypeVar("S") -T = TypeVar("T") - -# This should generate an error because S is not in scope. -TA9 = TypeAliasType("TA9", list[S], type_params=(T,)) - -my_tuple = (S, T) - -# This should generate two errors because type_params is not a tuple expression. -TA10 = TypeAliasType("TA10", int, type_params=my_tuple) -print(TA10.__value__) - - -TA11 = TypeAliasType("TA11", int) -print(TA11.__value__) - -type TA12 = int | str -print(TA12.__value__) - -# This should generate an error. -TA13 = TypeAliasType("TA13", ...) - - -def func1(): - # This should generate an error. - TA14 = TypeAliasType("TA14", int) diff --git a/packages/vipeye-internal/src/tests/samples/typeAliasType2.py b/packages/vipeye-internal/src/tests/samples/typeAliasType2.py deleted file mode 100644 index ba75b0cb..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeAliasType2.py +++ /dev/null @@ -1,81 +0,0 @@ -# This sample tests the TypeAliasType constructor. - -from typing import Callable, Generic, ParamSpec, TypeVar, TypeVarTuple -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeAliasType, -) - -T1 = TypeVar("T1") - -S = TypeVar("S", bound=int) -T = TypeVar("T", bound=str) -P = ParamSpec("P") -Ts = TypeVarTuple("Ts") - -TA1 = TypeAliasType("TA1", "T1 | list[TA1[T1]]", type_params=(T1,)) - -x1: TA1[int] = 1 -x2: TA1[int] = [1] - -TA2 = TypeAliasType( - "TA2", - "Callable[P, T] | list[S] | list[TA2[S, T, P]] | tuple[*Ts]", - type_params=(S, T, P, Ts), -) - - -# This should generate an error because str isn't compatible with S bound. -x3: TA2[str, str, ..., int, str] - -x4: TA2[int, str, ..., int, str] - -# This should generate an error because int isn't compatible with T bound. -x5: TA2[int, int, ...] - -x6: TA2[int, str, [int, str], *tuple[int, str, int]] - -# This should generate an error because it is unresolvable. -TA3 = TypeAliasType("TA3", TA3) - -# This should generate an error because it is unresolvable. -TA4 = TypeAliasType("TA4", "T | TA4[str]", type_params=(T,)) - -TA5 = TypeAliasType("TA5", "T | list[TA5[T]]", type_params=(T,)) - -# This should generate an error because it is unresolvable. -TA6 = TypeAliasType("TA6", "TA7") -TA7 = TypeAliasType("TA7", "TA6") - -JSONNode = TypeAliasType( - "JSONNode", "list[JSONNode] | dict[str, JSONNode] | str | float" -) - - -class A(Generic[T1]): - L = TypeAliasType("L", list[T1]) - - -a1: A[int].L = [1, 2, 3] -a2: A[str].L = ["1", "2", "3"] - -# This should generate an error because S is not in scope. -TA8 = TypeAliasType("TA8", list[S]) - - -def identity[T](t: T) -> T: - return t - - -reveal_type(identity(TA1), expected_text="TypeAliasType") - - -class B: - TA9 = TypeAliasType("TA9", T1 | list[T1], type_params=(T1,)) - - -b1: B.TA9[int] - - -# This should generate an error because TA9 refers to itself -# and is not quoted. -TA9 = TypeAliasType("TA9", list[TA9]) diff --git a/packages/vipeye-internal/src/tests/samples/typeCheckOnly1.py b/packages/vipeye-internal/src/tests/samples/typeCheckOnly1.py deleted file mode 100644 index 44a4fa45..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeCheckOnly1.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the reporting of a function or class decorated with -# @type_check_only when used in a value expression. - -from __future__ import annotations - -from typing import TYPE_CHECKING, type_check_only - -if TYPE_CHECKING: - from typing import _TypedDict - -a1: function -a2: _TypedDict - -# This should generate an error. -v1 = function - -# This should generate an error, but it doesn't because -# of a typeshed issue. -v2 = isinstance(1, ellipsis) - -# This should generate an error. -v3 = _TypedDict - - -if TYPE_CHECKING: - - class ClassA: - @type_check_only - def method1(self): - pass - - @type_check_only - def func1() -> None: ... - - -# This should generate an error. -ClassA().method1() - -# This should generate an error. -func1() diff --git a/packages/vipeye-internal/src/tests/samples/typeForm1.py b/packages/vipeye-internal/src/tests/samples/typeForm1.py deleted file mode 100644 index efaffee5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm1.py +++ /dev/null @@ -1,32 +0,0 @@ -# This sample tests basic usage of the TypeForm special form -# when used as a call. - -# viper: reportMissingModuleSource=false - -from typing import Annotated -from typing_extensions import TypeForm - -# This should generate an error because TypeForm requires one arg. -t1 = TypeForm() - -# This should generate an error because TypeForm uses positional args only. -t2 = TypeForm(x=int) - -# This should generate an error because TypeForm accepts only one arg. -t3 = TypeForm(int, str) - -# This should generate an error because the type expression is invalid. -t4 = TypeForm("int[str]") - - -s1 = TypeForm(int) -reveal_type(s1, expected_text="TypeForm[int]") - -s2 = TypeForm("int | str") -reveal_type(s2, expected_text="TypeForm[int | str]") - -s3 = TypeForm(list["str"]) -reveal_type(s3, expected_text="TypeForm[list[str]]") - -s4 = TypeForm(Annotated[int, "meta"]) -reveal_type(s4, expected_text="TypeForm[int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeForm2.py b/packages/vipeye-internal/src/tests/samples/typeForm2.py deleted file mode 100644 index 227795b6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm2.py +++ /dev/null @@ -1,231 +0,0 @@ -# This sample tests type inference rules for TypeForm. - -# viper: reportMissingModuleSource=false - -from typing import ( - Annotated, - Any, - Callable, - Concatenate, - Final, - Generic, - Literal, - LiteralString, - Never, - NoReturn, - NotRequired, - Optional, - Required, - Type, - TypeAlias, - TypeGuard, - TypeVar, - Union, - Unpack, -) -import typing as tp -from typing_extensions import TypeForm, TypeIs, ReadOnly - -T = TypeVar("T") - -type TA1 = int | str -type TA2[T] = list[T] | T -TA3: TypeAlias = Annotated[int, "meta"] -TA4 = int | str -type TA5[T] = int - - -def tf[T](x: TypeForm[T]) -> TypeForm[T]: ... - - -def func1(): - t1 = tf(int) - reveal_type(t1, expected_text="TypeForm[int]") - - t2 = tf(int | str) - reveal_type(t2, expected_text="TypeForm[int | str]") - - t3 = tf("int | str") - reveal_type(t3, expected_text="TypeForm[int | str]") - - t5 = tf(Annotated[int, "meta"]) - reveal_type(t5, expected_text="TypeForm[int]") - - t5_alt1 = tf(tp.Annotated[int, "meta"]) - reveal_type(t5_alt1, expected_text="TypeForm[int]") - - t6 = tf(Any) - reveal_type(t6, expected_text="TypeForm[Any]") - - t6_alt1 = tf(tp.Any) - reveal_type(t6_alt1, expected_text="TypeForm[Any]") - - t7 = tf(type[int]) - reveal_type(t7, expected_text="TypeForm[type[int]]") - - t7_alt = tf(type) - reveal_type(t7_alt, expected_text="TypeForm[type]") - - t8 = tf(TA1) - reveal_type(t8, expected_text="TypeForm[int | str]") - - t9 = tf(TA2[str]) - reveal_type(t9, expected_text="TypeForm[list[str] | str]") - - t9_alt = tf(TA2) - reveal_type(t9_alt, expected_text="TypeForm[list[T@TA2] | T@TA2]") - - t10 = tf(TA3) - reveal_type(t10, expected_text="TypeForm[int]") - - t11 = tf(TA4) - reveal_type(t11, expected_text="TypeForm[int | str]") - - t12 = tf(Literal[1, 2, 3]) - reveal_type(t12, expected_text="TypeForm[Literal[1, 2, 3]]") - - t12_alt1 = tf(tp.Literal[1, 2, 3]) - reveal_type(t12_alt1, expected_text="TypeForm[Literal[1, 2, 3]]") - - t13 = tf(Optional[str]) - reveal_type(t13, expected_text="TypeForm[str | None]") - - t13_alt1 = tf(tp.Optional[str]) - reveal_type(t13_alt1, expected_text="TypeForm[str | None]") - - t14 = tf(Union[list[int], str]) - reveal_type(t14, expected_text="TypeForm[list[int] | str]") - - t14_alt1 = tf(tp.Union[list[int], str]) - reveal_type(t14_alt1, expected_text="TypeForm[list[int] | str]") - - t15 = tf(TypeGuard[int]) - reveal_type(t15, expected_text="TypeForm[TypeGuard[int]]") - - t15_alt1 = tf(tp.TypeGuard[int]) - reveal_type(t15_alt1, expected_text="TypeForm[TypeGuard[int]]") - - t16 = tf(TypeIs[str]) - reveal_type(t16, expected_text="TypeForm[TypeIs[str]]") - - t17 = tf(Callable[[int], None]) - reveal_type(t17, expected_text="TypeForm[(int) -> None]") - - t17_alt1 = tf(tp.Callable[[int], None]) - reveal_type(t17_alt1, expected_text="TypeForm[(int) -> None]") - - t18 = list - reveal_type(tf(t18), expected_text="TypeForm[list[Unknown]]") - reveal_type(tf(t18[int]), expected_text="TypeForm[list[int]]") - - t19 = tf(list | dict) - reveal_type( - t19, - expected_text="TypeForm[list[Unknown] | dict[Unknown, Unknown]]", - ) - - t20 = tuple - reveal_type(tf(t20), expected_text="TypeForm[tuple[Unknown, ...]]") - reveal_type(tf(t20[()]), expected_text="TypeForm[tuple[()]]") - reveal_type(tf(t20[int, ...]), expected_text="TypeForm[tuple[int, ...]]") - - t21 = tf(tuple[()]) - reveal_type(t21, expected_text="TypeForm[tuple[()]]") - - t22 = tf(tuple[int, *tuple[str, ...], int]) - reveal_type(t22, expected_text="TypeForm[tuple[int, *tuple[str, ...], int]]") - - t23 = tf(TA5) - reveal_type(t23, expected_text="TypeForm[int]") - - t24 = tf(str | None) - reveal_type(t24, expected_text="TypeForm[str | None]") - - t25 = tf(None) - reveal_type(t25, expected_text="TypeForm[None]") - - t26 = tf(LiteralString) - reveal_type(t26, expected_text="TypeForm[LiteralString]") - - -def func2[T](x: T) -> T: - t1 = tf(str | T) - reveal_type(t1, expected_text="TypeForm[str | T@func2]") - - t2 = tf(type[T]) - reveal_type(t2, expected_text="TypeForm[type[T@func2]]") - - return x - - -def func3[**P, R](x: Callable[P, R]) -> Callable[P, R]: - t1 = tf(Callable[Concatenate[int, P], R]) - reveal_type(t1, expected_text="TypeForm[(int, **P@func3) -> R@func3]") - - return x - - -def func4(): - t1 = tf(Never) - reveal_type(t1, expected_text="TypeForm[Never]") - - t1_alt1 = tf(tp.Never) - reveal_type(t1_alt1, expected_text="TypeForm[Never]") - - t2 = tf(NoReturn) - reveal_type(t2, expected_text="TypeForm[NoReturn]") - - t3 = tf(Type[int]) - reveal_type(t3, expected_text="TypeForm[type[int]]") - - t3_alt1 = tf(tp.Type[int]) - reveal_type(t3_alt1, expected_text="TypeForm[type[int]]") - - -def func5(): - t1 = tf(TypeForm[int | str]) - reveal_type(t1, expected_text="TypeForm[TypeForm[int | str]]") - - t2 = tf(TypeForm[TypeForm[int | str]]) - reveal_type(t2, expected_text="TypeForm[TypeForm[TypeForm[int | str]]]") - - -def func6(x: T) -> T: - v1: TypeForm[T] = T - v2 = tf(T) - reveal_type(v2, expected_text="TypeForm[T@func6]") - - v3: TypeForm[T | int] = T - v3 = T | int - - v4 = tf(T | int) - reveal_type(v4, expected_text="TypeForm[T@func6 | int]") - - v5: TypeForm[list[T]] = list[T] - - v6 = tf(list[T]) - reveal_type(v6, expected_text="TypeForm[list[T@func6]]") - - return x - - -# These should maybe generage errors, but given -# that the typing spec doesn't say anything about how -# to evaluate the type of a special form when it's used -# in a value expression context, it's not clear. -def func7(): - t1 = tf(Generic) - - t2 = tf(Final) - - t3 = tf(Final[int]) - - t4 = tf(Concatenate[int]) - - t5 = tf(Unpack[int]) - - t6 = tf(Required[int]) - - t7 = tf(NotRequired[int]) - - t8 = tf(ReadOnly[int]) diff --git a/packages/vipeye-internal/src/tests/samples/typeForm3.py b/packages/vipeye-internal/src/tests/samples/typeForm3.py deleted file mode 100644 index 5befb0a2..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm3.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests inference behaviors related to TypeForm. - -# viper: strict - - -def func1(): - return "int | str" - - -reveal_type(func1(), expected_text="Literal['int | str']") - - -def func2(): - return int | str - - -reveal_type(func2(), expected_text="UnionType") - - -v1 = [int | str, str | bytes] -reveal_type(v1, expected_text="list[UnionType]") - -v2 = {int | str, str | bytes} -reveal_type(v2, expected_text="set[UnionType]") - -v3 = {int | str: str | bytes} -reveal_type(v3, expected_text="dict[UnionType, UnionType]") diff --git a/packages/vipeye-internal/src/tests/samples/typeForm4.py b/packages/vipeye-internal/src/tests/samples/typeForm4.py deleted file mode 100644 index f3405e1c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm4.py +++ /dev/null @@ -1,241 +0,0 @@ -# This sample tests assignability rules for TypeForm types. - -# viper: reportMissingModuleSource=false - -from typing import ( - Annotated, - Any, - Callable, - Concatenate, - Final, - Generic, - Literal, - LiteralString, - Never, - NewType, - NoReturn, - NotRequired, - Optional, - Required, - Type, - TypeAlias, - TypeGuard, - TypeVar, - Union, - Unpack, -) -import typing -from typing_extensions import ReadOnly, TypeForm, TypeIs - -type TA1 = int | str -type TA2[T] = list[T] | T -TA3: TypeAlias = Annotated[int, "meta"] -TA4 = int | str -type TA5[T] = int - - -def func1(): - t1: TypeForm[int | str] = int - t2: TypeForm[int | str] = "int | str" - t3: TypeForm[Any] = int | str - t4: TypeForm = Annotated[int, "meta"] - t5: TypeForm = Any - t6: TypeForm = type[int] - t7: TypeForm[Any] = type - - t8: TypeForm[TA1] = TA1 - t9: TypeForm[int | str] = TA1 - - t10: TypeForm = TA2[str] - t11: TypeForm[TA2[str]] = TA2[str] - t12: TypeForm[list[Any] | str] = TA2[str] - - t13: TypeForm = TA2 - - t14: TypeForm[int] = TA3 - - t15: TypeForm = TA4 - - t16: TypeForm[int] = Literal[1, 2, 3] - - t17: TypeForm[str | None] = Optional[str] - - t18: TypeForm = Union[list[int], str] - - t19: TypeForm[TypeGuard[Any]] = TypeGuard[int] - t20: TypeForm = TypeIs[str] - - t21: TypeForm[Callable] = Callable[[int], None] - - t22: TypeForm[list[Any]] = list - - t24: TypeForm = list | dict - - t25: TypeForm = tuple - - t28: TypeForm = tuple[()] - - t29: TypeForm = tuple[int, *tuple[str, ...], int] - t30: TypeForm = TA5 - - t31: TypeForm = None - t32: TypeForm = None | str - - def get_type() -> TypeForm[int]: - return int - - t33: TypeForm = get_type() - - -def func2[T](x: T) -> T: - t1: TypeForm[str | T | None] = str | T - - t2: TypeForm[Any] = type[T] - - return x - - -def func3[**P, R](x: Callable[P, R]) -> Callable[P, R]: - t1: TypeForm = Callable[Concatenate[int, P], R] - - return x - - -def func4(): - t1: TypeForm[Never] = Never - - t2: TypeForm[Never] = NoReturn - - t3: TypeForm[type[int]] = Type[int] - - -NT1 = NewType("NT1", int) - - -def func5[**P, R](): - t1: TypeForm[LiteralString] = typing.LiteralString - t2: TypeForm = TypeForm[int | str] - t3: TypeForm = "P" - t4: TypeForm = "typing.Callable" - t5: TypeForm = "Union[int, str]" - t6: TypeForm = NT1 - - -T = TypeVar("T") - - -def func6[**P, R](): - # This should generate an error. - t1: TypeForm[int] = Generic - - # This should generate an error. - t2: TypeForm[int] = Final - - # This should generate an error. - t3: TypeForm[int] = Final[int] - - # This should generate an error. - t4: TypeForm[int] = Concatenate[int] - - # This should generate an error. - t5: TypeForm[int] = Unpack[int] - - # This should generate an error. - t6: TypeForm[int] = Required[int] - - # This should generate an error. - t7: TypeForm[int] = NotRequired[int] - - # This should generate an error. - t8: TypeForm[int] = ReadOnly[int] - - var1 = 1 - # This should generate an error. - t9: TypeForm = int | var1 - - # This should generate an error. - t10: TypeForm = "int + str" - - # This should generate an error. - t11: TypeForm = "(int, str)" - - # This should generate an error. - t12: TypeForm = "Q" - - # This should generate an error. - t13: TypeForm = "Callable[P]" - - # This should generate an error. - t14: TypeForm = "Callable[]" - - # This should generate an error. - t15: TypeForm = "typing.Optional" - - # This should generate an error. - t16: TypeForm = "Union[]" - - # This should generate an error. - t17: TypeForm = "Union[int]" - - # This should generate an error. - t18: TypeForm = "Annotated" - - # This should generate an error. - t19: TypeForm = "T" - - # This should generate an error. - t20: TypeForm = "int extra" - - -def func7(): - # This should generate an error. - t1: TypeForm[Literal[""]] = typing.LiteralString - - # This should generate an error. - t2: TypeForm[Never] = int - - # This should generate an error. - t3: TypeForm[type[int]] = int - - # This should generate an error. - t4: TypeForm[int] = type[int] - - -def func8[S, T: type](p1: TypeForm[Any], p2: TypeForm[int | str], p3: TypeForm[S]): - t1: TypeForm = p1 - t2: TypeForm = p2 - t3: TypeForm = p3 - - t4: TypeForm[int | str] = p2 - t5: TypeForm[int | str | None] = p2 - - # This should generate an error. - t6: TypeForm[int] = p2 - - t7: TypeForm[S] = p3 - - # This should generate an error. - t8: TypeForm[T] = p3 - - t9: TypeForm = S - t10: TypeForm = T - - t11: TypeForm[S] = S - t12: TypeForm[T] = T - - -def func9(): - t1: list[TypeForm[int | str]] = ["str | int", str] - t1.append("bool") - - # This should generate an error. - t1.append(complex) - - -def func10[T](x: type[T], y: type[int]): - t1: TypeForm = x - t2: TypeForm[T] = x - - t3: TypeForm = y - t4: TypeForm[int] = y - t5: TypeForm[float] = y diff --git a/packages/vipeye-internal/src/tests/samples/typeForm5.py b/packages/vipeye-internal/src/tests/samples/typeForm5.py deleted file mode 100644 index efad4413..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm5.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests the TypeForm special form when used with type variables. - -# viper: reportMissingModuleSource=false - -from typing import Literal, LiteralString, TypeGuard, Optional -from typing_extensions import TypeForm, TypeIs - - -def func1[T](x: TypeForm[T]) -> T: ... - - -def func2[S](x: TypeForm[S | None]) -> S: ... - - -def func3[S, T](x: TypeForm[S | T]) -> S: ... - - -def func4[T](x: object, t: TypeForm[T]) -> TypeIs[T]: ... - - -def func5[T](x: TypeForm[T]) -> TypeGuard[type[T]]: ... - - -v1 = func1(int | str) -reveal_type(v1, expected_text="int | str") - -v2 = func1("int | str") -reveal_type(v2, expected_text="int | str") - -v3 = func1(LiteralString) -reveal_type(v3, expected_text="LiteralString") - -v4 = func1(Literal[1, 2, 3]) -reveal_type(v4, expected_text="Literal[1, 2, 3]") - -v5 = func2("Optional[str]") -reveal_type(v5, expected_text="str") - -v6 = func2(int | str | None) -reveal_type(v6, expected_text="int | str") - -v7 = func3(int | str | None) -reveal_type(v7, expected_text="int | str | None") - -v8 = func4(1, int | str | None) -reveal_type(v8, expected_text="TypeIs[int | str | None]") - -v9 = func5(int | str | None) -reveal_type(v9, expected_text="TypeGuard[type[int] | type[str] | type[None]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeForm6.py b/packages/vipeye-internal/src/tests/samples/typeForm6.py deleted file mode 100644 index 4753db29..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm6.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests the handling of assert_type with TypeForm types. - -# viper: reportMissingModuleSource=false - -from types import UnionType -from typing import assert_type -from typing_extensions import TypeForm - - -def func1[T](x: T) -> T: - v1 = str - assert_type(v1, type[str]) - - # This should generate an error. - assert_type(v1, TypeForm[str]) - - # This should generate an error. - assert_type(v1, type[str] | type[int]) - - # This should generate an error. - assert_type(v1, TypeForm[str | int]) - - v1_tf: TypeForm[str | int] = str - assert_type(v1_tf, TypeForm[str]) - - # This should generate an error. - assert_type(v1_tf, type[str]) - - return x - - -def func2[T](x: T) -> T: - v2 = str | T - assert_type(v2, UnionType) - - # This should generate an error. - assert_type(v2, TypeForm[str | T]) - - v2_tf: TypeForm[object] = str | T - - # This should generate an error. - assert_type(v2_tf, UnionType) - - assert_type(v2_tf, TypeForm[str | T]) - - return x - - -def func3[T](x: T) -> T: - v3 = list["str | T"] | T - assert_type(v3, UnionType) - - # This should generate an error. - assert_type(v3, TypeForm[list[str | T] | T]) - - v3_tf: TypeForm[object] = list["str | T"] | T - # This should generate an error. - assert_type(v3_tf, UnionType) - - assert_type(v3_tf, TypeForm[list[str | T] | T]) - - return x diff --git a/packages/vipeye-internal/src/tests/samples/typeForm7.py b/packages/vipeye-internal/src/tests/samples/typeForm7.py deleted file mode 100644 index 901e9851..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm7.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the isinstance type narrowing involving TypeForm types. - -# viper: reportMissingModuleSource=false - -from types import UnionType -from typing import Any -from typing_extensions import TypeForm - - -def func1(tf1: TypeForm[Any]): - if isinstance(tf1, UnionType): - reveal_type(tf1, expected_text="UnionType") - else: - reveal_type(tf1, expected_text="TypeForm[Any]") - - reveal_type(tf1, expected_text="UnionType | TypeForm[Any]") - - -def func2(): - # This should generate an error. - if isinstance(1, TypeForm): - pass diff --git a/packages/vipeye-internal/src/tests/samples/typeForm8.py b/packages/vipeye-internal/src/tests/samples/typeForm8.py deleted file mode 100644 index c9ec244b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeForm8.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests that a string literal nested within a container literal -# is interpreted as a stringified TypeForm when the expected element -# type is a TypeForm. - -# viper: reportMissingModuleSource=false - -from typing import Union -from typing_extensions import TypeForm - - -# The string elements should be interpreted as stringified TypeForms -# (rather than as plain strs), so these assignments should not generate errors. -v1: list[TypeForm] = ["int", "str"] -v2: dict[str, TypeForm] = {"key": "int"} -v3: tuple[TypeForm, TypeForm] = ("int", "str | None") -v4: set[TypeForm] = {"int | str"} -v5: list[TypeForm[int]] = ["int"] - - -# Nested containers should propagate the expected TypeForm type as well. -v6: list[list[TypeForm]] = [["int", "str"]] -v7: dict[str, list[TypeForm]] = {"key": ["int", "str"]} - - -# This should generate an error because "int[str]" is not a valid type -# expression, so it falls back to a plain str that is not assignable to a -# TypeForm element. -v8: list[TypeForm] = ["int[str]"] - -# This should generate an error because "int" is interpreted as TypeForm[int], -# which is not assignable to a TypeForm[str] element. (Compare with v5, which -# uses TypeForm[int] and is accepted. This confirms the string is interpreted -# as a type rather than left as a plain str.) -v9: list[TypeForm[str]] = ["int"] - - -# When the expected element type is not a TypeForm, the string should remain -# a plain str. -v10: list[str] = ["int"] -reveal_type(v10, expected_text="list[str]") - -# A Union element type that includes a TypeForm should still trigger -# interpretation of the string as a stringified TypeForm. -v11: list[Union[TypeForm, int]] = ["int"] diff --git a/packages/vipeye-internal/src/tests/samples/typeGuard1.py b/packages/vipeye-internal/src/tests/samples/typeGuard1.py deleted file mode 100644 index 8b46aa7b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeGuard1.py +++ /dev/null @@ -1,132 +0,0 @@ -# This sample tests the TypeGuard functionality -# that allows user-defined functions to perform -# conditional type narrowing. - -# viper: reportMissingModuleSource=false - -import os -from typing import Any, Callable, TypeVar - -from typing_extensions import TypeGuard # viper: ignore[reportMissingModuleSource] - -_T = TypeVar("_T") - - -def is_two_element_tuple(a: tuple[_T, ...]) -> TypeGuard[tuple[_T, _T]]: - return True - - -def func1(a: tuple[int, ...]): - if is_two_element_tuple(a): - reveal_type(a, expected_text="tuple[int, int]") - else: - reveal_type(a, expected_text="tuple[int, ...]") - - -def is_string_list(val: list[Any], allow_zero_entries: bool) -> TypeGuard[list[str]]: - if allow_zero_entries and len(val) == 0: - return True - return all(isinstance(x, str) for x in val) - - -def func2(a: list[str | int]): - if is_string_list(a, True): - reveal_type(a, expected_text="list[str]") - else: - reveal_type(a, expected_text="list[str | int]") - - -# This should generate an error because TypeGuard -# has no type argument. -def bad1(a: int, b: object) -> TypeGuard: - # This is a runtime use of TypeGuard and shouldn't generate an error. - if b is TypeGuard: - return True - return True - - -# This should generate an error because TypeGuard -# has too many type arguments. -def bad2(a: int) -> TypeGuard[str, int]: - return True - - -# This should generate an error because TypeGuard -# does not accept an ellipsis. -def bad3(a: int) -> TypeGuard[...]: - return True - - -# This should generate an error because TypeGuard -# has does not accept a module. -def bad4(a: int) -> TypeGuard[os]: - return True - - -def bad5(a: int) -> TypeGuard[int]: - # This should generate an error because only - # bool values can be returned. - return 3 - - -# This should generate an error because a type guard function must -# accept at least one parameter. -def bad6() -> TypeGuard[int]: - return True - - -class ClassA: - # This should generate an error because a type guard function must - # accept at least one parameter. - def method1(self) -> TypeGuard[int]: - return True - - -class IsInt: - def __call__(self, value: Any) -> TypeGuard[int]: - return isinstance(value, int) - - -def func3(x: Any): - i = IsInt() - if i(x): - reveal_type(x, expected_text="int") - - -def is_int(obj: type) -> TypeGuard[type[int]]: ... - - -def func4(typ: type[_T]) -> _T: - if not is_int(typ): - raise Exception("Unsupported type") - - return typ() - - -def takes_int_typeguard(f: Callable[[object], TypeGuard[int]]) -> None: - pass - - -def int_typeguard(val: object) -> TypeGuard[int]: - return isinstance(val, int) - - -def bool_typeguard(val: object) -> TypeGuard[bool]: - return isinstance(val, bool) - - -def str_typeguard(val: object) -> TypeGuard[str]: - return isinstance(val, str) - - -takes_int_typeguard(int_typeguard) -takes_int_typeguard(bool_typeguard) - -# This should generate an error because TypeGuard is covariant. -takes_int_typeguard(str_typeguard) - - -v0 = is_int(int) -v1: bool = v0 -v2: int = v0 -v3 = v0 & v0 diff --git a/packages/vipeye-internal/src/tests/samples/typeGuard2.py b/packages/vipeye-internal/src/tests/samples/typeGuard2.py deleted file mode 100644 index 3de67232..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeGuard2.py +++ /dev/null @@ -1,54 +0,0 @@ -# This sample tests the handling of user-defined type guards (PEP 647) -# when they are used as callback functions. - -# viper: strict, reportMissingModuleSource=false - -from typing import Any, Callable, Sequence, TypeVar, overload -from typing_extensions import TypeGuard # viper: ignore[reportMissingModuleSource] - - -_T = TypeVar("_T") - - -def cb1(obj: object) -> TypeGuard[int]: ... - - -def cb2(obj: object) -> bool: ... - - -def simple_filter( - val: Sequence[object], fn: Callable[[object], bool] -) -> list[object]: ... - - -@overload -def overloaded_filter( - val: Sequence[object], fn: Callable[[object], TypeGuard[_T]] -) -> Sequence[_T]: ... - - -@overload -def overloaded_filter( - val: Sequence[object], fn: Callable[[object], bool] -) -> Sequence[object]: ... - - -def overloaded_filter( - val: Sequence[object], fn: Callable[[object], Any] -) -> Sequence[Any]: ... - - -x1 = cb1(1) -reveal_type(x1, expected_text="TypeGuard[int]") - -sf1 = simple_filter([], cb1) -reveal_type(sf1, expected_text="list[object]") - -sf2 = simple_filter([], cb2) -reveal_type(sf2, expected_text="list[object]") - -of1 = overloaded_filter([], cb1) -reveal_type(of1, expected_text="Sequence[int]") - -of2 = overloaded_filter([], cb2) -reveal_type(of2, expected_text="Sequence[object]") diff --git a/packages/vipeye-internal/src/tests/samples/typeGuard3.py b/packages/vipeye-internal/src/tests/samples/typeGuard3.py deleted file mode 100644 index 88967a63..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeGuard3.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests that user-defined TypeGuard can -# be used in an overloaded function. - -from enum import Enum -from typing import Literal, overload -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeGuard, - TypeIs, -) - - -class TypeGuardMode(Enum): - NoTypeGuard = 0 - TypeGuard = 1 - TypeIs = 2 - - -@overload -def is_int(obj: object, mode: Literal[TypeGuardMode.NoTypeGuard]) -> bool: ... - - -@overload -def is_int(obj: object, mode: Literal[TypeGuardMode.TypeGuard]) -> TypeGuard[int]: ... - - -@overload -def is_int(obj: object, mode: Literal[TypeGuardMode.TypeIs]) -> TypeIs[int]: ... - - -def is_int(obj: object, mode: TypeGuardMode) -> bool | TypeGuard[int] | TypeIs[int]: ... - - -def func_no_typeguard(val: int | str): - if is_int(val, TypeGuardMode.NoTypeGuard): - reveal_type(val, expected_text="int | str") - else: - reveal_type(val, expected_text="int | str") - - -def func_typeguard(val: int | str): - if is_int(val, TypeGuardMode.TypeGuard): - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="int | str") - - -def func_typeis(val: int | str): - if is_int(val, TypeGuardMode.TypeIs): - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/typeIgnore1.py b/packages/vipeye-internal/src/tests/samples/typeIgnore1.py deleted file mode 100644 index 6983a4c5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIgnore1.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the type: ignore for the entire file. - -# type: ignore - -# The "type: ignore" should suppress these errors. -a: int = 3 -b = len(a) - -for for for - diff --git a/packages/vipeye-internal/src/tests/samples/typeIgnore2.py b/packages/vipeye-internal/src/tests/samples/typeIgnore2.py deleted file mode 100644 index 71add07f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIgnore2.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests the type: ignore for individual lines. - -from typing import Dict - - -a: int = 3 -b = len(a) # type: ignore - -for for for # type: ignore - -c: Dict[str, str] = { - 3: 3, - 'hello': 3, - 3.2: 2.4 -} #type:ignore # something - - - - - diff --git a/packages/vipeye-internal/src/tests/samples/typeIgnore3.py b/packages/vipeye-internal/src/tests/samples/typeIgnore3.py deleted file mode 100644 index ece4541f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIgnore3.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the type: ignore for individual lines. -# It uses a form of ignore syntax that is not part of the -# official PEP 484 spec but is a variant supported by mypy. - -from typing import Dict - - -a: int = 3 -b = len(a) # type: ignore[1424] - -for for for # type: ignore[1424, 244] - -c: Dict[str, str] = { - 3: 3, - 'hello': 3, - 3.2: 2.4 -} #type:ignore[999] # something - - - - - diff --git a/packages/vipeye-internal/src/tests/samples/typeIgnore4.py b/packages/vipeye-internal/src/tests/samples/typeIgnore4.py deleted file mode 100644 index 99bdae16..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIgnore4.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the reportUnnecessaryTypeIgnoreComment diagnostic check -# as applied to the entire file. - -a: str = 3 # type: ignore - -# This should emit an error if reportUnnecessaryTypeComment is enabled -b: str = "" # type: ignore - -# This should emit an error if reportUnnecessaryTypeComment is enabled -c: int = 3 # type: ignore diff --git a/packages/vipeye-internal/src/tests/samples/typeIgnore5.py b/packages/vipeye-internal/src/tests/samples/typeIgnore5.py deleted file mode 100644 index 2cfea889..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIgnore5.py +++ /dev/null @@ -1,7 +0,0 @@ -# This sample tests the reportUnnecessaryTypeIgnoreComment diagnostic check -# as applied to individual lines. - -# This should generate an error if reportUnnecessaryTypeIgnoreComment is enabled. -# type: ignore - -b: str = "" diff --git a/packages/vipeye-internal/src/tests/samples/typeIs1.py b/packages/vipeye-internal/src/tests/samples/typeIs1.py deleted file mode 100644 index 8aaea931..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIs1.py +++ /dev/null @@ -1,190 +0,0 @@ -# This sample tests the TypeIs form. - -# viper: reportMissingModuleSource=false - -from typing import ( - Any, - Callable, - Collection, - Literal, - Mapping, - Sequence, - TypeVar, - Union, - overload, -) - -from typing_extensions import TypeIs - - -def is_str1(val: Union[str, int]) -> TypeIs[str]: - return isinstance(val, str) - - -def func1(val: Union[str, int]): - if is_str1(val): - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="int") - - -def is_true(o: object) -> TypeIs[Literal[True]]: ... - - -def func2(val: bool): - if not is_true(val): - reveal_type(val, expected_text="bool") - else: - reveal_type(val, expected_text="Literal[True]") - - reveal_type(val, expected_text="bool") - - -def is_list(val: object) -> TypeIs[list[Any]]: - return isinstance(val, list) - - -def func3(val: dict[str, str] | list[str] | list[int] | Sequence[int]): - if is_list(val): - reveal_type(val, expected_text="list[str] | list[int] | list[Any]") - else: - reveal_type(val, expected_text="dict[str, str] | Sequence[int]") - - -def func4(val: dict[str, str] | list[str] | list[int] | tuple[int]): - if is_list(val): - reveal_type(val, expected_text="list[str] | list[int]") - else: - reveal_type(val, expected_text="dict[str, str] | tuple[int]") - - -_K = TypeVar("_K") -_V = TypeVar("_V") - - -def is_dict(val: Mapping[_K, _V]) -> TypeIs[dict[_K, _V]]: - return isinstance(val, dict) - - -def func5(val: dict[_K, _V] | Mapping[_K, _V]): - if not is_dict(val): - reveal_type(val, expected_text="Mapping[_K@func5, _V@func5]") - else: - reveal_type(val, expected_text="dict[_K@func5, _V@func5]") - - -def is_cardinal_direction(val: str) -> TypeIs[Literal["N", "S", "E", "W"]]: - return val in ("N", "S", "E", "W") - - -def func6(direction: Literal["NW", "E"]): - if is_cardinal_direction(direction): - reveal_type(direction, expected_text="Literal['E']") - else: - reveal_type(direction, expected_text="Literal['NW']") - - -class Animal: ... - - -class Kangaroo(Animal): ... - - -class Koala(Animal): ... - - -T = TypeVar("T") - - -def is_marsupial(val: Animal) -> TypeIs[Kangaroo | Koala]: - return isinstance(val, Kangaroo | Koala) - - -# This should generate an error because list[T] isn't consistent with list[T | None]. -def has_no_nones(val: list[T | None]) -> TypeIs[list[T]]: - return None not in val - - -def takes_int_typeis(f: Callable[[object], TypeIs[int]]) -> None: - pass - - -def int_typeis(val: object) -> TypeIs[int]: - return isinstance(val, int) - - -def bool_typeis(val: object) -> TypeIs[bool]: - return isinstance(val, bool) - - -takes_int_typeis(int_typeis) - -# This should generate an error because TypeIs is invariant. -takes_int_typeis(bool_typeis) - - -def is_two_element_tuple(val: tuple[T, ...]) -> TypeIs[tuple[T, T]]: - return len(val) == 2 - - -def func7(names: tuple[str, ...]): - if is_two_element_tuple(names): - reveal_type(names, expected_text="tuple[str, str]") - else: - reveal_type(names, expected_text="tuple[str, ...]") - - -def is_int(obj: type) -> TypeIs[type[int]]: ... - - -def func8(x: type) -> None: - if is_int(x): - reveal_type(x, expected_text="type[int]") - - -def is_int_list(x: Collection[Any]) -> TypeIs[list[int]]: - raise NotImplementedError - - -def func9(val: Collection[object]) -> None: - if is_int_list(val): - reveal_type(val, expected_text="list[int]") - else: - reveal_type(val, expected_text="Collection[object]") - - -@overload -def func10(v: tuple[int | str, ...], b: Literal[False]) -> TypeIs[tuple[str, ...]]: ... - - -@overload -def func10( - v: tuple[int | str, ...], b: Literal[True] = True -) -> TypeIs[tuple[int, ...]]: ... - - -def func10(v: tuple[int | str, ...], b: bool = True) -> bool: ... - - -v0 = is_int(int) -v1: bool = v0 -v2: int = v0 -v3 = v0 & v0 - - -def is_sequence_of_int(sequence: Sequence) -> TypeIs[Sequence[int]]: - return all(isinstance(x, int) for x in sequence) - - -def func11(v: Sequence[int] | Sequence[str]): - if is_sequence_of_int(v): - reveal_type(v, expected_text="Sequence[int]") - else: - reveal_type(v, expected_text="Sequence[str]") - - -def func12(v: Sequence[int | str] | Sequence[list[Any]]): - if is_sequence_of_int(v): - reveal_type(v, expected_text="Sequence[int]") - else: - reveal_type(v, expected_text="Sequence[int | str] | Sequence[list[Any]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeIs2.py b/packages/vipeye-internal/src/tests/samples/typeIs2.py deleted file mode 100644 index a518169c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIs2.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests the subtyping relationships between TypeIs, TypeGuard, -# and bool. - -# viper: reportMissingModuleSource=false - -from typing import Callable - -from typing_extensions import TypeGuard, TypeIs - -TypeIsInt = Callable[..., TypeIs[int]] -TypeIsFloat = Callable[..., TypeIs[float]] -BoolReturn = Callable[..., bool] -TypeGuardInt = Callable[..., TypeGuard[int]] - - -def func1(v1: TypeIsInt, v2: TypeIsFloat, v3: BoolReturn, v4: TypeGuardInt): - a1: TypeIsInt = v1 - a2: TypeIsInt = v2 # Should generate an error - a3: TypeIsInt = v3 # Should generate an error - a4: TypeIsInt = v4 # Should generate an error - - b1: TypeIsFloat = v1 # Should generate an error - b2: TypeIsFloat = v2 - b3: TypeIsFloat = v3 # Should generate an error - b4: TypeIsFloat = v4 # Should generate an error - - c1: BoolReturn = v1 - c2: BoolReturn = v2 - c3: BoolReturn = v3 - c4: BoolReturn = v4 - - d1: TypeGuardInt = v1 # Should generate an error - d2: TypeGuardInt = v2 # Should generate an error - d3: TypeGuardInt = v3 # Should generate an error - d4: TypeGuardInt = v4 diff --git a/packages/vipeye-internal/src/tests/samples/typeIs3.py b/packages/vipeye-internal/src/tests/samples/typeIs3.py deleted file mode 100644 index 95856bd5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIs3.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the handling of tuple types when used with TypeIs. - -# viper: reportMissingModuleSource=false - -from typing_extensions import TypeIs - - -def is_tuple_of_strings(v: tuple[int | str, ...]) -> TypeIs[tuple[str, ...]]: - return all(isinstance(x, str) for x in v) - - -def test1(t: tuple[int]) -> None: - if is_tuple_of_strings(t): - reveal_type(t, expected_text="Never") - else: - reveal_type(t, expected_text="tuple[int]") - - -def test2(t: tuple[str, int]) -> None: - if is_tuple_of_strings(t): - reveal_type(t, expected_text="Never") - else: - reveal_type(t, expected_text="tuple[str, int]") - - -def test3(t: tuple[int | str]) -> None: - if is_tuple_of_strings(t): - reveal_type(t, expected_text="tuple[str]") - else: - reveal_type(t, expected_text="tuple[int | str]") - - -def test4(t: tuple[int | str, int | str]) -> None: - if is_tuple_of_strings(t): - reveal_type(t, expected_text="tuple[str, str]") - else: - reveal_type(t, expected_text="tuple[int | str, int | str]") - - -def test5(t: tuple[int | str, ...]) -> None: - if is_tuple_of_strings(t): - reveal_type(t, expected_text="tuple[str, ...]") - else: - reveal_type(t, expected_text="tuple[int | str, ...]") - - -def test6(t: tuple[str, *tuple[int | str, ...], str]) -> None: - if is_tuple_of_strings(t): - reveal_type(t, expected_text="tuple[str, *tuple[str, ...], str]") - else: - reveal_type(t, expected_text="tuple[str, *tuple[int | str, ...], str]") diff --git a/packages/vipeye-internal/src/tests/samples/typeIs4.py b/packages/vipeye-internal/src/tests/samples/typeIs4.py deleted file mode 100644 index cc67dde8..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeIs4.py +++ /dev/null @@ -1,38 +0,0 @@ -# This sample tests TypeIs when used with a Callable type. - -# viper: reportMissingModuleSource=false - -from typing import Callable -from typing_extensions import TypeIs - - -def is_callable(obj: object, /) -> TypeIs[Callable[..., object]]: ... - - -def func1(x: type[int]): - if is_callable(x): - reveal_type(x, expected_text="type[int]") - else: - reveal_type(x, expected_text="Never") - - -def func2[T](x: type[T]): - if is_callable(x): - reveal_type(x, expected_text="type[T@func2]") - else: - reveal_type(x, expected_text="Never") - - -def func3[T](x: type[T] | T): - if is_callable(x): - reveal_type(x, expected_text="type[T@func3] | ((...) -> object)") - else: - reveal_type(x, expected_text="object*") - - -def func4[T](x: T) -> T: - if not is_callable(x): - reveal_type(x, expected_text="object*") - raise ValueError() - reveal_type(x, expected_text="(...) -> object") - return x diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing1.py deleted file mode 100644 index 99110511..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing1.py +++ /dev/null @@ -1,68 +0,0 @@ -# This file validates type narrowing that involve -# conditional binary expressions. - -# viper: reportOptionalMemberAccess=false - -from random import random - - -class ClassA: - def x(self): - return - - -maybe = True - -a = None if maybe else ClassA() -b = None if maybe else ClassA() - -if not a or not b: - a.x() - b.x() -else: - a.x() - b.x() - -if not (not a or not b): - a.x() - b.x() -else: - a.x() - b.x() - -if not a and not b: - # This should be flagged as an error - a.x() - # This should be flagged as an error - b.x() -else: - a.x() - b.x() - -if not (not a and not b): - a.x() - b.x() -else: - # This should be flagged as an error - a.x() - # This should be flagged as an error - b.x() - -if a or b: - a.x() - b.x() -else: - # This should be flagged as an error - a.x() - # This should be flagged as an error - b.x() - - -def func1(a: str, b: str | bool) -> bool: - x: str | bool = a and a in [] - reveal_type(x, expected_text="bool | Literal['']") - - if random() > 0.5: - return (a and a in [""]) or True - else: - return x or True diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing2.py deleted file mode 100644 index 1697dc29..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing2.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests the type narrowing logic for "continue" -# statements within a loop. - - -def func1(args: list[int | None]): - for arg in args: - if arg is None: - continue - - reveal_type(arg.bit_length(), expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing3.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing3.py deleted file mode 100644 index 9a349f36..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing3.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the type analyzer's type narrowing logic -# relating to break and continue statements and while test expressions. - - -def only_int(a: int): - return a < 3 - - -def test_break(): - val1 = None - while True: - if val1 is None: - val1 = 5 - break - else: - val1 = "hello" - - reveal_type(val1, expected_text="Literal[5]") - - -def test_continue(): - bar1 = 1 - my_list: list[int | None] = [None, 3, 5] - for n in my_list: - if n is None: - continue - bar1 = n - - only_int(bar1) - - -def test_while_condition(): - param = 3 - - # This should generate an error because param - # can be a str type at this point. - while only_int(param): - if param: - break - else: - param = "hello" diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing4.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing4.py deleted file mode 100644 index 165b7bfd..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing4.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the type narrowing logic for -# conditional expression involving assignment expressions -# (walrus operator). - -# viper: strict - - -class C: - def method1(self): - pass - - -def good(b: C | None) -> None: - a = b - if a: - a.method1() - - -def bad(b: C | None) -> None: - if c := b: - c.method1() - b.method1() diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing5.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing5.py deleted file mode 100644 index d457bd31..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing5.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests type narrowing for assignments -# where the source contains Unknown or Any type -# arguments. - -from typing import Any, Generic, TypeVar - - -def func1(struct: dict[Any, Any]): - a1: dict[str, Any] = struct - reveal_type(a1, expected_text="dict[str, Any]") - - -def func2(struct: Any): - a1: dict[Any, str] = struct - reveal_type(a1, expected_text="dict[Any, str]") - - if isinstance(struct, dict): - a2: dict[str, Any] = struct - reveal_type(a2, expected_text="dict[str, Any]") - - -T = TypeVar("T") - - -class A(Generic[T]): ... - - -def func3(val: A[Any]): - x: A[int] = val - reveal_type(x, expected_text="A[int]") - - -def func4(val: A[list[Any]]): - x: A[list[int]] = val - reveal_type(x, expected_text="A[list[int]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing6.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing6.py deleted file mode 100644 index ccb6654f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing6.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample verifies that a member access expression whose type -# is narrowed is "reset" when part of the member access expression -# is reassigned. - - -class Class1: - val0: int - - -class Class2: - val1: int - val2: Class1 - - -def func1(a: bool): - foo2: Class2 = Class2() - foo2.val1 = 0 - foo2.val2.val0 = 4 - - reveal_type(foo2.val1, expected_text="Literal[0]") - reveal_type(foo2.val2.val0, expected_text="Literal[4]") - - if a: - foo2 = Class2() - - reveal_type(foo2.val1, expected_text="int") - reveal_type(foo2.val2.val0, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing7.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing7.py deleted file mode 100644 index 905bd2db..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing7.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests type narrowing for index operations. - - -class Foo: - val: list[list[str | None]] = [] - - -def func1(v1: list[complex | None]): - if v1[0] and v1[1]: - reveal_type(v1[0], expected_text="complex") - reveal_type(v1[1], expected_text="complex") - reveal_type(v1[2], expected_text="complex | None") - - v1[0], v1[1] = None, None - reveal_type(v1[0], expected_text="None") - reveal_type(v1[1], expected_text="None") - - v1[0], v1[1] = 1, 2 - reveal_type(v1[0], expected_text="Literal[1]") - reveal_type(v1[1], expected_text="Literal[2]") - - v1 = [] - reveal_type(v1[0], expected_text="complex | None") - - i = 1 - if v1[i]: - reveal_type(v1[i], expected_text="complex | None") - - foo = Foo() - if foo.val[0][2]: - reveal_type(foo.val[0][2], expected_text="str") - reveal_type(foo.val[1][2], expected_text="str | None") - - foo.val = [] - reveal_type(foo.val[0][2], expected_text="str | None") - - if v1[-1]: - reveal_type(v1[-1], expected_text="complex") - - -def func2(v1: list[dict[str, str] | list[str]]): - if isinstance(v1[0], dict): - reveal_type(v1[0], expected_text="dict[str, str]") - reveal_type(v1[1], expected_text="dict[str, str] | list[str]") - - if isinstance(v1[-1], list): - reveal_type(v1[-1], expected_text="list[str]") - - -def func3(): - v1: dict[str, int] = {} - - reveal_type(v1["x1"], expected_text="int") - v1["x1"] = 3 - reveal_type(v1["x1"], expected_text="Literal[3]") - - v1[f"x2"] = 5 - reveal_type(v1["x2"], expected_text="int") - - v1 = {} - reveal_type(v1["x1"], expected_text="int") - - v2: dict[str, dict[str, int]] = {} - - reveal_type(v2["y1"]["y2"], expected_text="int") - v2["y1"]["y2"] = 3 - reveal_type(v2["y1"]["y2"], expected_text="Literal[3]") - v2["y1"] = {} - reveal_type(v2["y1"]["y2"], expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowing8.py b/packages/vipeye-internal/src/tests/samples/typeNarrowing8.py deleted file mode 100644 index 878dee34..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowing8.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests type narrowing for expressions that include -# assignment expressions (walrus operators). - - -def func1(v1: int | str, v2: str | None) -> None: - if isinstance(x1 := v1, str): - reveal_type(x1, expected_text="str") - - if (x2 := v2) == "hello": - reveal_type(x2, expected_text="Literal['hello']") - - if x2 := v2: - reveal_type(x2, expected_text="str") - - -class A: - val: bool | None - - def __init__(self, val: bool | None) -> None: - self.val = val - - -def func2(): - if (v1 := A(True)).val: - reveal_type(v1.val, expected_text="Literal[True]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingAny1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingAny1.py deleted file mode 100644 index 833ab9a3..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingAny1.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the type analyzer's type narrowing logic for -# Any and Unknown types with "is None" checks. - -# viper: strict - -from typing import Any, reveal_type - - -def test_any_narrowing(x: Any): - if x is None: - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="Any") - - -def test_any_equality_narrowing(x: Any): - # Test == None operator (narrowTypeForIsNone handles both is and ==) - if x == None: - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="Any") - - -def test_any_list_comprehension(xs: list[Any]): - filtered = [x for x in xs if isinstance(x, str) or x is None] - reveal_type(filtered, expected_text="list[str | None]") - - -def test_unknown_narrowing(x: int): - # Create an Unknown type - u = x.unknown_method() # type: ignore - reveal_type(u, expected_text="Unknown") - - if u is None: - reveal_type(u, expected_text="None") - else: - reveal_type(u, expected_text="Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingAssert1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingAssert1.py deleted file mode 100644 index 791f4a6e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingAssert1.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample exercises the type analyzer's type narrowing -# logic for assert statements. - -condition: bool = True - - -def func1(a: str | int) -> int: - if condition: - # This should generate an error because - # a could be a str. - return a - - assert isinstance(a, int) - - return a - - -def func2(a: str | int) -> int: - # Test the form of "assert" that includes a message string. - assert isinstance(a, int), "Message" - return a diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingCallable1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingCallable1.py deleted file mode 100644 index 9126c825..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingCallable1.py +++ /dev/null @@ -1,85 +0,0 @@ -# This sample tests the type engine's narrowing logic for -# callable expressions. - -from typing import Callable, Optional, TypeVar, Union - - -class CallableObj: - def __call__(self, val: int): - return 3 - - -def f(a: int) -> Union[Callable[[int], int], type[int], CallableObj, int]: - if a == 0: - - def h(b: int): - return 3 - - return h - elif a < 40: - return 2 - else: - return int - - -q = f(45) -if callable(q): - w = q(3) - -if not callable(q): - a = q + 3 - - -def g(a: Optional[Callable[[int], int]]): - if callable(a): - a(3) - - -_T1 = TypeVar("_T1", bound=int) - - -def test1(arg: Union[_T1, Callable[[], _T1]]) -> _T1: - if callable(arg): - return arg() - return arg - - -class ClassA: - def bar(self) -> None: - pass - - -def test2(o: ClassA) -> None: - if callable(o): - reveal_type(o, expected_text="") - - # This should generate an error - o.foo() - o.bar() - r1 = o(1, 2, 3) - reveal_type(r1, expected_text="Unknown") - else: - o.bar() - - # This should generate an error - o(1, 2, 3) - - -_T2 = TypeVar("_T2", int, str, Callable[[], int], Callable[[], str]) - - -def test3(v: _T2) -> Union[_T2, int, str]: - if callable(v): - reveal_type(v, expected_text="(() -> int) | (() -> str)") - reveal_type(v(), expected_text="int* | str*") - return v() - else: - reveal_type(v, expected_text="int* | str*") - return v - - -def test4(v: type[int] | object): - if callable(v): - reveal_type(v, expected_text="type[int] | ((...) -> object)") - else: - reveal_type(v, expected_text="object") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingEnum1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingEnum1.py deleted file mode 100644 index 852c6e86..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingEnum1.py +++ /dev/null @@ -1,70 +0,0 @@ -# This sample tests exhaustive type narrowing for enums -# and the use of "Never" and "NoReturn". - -from enum import Enum, Flag -from typing import Literal, NoReturn, Union - - -class SomeEnum(Enum): - value1 = 1 - value2 = 2 - value3 = 3 - - -def assert_never(x: NoReturn) -> NoReturn: - """Used to cause Mypy to catch impossible cases.""" - # https://github.com/python/mypy/issues/6366#issuecomment-560369716 - assert False, "Unhandled type: {}".format(type(x).__name__) - - -def func1(a: SomeEnum): - if a == SomeEnum.value1: - pass - elif a == SomeEnum.value2: - pass - elif a == SomeEnum.value3: - pass - else: - assert_never(a) - - -def func2(val: Literal["a", "b"]): - if val == "a": - pass - elif val == "b": - pass - else: - assert_never(val) - - -def func3(val: Union[str, int]): - if isinstance(val, str): - pass - elif isinstance(val, int): - pass - else: - assert_never(val) - - -def func4(val: Union[str, int]) -> Union[str, int]: - if isinstance(val, str): - return val - elif isinstance(val, int): - return val - else: - # Even though "val" is a Never type at this - # point, it should be assignable to Union[str, int] - # because Never is assignable to any type. - return val - - -class MyFlags(Flag): - V1 = 1 - V2 = 2 - - -def func5(val: MyFlags): - if val == MyFlags.V1 or val == MyFlags.V2: - return - - reveal_type(val, expected_text="MyFlags") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingEnum2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingEnum2.py deleted file mode 100644 index 597af89c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingEnum2.py +++ /dev/null @@ -1,77 +0,0 @@ -# This sample tests the type narrowing logic for -# enum values or False/True that are compared using the -# "is" and "is not" operators. - -from enum import Enum -from typing import Literal, NoReturn, Union - - -class SomeEnum(Enum): - VALUE1 = 1 - VALUE2 = 2 - - -def assert_never(val: NoReturn): ... - - -def func1(a: SomeEnum): - if a is SomeEnum.VALUE1: - pass - elif a is SomeEnum.VALUE2: - pass - else: - assert_never(a) - - -def func2(a: SomeEnum): - if a is SomeEnum.VALUE1: - pass - else: - # This should generate an error because - # a hasn't been narrowed to Never. - assert_never(a) - - -def func3(a: SomeEnum): - if not a is not SomeEnum.VALUE1: - pass - elif not a is not SomeEnum.VALUE2: - pass - else: - assert_never(a) - - -def func4(a: SomeEnum): - if not a is not SomeEnum.VALUE1: - pass - else: - # This should generate an error because - # a hasn't been narrowed to Never. - assert_never(a) - - -def func5(a: Union[str, Literal[False]]) -> str: - if a is False: - return "no" - return a - - -def func6(a: Union[str, Literal[False]]) -> str: - if a is not False: - return a - return "no" - - -def func7(a: Union[str, bool]) -> str: - if a is False: - return "False" - elif a is True: - return "True" - return a - - -def func8(a: object): - if a is SomeEnum.VALUE1 or a is SomeEnum.VALUE2: - reveal_type(a, expected_text="Literal[SomeEnum.VALUE1, SomeEnum.VALUE2]") - else: - reveal_type(a, expected_text="object") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingFalsy1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingFalsy1.py deleted file mode 100644 index d6546113..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingFalsy1.py +++ /dev/null @@ -1,244 +0,0 @@ -# This sample tests type narrowing for falsey and truthy values. - -from typing import ( - AnyStr, - Iterable, - Literal, - NamedTuple, - NotRequired, - TypeVar, - TypedDict, -) -from enum import Enum, IntEnum - - -class A: ... - - -class B: - def __bool__(self) -> bool: ... - - -class C: - def __bool__(self) -> Literal[False]: ... - - -class D: - def __bool__(self) -> Literal[True]: ... - - -def func1(x: int | list[int] | A | B | C | D | None) -> None: - if x: - reveal_type(x, expected_text="int | list[int] | A | B | D") - else: - reveal_type(x, expected_text="list[int] | B | C | Literal[0] | None") - - -def func2(maybe_int: int | None): - if bool(maybe_int): - reveal_type(maybe_int, expected_text="int") - else: - reveal_type(maybe_int, expected_text="Literal[0] | None") - - -def func3_1(maybe_a: A | None): - if bool(maybe_a): - reveal_type(maybe_a, expected_text="A") - else: - reveal_type(maybe_a, expected_text="None") - - -def func3_2(maybe_a: A | None): - if bool(maybe_a): - reveal_type(maybe_a, expected_text="A") - else: - reveal_type(maybe_a, expected_text="None") - - -def func4(val: Iterable[int]) -> None: - if val: - reveal_type(val, expected_text="Iterable[int]") - else: - reveal_type(val, expected_text="Iterable[int]") - - -def func5(val: tuple[int]) -> None: - if val: - reveal_type(val, expected_text="tuple[int]") - else: - reveal_type(val, expected_text="Never") - - -def func6(val: tuple[int, ...]) -> None: - if val: - reveal_type(val, expected_text="tuple[int, ...]") - else: - reveal_type(val, expected_text="tuple[int, ...]") - - -def func7(val: tuple[()]) -> None: - if val: - reveal_type(val, expected_text="Never") - else: - reveal_type(val, expected_text="tuple[()]") - - -class NT1(NamedTuple): - val: int - - -def func8(val: NT1) -> None: - if val: - reveal_type(val, expected_text="NT1") - else: - reveal_type(val, expected_text="Never") - - -class NT2(NT1): - pass - - -def func9(val: NT2) -> None: - if val: - reveal_type(val, expected_text="NT2") - else: - reveal_type(val, expected_text="Never") - - -class E: - def __init__(self, value: int = 0) -> None: - self.value = value - - def __bool__(self) -> bool: - return self.value >= 0 - - def method(self) -> None: - while not self: - reveal_type(self, expected_text="Self@E") - self.value += 1 - - -def func10(val: AnyStr | None): - return 1 - - -def func11(val: AnyStr | None): - assert val - reveal_type(val, expected_text="AnyStr@func11") - - -T = TypeVar("T") - - -def func12(val: T) -> T: - if val: - reveal_type(val, expected_text="T@func12") - else: - reveal_type(val, expected_text="T@func12") - - return val - - -class Enum1(Enum): - A = 0 - - -class Enum2(Enum): - A = 0 - - def __bool__(self) -> Literal[False]: - return False - - -class Enum3(IntEnum): - A = 0 - B = 1 - - -def func13(x: Literal[Enum1.A]): - if x: - reveal_type(x, expected_text="Literal[Enum1.A]") - else: - reveal_type(x, expected_text="Never") - - -def func14(x: Enum1): - if x: - reveal_type(x, expected_text="Enum1") - else: - reveal_type(x, expected_text="Never") - - -def func15(x: Literal[Enum2.A]): - if x: - reveal_type(x, expected_text="Never") - else: - reveal_type(x, expected_text="Literal[Enum2.A]") - - -def func16(x: Enum2): - if x: - reveal_type(x, expected_text="Never") - else: - reveal_type(x, expected_text="Enum2") - - -def func17(x: Enum3): - if x: - reveal_type(x, expected_text="Enum3") - else: - reveal_type(x, expected_text="Enum3") - - -def func18(x: Literal[Enum3.A], y: Literal[Enum3.B]): - if x: - reveal_type(x, expected_text="Never") - else: - reveal_type(x, expected_text="Literal[Enum3.A]") - - if y: - reveal_type(y, expected_text="Literal[Enum3.B]") - else: - reveal_type(y, expected_text="Never") - - -class TD1(TypedDict): - d1: int - - -class TD2(TypedDict): - d1: NotRequired[int] - - -class TD3(TypedDict): - pass - - -def func19(v1: TD1 | None, v2: TD2 | None, v3: TD3 | None): - if v1: - reveal_type(v1, expected_text="TD1") - else: - reveal_type(v1, expected_text="None") - - if v2: - reveal_type(v2, expected_text="TD2") - else: - reveal_type(v2, expected_text="TD2 | None") - - if v2 is not None: - if v2: - reveal_type(v2, expected_text="TD2") - else: - reveal_type(v2, expected_text="TD2") - - v2["d1"] = 1 - - if v2: - reveal_type(v2, expected_text="TD2") - else: - reveal_type(v2, expected_text="Never") - - if v3: - reveal_type(v3, expected_text="TD3") - else: - reveal_type(v3, expected_text="TD3 | None") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIn1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIn1.py deleted file mode 100644 index de42085d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIn1.py +++ /dev/null @@ -1,226 +0,0 @@ -# This sample tests type narrowing for the "in" operator. - -from typing import ( - Any, - Callable, - Generic, - Literal, - LiteralString, - ParamSpec, - TypeVar, - TypedDict, -) -import random - - -def func0(x: str | None, y: int | str): - if random.random() < 0.5: - x = None - y = 1 - else: - x = "2" - y = "2" - - if x in ["2"]: - reveal_type(x, expected_text="Literal['2']") - - if y in [1]: - reveal_type(y, expected_text="Literal[1]") - - -def func1(x: int | str | None, y: Literal[1, 2, "b"], b: int): - if x in (1, 2, "a"): - reveal_type(x, expected_text="Literal[1, 2, 'a']") - - if x in (1, "2"): - reveal_type(x, expected_text="Literal[1, '2']") - - if x in (1, None): - reveal_type(x, expected_text="Literal[1] | None") - - if x in (1, b, "a"): - reveal_type(x, expected_text="int | Literal['a']") - - if y in (1, b, "a"): - reveal_type(y, expected_text="Literal[1, 2]") - - if y in (1, "a"): - reveal_type(y, expected_text="Literal[1]") - - if y in (1, "b"): - reveal_type(y, expected_text="Literal[1, 'b']") - - -def func2(a: Literal[1, 2, 3]): - x = (1, 2) - if a in x: - reveal_type(a, expected_text="Literal[1, 2]") - else: - reveal_type(a, expected_text="Literal[3]") - - -def func3(val: str | None, container: frozenset[str]): - if val in container: - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="str | None") - - -def func4(val: str | None, container: list[str]): - if val not in container: - reveal_type(val, expected_text="str | None") - else: - reveal_type(val, expected_text="str") - - -def func5(x: str | None, y: int | None, z: dict[str, str]): - if x in z: - reveal_type(x, expected_text="str") - else: - reveal_type(x, expected_text="str | None") - - if y not in z: - reveal_type(y, expected_text="int | None") - else: - reveal_type(y, expected_text="Never") - - -def func6(x: type): - if x in (str, int, float, bool): - reveal_type(x, expected_text="type[str] | type[int] | type[float] | type[bool]") - else: - reveal_type(x, expected_text="type") - - -def func7(x: object | bytes, y: str, z: int): - if x in (y, z): - reveal_type(x, expected_text="object") - else: - reveal_type(x, expected_text="object | bytes") - reveal_type(x, expected_text="object | bytes") - - -def func8(x: object): - if x in ("a", "b", 2, None): - reveal_type(x, expected_text="Literal['a', 'b', 2] | None") - - -def func9(x: Literal["A", "B", "C", None, True]): - if x in (None, "B", True): - reveal_type(x, expected_text="Literal['B', True] | None") - else: - reveal_type(x, expected_text="Literal['A', 'C']") - if x not in ("A", "C"): - reveal_type(x, expected_text="Never") - else: - reveal_type(x, expected_text="Literal['A', 'C']") - - if x in ("A", "B"): - reveal_type(x, expected_text="Literal['B', 'A']") - else: - reveal_type(x, expected_text="Literal[True, 'C'] | None") - - -def func10(x: Literal["A", "B"], y: tuple[Literal["A"], ...]): - if x in y: - reveal_type(x, expected_text="Literal['A']") - else: - reveal_type(x, expected_text="Literal['A', 'B']") - - -class TD1(TypedDict): - x: str - - -class TD2(TypedDict): - y: str - - -T1 = TypeVar("T1", TD1, TD2) - - -def func12(v: T1): - if "x" in v: - # This should technically be TD1* | TD2*, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(v, expected_text="TD1*") - # reveal_type(v, expected_text="TD1* | TD2*") - else: - reveal_type(v, expected_text="TD2*") - - -P = ParamSpec("P") - - -class Container(Generic[P]): - def __init__(self, func: Callable[P, str]) -> None: - self.func = func - - def __call__(self, *args: P.args, **kwargs: P.kwargs) -> str: - if "data" in kwargs: - raise ValueError("data is not allowed in kwargs") - - return self.func(*args, **kwargs) - - -T13 = TypeVar("T13") - - -def func13(x: type[T13]) -> type[T13]: - if x in (str, int, float): - reveal_type(x, expected_text="type[str]* | type[int]* | type[float]*") - - return x - - -def func14(x: str, y: dict[Any, Any]): - if x in y: - reveal_type(x, expected_text="str") - - -def func15(x: Any, y: dict[str, str]): - if x in y: - reveal_type(x, expected_text="Any") - - -def func16(x: int, y: list[Literal[0, 1]]): - if x in y: - reveal_type(x, expected_text="Literal[0, 1]") - - -def func17(x: Literal[-1, 0], y: list[Literal[0, 1]]): - if x in y: - reveal_type(x, expected_text="Literal[0]") - - -def func18(x: Literal[0, 1, 2], y: list[Literal[0, 1]]): - if x in y: - reveal_type(x, expected_text="Literal[0, 1]") - - -def func19(x: float, y: list[int]): - if x in y: - reveal_type(x, expected_text="float") - - -def func20(x: float, y: list[Literal[0, 1]]): - if x in y: - reveal_type(x, expected_text="Literal[0, 1]") - - -def func21(x: int, y: list[Literal[0, True]]): - if x in y: - reveal_type(x, expected_text="Literal[0, True]") - - -def func22(x: bool, y: list[Literal[0, 1]]): - if x in y: - reveal_type(x, expected_text="bool") - - -def func23[T: LiteralString](x: str, y: tuple[T, ...]) -> T: - if x in y: - return x - raise ValueError(f"Invalid value {x!r}") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIn2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIn2.py deleted file mode 100644 index 2810c553..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIn2.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests type narrowing for Enums using the "in" operator. - -import enum - - -class MyEnum(enum.Enum): - A = enum.auto() - B = enum.auto() - C = enum.auto() - - -def func1(x: MyEnum): - if x is MyEnum.C: - return - elif x in (MyEnum.A, MyEnum.B): - reveal_type(x, expected_text="Literal[MyEnum.A, MyEnum.B]") - else: - reveal_type(x, expected_text="Never") - - -def func2(x: MyEnum): - if x in (MyEnum.A, MyEnum.B): - reveal_type(x, expected_text="Literal[MyEnum.A, MyEnum.B]") - else: - reveal_type(x, expected_text="Literal[MyEnum.C]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsClass1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsClass1.py deleted file mode 100644 index 71633b92..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsClass1.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests type narrowing for conditional -# statements of the form X is or X is not . - -from typing import Any, TypeVar, final - - -@final -class A: ... - - -@final -class B: ... - - -class C: ... - - -def func1(x: type[A] | type[B] | None | int): - if x is A: - reveal_type(x, expected_text="type[A]") - else: - reveal_type(x, expected_text="type[B] | int | None") - - -def func2(x: type[A] | type[B] | None | int, y: type[A]): - if x is not y: - reveal_type(x, expected_text="type[B] | int | None") - else: - reveal_type(x, expected_text="type[A]") - - -def func3(x: type[A] | type[B] | Any): - if x is A: - reveal_type(x, expected_text="type[A]") - else: - reveal_type(x, expected_text="type[B] | Any") - - -def func4(x: type[A] | type[B] | type[C]): - if x is C: - reveal_type(x, expected_text="type[C]") - else: - reveal_type(x, expected_text="type[A] | type[B] | type[C]") - - -T = TypeVar("T") - - -def func5(x: type[A] | type[B] | type[T]) -> type[A] | type[B] | type[T]: - if x is A: - reveal_type(x, expected_text="type[A] | type[A]*") - else: - reveal_type(x, expected_text="type[B] | type[T@func5]") - - return x - - -def func6(x: type): - if x is str: - reveal_type(x, expected_text="type[str]") - else: - reveal_type(x, expected_text="type") - - -def func7(x: type[A | B]): - if x is A: - reveal_type(x, expected_text="type[A]") - else: - reveal_type(x, expected_text="type[B]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsEllipsis1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsEllipsis1.py deleted file mode 100644 index 910e72ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsEllipsis1.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the type analyzer's type narrowing logic for -# conditions of the form "X is ...", "X is not ...", -# "X == .." and "X != ...". - -import types -from typing import Any, TypeVar - -_T = TypeVar("_T", str, types.EllipsisType) - - -def func1(val: int | ellipsis): - if val is not ...: - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="EllipsisType") - - -def func2(val: _T): - if val is ...: - reveal_type(val, expected_text="EllipsisType*") - else: - reveal_type(val, expected_text="str*") - - -def func3(val: int | types.EllipsisType): - if val != ...: - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="EllipsisType") - - -def func4(val: int | ellipsis): - if not val == ...: - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="EllipsisType") - - -def func5(val: object): - if val is ...: - reveal_type(val, expected_text="EllipsisType") - else: - reveal_type(val, expected_text="object") - - -def func6(val: Any | types.EllipsisType): - if val is not ...: - reveal_type(val, expected_text="Any") - else: - reveal_type(val, expected_text="EllipsisType") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone1.py deleted file mode 100644 index 258d6f68..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone1.py +++ /dev/null @@ -1,115 +0,0 @@ -# This sample tests the type analyzer's type narrowing logic for -# conditions of the form "X is None", "X is not None", -# "X == None" and "X != None". - -# viper: strict, reportUnusedVariable=false - -from typing import Any, Literal, Protocol, Self, TypeVar - - -def func1(x: int | None): - if x is not None: - x.bit_length() - - if x != None: - x.bit_length() - - if x is None: - pass - else: - x.bit_length() - - if x == None: - pass - else: - x.bit_length() - - -_T1 = TypeVar("_T1", None, str) - - -def func2(val: _T1) -> _T1: - if val is not None: - reveal_type(val, expected_text="str*") - return val - else: - reveal_type(val, expected_text="None*") - return val - - -def func3(x: object): - if x is None: - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="object") - - -_T2 = TypeVar("_T2") - - -def func4(x: _T2) -> _T2: - if x is None: - reveal_type(x, expected_text="None*") - raise ValueError() - else: - reveal_type(x, expected_text="_T2@func4") - return x - - -def func5(x: Any | None): - if x is None: - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="Any") - - -def func6(x: Any | object | None): - if x is None: - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="Any | object") - - -class NoneProto(Protocol): - def __bool__(self) -> Literal[False]: ... - - -def func7(x: NoneProto | None): - if x is None: - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="NoneProto") - - -_T3 = TypeVar("_T3", bound=None | int) - - -def func8(x: _T3) -> _T3: - if x is None: - reveal_type(x, expected_text="None*") - else: - reveal_type(x, expected_text="int*") - return x - - -_T4 = TypeVar("_T4") - - -def func9(value: type[_T4] | None): - if value is None: - reveal_type(value, expected_text="None") - else: - reveal_type(value, expected_text="type[_T4@func9]") - - -class A: - def __init__(self, parent: Self | None) -> None: - self.parent = parent - - def get_depth(self) -> int: - current: Self | None = self - count = 0 - while current is not None: - count += 1 - current = current.parent - return count - 1 diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone2.py deleted file mode 100644 index 181de12a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNone2.py +++ /dev/null @@ -1,8 +0,0 @@ -# This sample tests type narrowing for conditional -# statements of the form X is None or X is not None -# where X is an assignment expression. - -# viper: strict - -i = {"a": "", "b": None} -dict_comp = {key: w.strip() if (w := i[key]) is not None else "" for key in i} diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple1.py deleted file mode 100644 index d9dec6cc..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple1.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests the type narrowing case for unions of tuples -# where one or more of the entries is tested against type None. - -from typing import TypeVar, Tuple, Union - -_T1 = TypeVar("_T1") - - -def func1(a: Union[Tuple[_T1, None], Tuple[None, str]]) -> Tuple[_T1, None]: - if a[1] is None: - reveal_type(a, expected_text="Tuple[_T1@func1, None]") - return a - else: - reveal_type(a, expected_text="Tuple[None, str]") - raise ValueError() - - -_T2 = TypeVar("_T2", bound=Union[None, int]) - - -def func2(a: Union[Tuple[_T2, None], Tuple[None, str]]): - if a[0] is None: - reveal_type(a, expected_text="Tuple[_T2@func2, None] | Tuple[None, str]") - else: - reveal_type(a, expected_text="Tuple[_T2@func2, None]") - - -_T3 = TypeVar("_T3", None, int) - - -def func3(a: Union[Tuple[_T3, None], Tuple[None, str]]): - if a[0] is None: - reveal_type(a, expected_text="Tuple[_T3@func3, None] | Tuple[None, str]") - else: - reveal_type(a, expected_text="Tuple[_T3@func3, None]") - - -def func4(a: Union[Tuple[Union[int, None]], Tuple[None, str]]): - if a[0] is None: - reveal_type(a, expected_text="Tuple[int | None] | Tuple[None, str]") - else: - reveal_type(a, expected_text="Tuple[int | None]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple2.py deleted file mode 100644 index 5a4c7b4b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsNoneTuple2.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the type narrowing case for unions of NamedTuples -# where one or more of the entries is tested against type None by index. - -from typing import NamedTuple - -IntFirst = NamedTuple( - "IntFirst", - [ - ("first", int), - ("second", None), - ], -) - -StrSecond = NamedTuple( - "StrSecond", - [ - ("first", None), - ("second", str), - ], -) - - -def func1(a: IntFirst | StrSecond) -> IntFirst: - if a[1] is None: - reveal_type(a, expected_text="IntFirst") - return a - else: - reveal_type(a, expected_text="StrSecond") - raise ValueError() - - -UnionFirst = NamedTuple( - "UnionFirst", - [ - ("first", None | int), - ("second", None), - ], -) - - -def func2(a: UnionFirst | StrSecond): - if a[0] is None: - reveal_type(a, expected_text="UnionFirst | StrSecond") - else: - reveal_type(a, expected_text="UnionFirst") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance1.py deleted file mode 100644 index 150e8ffe..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance1.py +++ /dev/null @@ -1,291 +0,0 @@ -# This sample exercises the type analyzer's isinstance type narrowing logic. - -from types import NoneType -from typing import ( - Any, - Generic, - Iterable, - Iterator, - Protocol, - Sized, - TypeVar, - Union, - runtime_checkable, -) - -S = TypeVar("S") -T = TypeVar("T") - - -class UnrelatedClass: - class_var1: int - - def __init__(self) -> None: - self.property: None = None - - -class UnrelatedSubclass(UnrelatedClass): - def __init__(self) -> None: - self.property2: None = None - - -class SuperClass: - class_var1: int - - def __init__(self) -> None: - self.property: None = None - - -class MyClass1(SuperClass): - class_var2: int - - def __init__(self) -> None: - self.property2: None = None - - -class MyClass2(SuperClass): - def __init__(self) -> None: - self.property2: None = None - - -def f(instance: Union[SuperClass, UnrelatedClass], a: Any) -> None: - if isinstance(instance, (MyClass1, UnrelatedSubclass, a)): - print(instance.property) - - # This should generate two errors: - # 'property2' is not a known member of 'SuperClass' - # 'property2' is not a known member of 'UnrelatedClass' - print(instance.property2) - else: - print(instance.property) - - # This should generate two errors: - # 'property2' is not a known member of 'SuperClass' - # 'property2' is not a known member of 'UnrelatedClass' - print(instance.property2) - - -def g(cls: Union[type[SuperClass], type[UnrelatedClass]], a: Any) -> None: - if issubclass(cls, (MyClass1, UnrelatedSubclass, a)): - print(cls.class_var1) - - # This should generate two errors: - # 'property2' is not a known member of 'SuperClass' - # 'property2' is not a known member of 'UnrelatedClass' - print(cls.class_var2) - else: - print(cls.class_var1) - - # This should generate two errors: - # 'property2' is not a known member of 'SuperClass' - # 'property2' is not a known member of 'UnrelatedClass' - print(cls.class_var2) - - -# This code should analyze without any errors. -class TestClass1: - def __init__(self) -> None: - self.property = True - - -class TestClass2(TestClass1): - pass - - -def func1(instance: TestClass2) -> None: - # Although it's redundant for code to check for either - # TestClass1 or TestClass2, the analyzer should be fine with it. - if isinstance(instance, TestClass2): - print(instance.property) - - if isinstance(instance, TestClass1): - print(instance.property) - - -def func2(val: Union[int, None, str]) -> int | None: - return None if isinstance((z := val), str) else z - - -# Test the special-case handling of isinstance with a -# "type" class. -def func3(ty: type[int]) -> type[int]: - assert isinstance(ty, (type, str)) - return ty - - -def func4(ty: type[int]) -> type[int]: - assert not isinstance(ty, str) - return ty - - -def func5(ty: type[T]) -> type[T]: - assert isinstance(ty, (type, str)) - return ty - - -def func6(ty: type[T]) -> type[T]: - assert not isinstance(ty, str) - return ty - - -def func6_2(ty: type[int] | int): - if isinstance(ty, type): - reveal_type(ty, expected_text="type[int]") - else: - reveal_type(ty, expected_text="int") - - -def func6_3(ty: type): - if issubclass(ty, str): - reveal_type(ty, expected_text="type[str]") - else: - reveal_type(ty, expected_text="type[Unknown]") - - -def func6_4(ty: Any): - if issubclass(ty, str): - reveal_type(ty, expected_text="type[str]") - else: - reveal_type(ty, expected_text="Any") - - -# Test the handling of protocol classes that support runtime checking. -def func7(a: Union[list[int], int]): - if isinstance(a, Sized): - reveal_type(a, expected_text="list[int]") - else: - reveal_type(a, expected_text="int") - - -# Test handling of member access expressions whose types change based -# on isinstance checks. - - -class Base1: ... - - -class Sub1_1(Base1): - value: str - - -class Sub1_2(Base1): - value: Base1 - - -def handler(node: Base1) -> Any: - if isinstance(node, Sub1_1): - reveal_type(node.value, expected_text="str") - elif isinstance(node, Sub1_2): - reveal_type(node.value, expected_text="Base1") - if isinstance(node.value, Sub1_1): - reveal_type(node.value, expected_text="Sub1_1") - - -def func8a(a: int | list[int] | dict[str, int] | None): - if isinstance(a, (str, (int, list, type(None)))): - reveal_type(a, expected_text="int | list[int] | None") - else: - reveal_type(a, expected_text="dict[str, int]") - - -def func8b(a: int | list[int] | dict[str, int] | None): - if isinstance(a, str | int | list | type(None)): - reveal_type(a, expected_text="int | list[int] | None") - else: - reveal_type(a, expected_text="dict[str, int]") - - -TA1 = str | int | list | None - - -def func8c(a: int | list[int] | dict[str, int] | None): - if isinstance(a, TA1): - reveal_type(a, expected_text="int | list[int] | None") - else: - reveal_type(a, expected_text="dict[str, int]") - - -def func9(a: int | None): - if not isinstance(a, NoneType): - reveal_type(a, expected_text="int") - else: - reveal_type(a, expected_text="None") - - -class Base2(Generic[S, T]): - pass - - -class Sub2(Base2[T, T]): - pass - - -def func10(val: Sub2[str] | Base2[str, float]): - if isinstance(val, Sub2): - reveal_type(val, expected_text="Sub2[str] | Sub2[str | float]") - - -@runtime_checkable -class Proto1(Protocol): - def f0(self, /) -> None: ... - - -@runtime_checkable -class Proto2(Proto1, Protocol): - def f1(self, /) -> None: ... - - -def func11(x: Proto1): - if isinstance(x, Proto2): - reveal_type(x, expected_text="Proto2") - else: - reveal_type(x, expected_text="Proto1") - - -TA2 = list["TA3"] | dict[str, "TA3"] -TA3 = str | TA2 - - -def func12(x: TA3) -> None: - if isinstance(x, dict): - reveal_type(x, expected_text="dict[str, str | list[TA3] | dict[str, TA3]]") - else: - reveal_type(x, expected_text="str | list[str | list[TA3] | dict[str, TA3]]") - - -def func13(x: object | type[object]) -> None: - if isinstance(x, object): - reveal_type(x, expected_text="object | type[object]") - - -def func14(x: Iterable[T]): - if isinstance(x, Iterator): - reveal_type(x, expected_text="Iterator[T@func14]") - - -class Base15(Generic[T]): - value: T - - -class Child15(Base15[int]): - value: int - - -def func15(x: Base15[T]): - if isinstance(x, Child15): - # This should generate an error. It's here just to ensure that - # this code branch isn't marked unreachable. - reveal_type(x, expected_text="Never") - - reveal_type(x, expected_text="Child15") - reveal_type(x.value, expected_text="int") - - -def func16(x: Any): - if isinstance(x, (int, int)): - reveal_type(x, expected_text="int") - - -def func17(x: Any): - if isinstance(x, (Union[int, int])): - reveal_type(x, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance10.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance10.py deleted file mode 100644 index adeadf3e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance10.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where an isinstance type guard is used -# with a dynamic set of types. - -SOME_TYPES_L: list[type[object]] = [int, float] -SOME_TYPES: tuple[type[object], ...] = tuple(SOME_TYPES_L) - - -def check_object(obj: object): - if isinstance(obj, SOME_TYPES): - reveal_type(obj, expected_text="object") - return - reveal_type(obj, expected_text="object") - - if isinstance(obj, list): - reveal_type(obj, expected_text="list[Unknown]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance11.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance11.py deleted file mode 100644 index 7b065b8f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance11.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where the class type passed as the second -# argument to isinstance is incomplete the first time the type guard -# is evaluated because it's in an loop. - - -class X: - pass - - -class Y: - p: type - - -def func1(xs: list[X | Y]) -> None: - for x in xs: - if not isinstance(x, X): - if x.p == X: - pass diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance12.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance12.py deleted file mode 100644 index 80a435a6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance12.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests the case where a symbol with type `|Any` -# is narrowed using an `isinstance` type guard. - -from typing import Any - - -def func1(val: Any): - if isinstance(val, str): - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="Any") - - -def func2(val: str): - if isinstance(val, str): - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="Never") - - -def func3(val: str | int): - if isinstance(val, str): - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="int") - - -def func4(val: str | Any): - if isinstance(val, str): - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="Any") - - -def func5(val: str | int | Any): - if isinstance(val, str): - reveal_type(val, expected_text="str") - else: - reveal_type(val, expected_text="int | Any") - - -def func6(val: list[str] | Any): - if isinstance(val, list): - reveal_type(val, expected_text="list[str] | list[Unknown]") - else: - reveal_type(val, expected_text="Any") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance13.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance13.py deleted file mode 100644 index beb9870c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance13.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where isinstance type narrowing is used -# with a protocol class that supports runtime checking. - -# viper: reportUnnecessaryIsInstance=true - -from typing import Any, Iterable, Sized - - -def func1(v: Any) -> bool: - if isinstance(v, Iterable): - reveal_type(v, expected_text="Iterable[Unknown]") - if isinstance(v, Sized): - reveal_type(v, expected_text="") - return True - return False diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance14.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance14.py deleted file mode 100644 index 4e8613f0..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance14.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the isinstance narrowing when the list -# of classes includes a type defined by a type variable. - -from typing import Any, TypeVar - -T = TypeVar("T") - - -def func1(cls: type[T], obj: Any) -> T: - assert isinstance(obj, cls) - reveal_type(obj, expected_text="T@func1") - return obj - - -v1 = func1(int, 3) -reveal_type(v1, expected_text="int") - - -def func2(klass: type[T], obj: T | int) -> T: - assert isinstance(obj, klass) - reveal_type(obj, expected_text="object*") - return obj - - -v2 = func2(str, 3) -reveal_type(v2, expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance15.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance15.py deleted file mode 100644 index 1562a3f4..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance15.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests that the negative filtering for the 'isinstance' -# narrowing logic properly preserves a TypeVar. - -from typing import TypeVar, Generic - - -class Operator: ... - - -OpType = TypeVar("OpType", bound=Operator) - - -class BasePipeline(Operator, Generic[OpType]): - def __init__( - self, - step: OpType, - ) -> None: - if isinstance(step, BasePipeline): - reveal_type(step, expected_text="BasePipeline[Unknown]*") - else: - reveal_type(step, expected_text="Operator*") - - -T1 = TypeVar("T1", int, str) - - -def do_nothing1(x: T1) -> T1: - if isinstance(x, int): - return x - return x - - -T2 = TypeVar("T2") - - -def func2(arg: T2) -> T2: - if isinstance(arg, str): - reveal_type(arg, expected_text="str*") - - reveal_type(arg, expected_text="str* | object*") - return arg diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance16.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance16.py deleted file mode 100644 index a7b7281b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance16.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests isinstance and issubclass type narrowing -# based on cls and self parameters. - - -class ClassA: - @classmethod - def bar(cls, other: type): - if issubclass(other, cls): - reveal_type(other, expected_text="type[Self@ClassA]") - - if issubclass(other, (int, cls)): - reveal_type(other, expected_text="type[Self@ClassA] | type[int]") - - def baz(self, other: object): - if isinstance(other, type(self)): - reveal_type(other, expected_text="Self@ClassA") - - if isinstance(other, (int, type(self))): - reveal_type(other, expected_text="Self@ClassA | int") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance17.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance17.py deleted file mode 100644 index 0f49cd08..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance17.py +++ /dev/null @@ -1,79 +0,0 @@ -# This sample tests basic type narrowing behavior for -# the isinstance call. - -from types import NoneType -from typing import Any, TypedDict - - -def func1(x: list[str] | int): - if isinstance(x, list): - reveal_type(x, expected_text="list[str]") - else: - reveal_type(x, expected_text="int") - - -def func2(x: Any): - if isinstance(x, list): - reveal_type(x, expected_text="list[Unknown]") - else: - reveal_type(x, expected_text="Any") - - -def func3(x): - if isinstance(x, list): - reveal_type(x, expected_text="list[Unknown]") - else: - reveal_type(x, expected_text="Unknown") - - -class SomeTypedDict(TypedDict): - name: str - - -def func4(x: int | SomeTypedDict): - if isinstance(x, dict): - reveal_type(x, expected_text="SomeTypedDict") - else: - reveal_type(x, expected_text="int") - - -def func5(x: int | str | complex): - if isinstance(x, (int, str)): - reveal_type(x, expected_text="int | str") - else: - reveal_type(x, expected_text="complex | float") - - -def func6(x: type[int] | type[str] | type[complex]): - if issubclass(x, (int, str)): - reveal_type(x, expected_text="type[int] | type[str]") - else: - reveal_type(x, expected_text="type[complex] | type[float]") - - -def func7(x: int | SomeTypedDict | None): - if isinstance(x, (dict, type(None))): - reveal_type(x, expected_text="SomeTypedDict | None") - else: - reveal_type(x, expected_text="int") - - -def func8(x: type[int] | type[SomeTypedDict] | type[None]): - if issubclass(x, (dict, type(None))): - reveal_type(x, expected_text="type[SomeTypedDict] | type[None]") - else: - reveal_type(x, expected_text="type[int]") - - -def func9(x: int | None): - if isinstance(x, NoneType): - reveal_type(x, expected_text="None") - else: - reveal_type(x, expected_text="int") - - -def func10(x: type[int] | type[None]): - if issubclass(x, NoneType): - reveal_type(x, expected_text="type[None]") - else: - reveal_type(x, expected_text="type[int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance18.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance18.py deleted file mode 100644 index e4c28874..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance18.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests the case where a filter (guard) type has a subtype -# relationship to the type of the variable being filtered but the -# type arguments sometimes mean that it cannot be a subtype. - -from typing import Generic, NamedTuple, TypeVar - -T = TypeVar("T") - - -class NT1(NamedTuple, Generic[T]): - pass - - -def func1(val: NT1[str] | tuple[int, int]): - if isinstance(val, NT1): - reveal_type(val, expected_text="NT1[str]") - else: - reveal_type(val, expected_text="tuple[int, int]") - - -class NT2(NamedTuple, Generic[T]): - a: T - b: str - - -def func2(val: NT2[str] | tuple[int, int]): - if isinstance(val, NT2): - reveal_type(val, expected_text="NT2[str]") - else: - reveal_type(val, expected_text="tuple[int, int]") - - -def func3(val: NT2[str] | tuple[int, str]): - if isinstance(val, NT2): - reveal_type(val, expected_text="NT2[str] | NT2[Unknown]") - else: - reveal_type(val, expected_text="tuple[int, str]") - - -class NT3(NamedTuple, Generic[T]): - a: T - b: T - - -def func4(val: NT3[str] | tuple[int, int]): - if isinstance(val, NT3): - reveal_type(val, expected_text="NT3[str] | NT3[Unknown]") - else: - reveal_type(val, expected_text="tuple[int, int]") - - -def func5(val: NT3[str] | tuple[str, str, str]): - if isinstance(val, NT3): - reveal_type(val, expected_text="NT3[str]") - else: - reveal_type(val, expected_text="tuple[str, str, str]") - - -def func6(val: NT3[str] | tuple[str, ...]): - if isinstance(val, NT3): - reveal_type(val, expected_text="NT3[str] | NT3[Unknown]") - else: - reveal_type(val, expected_text="tuple[str, ...]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance19.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance19.py deleted file mode 100644 index 050128d7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance19.py +++ /dev/null @@ -1,89 +0,0 @@ -# This sample tests the logic for narrowing a metaclass using an -# issubclass call. - -from abc import ABC, ABCMeta -from typing import Any, ClassVar, Iterable -from typing_extensions import reveal_type # viper: ignore[reportMissingModuleSource] - - -class Meta1(ABCMeta): - pass - - -class Parent1(ABC, metaclass=Meta1): - pass - - -class Child1(Parent1): - x: ClassVar[tuple[int, int]] = (0, 1) - - -def func1(m: Meta1) -> None: - if issubclass(m, Parent1): - reveal_type(m, expected_text="type[Parent1]") - else: - reveal_type(m, expected_text="Meta1") - - -def func2(m: Meta1) -> None: - if issubclass(m, Child1): - reveal_type(m, expected_text="type[Child1]") - else: - reveal_type(m, expected_text="Meta1") - - -def func3(m: ABCMeta) -> None: - if issubclass(m, Child1): - reveal_type(m, expected_text="type[Child1]") - else: - reveal_type(m, expected_text="ABCMeta") - - -def func4(m: ABCMeta) -> None: - if issubclass(m, (Parent1, Child1, int)): - reveal_type(m, expected_text="type[Parent1] | type[Child1]") - else: - reveal_type(m, expected_text="ABCMeta") - - -def func5(m: Meta1) -> None: - if issubclass(m, (Parent1, Child1)): - reveal_type(m, expected_text="type[Parent1] | type[Child1]") - else: - reveal_type(m, expected_text="Meta1") - - -def func6(m: Meta1, x: type[Any]) -> None: - if issubclass(m, x): - reveal_type(m, expected_text="Meta1") - else: - reveal_type(m, expected_text="Meta1") - - -def func7(m: Meta1, x: type[Parent1] | type[Child1]) -> None: - if issubclass(m, x): - reveal_type(m, expected_text="type[Parent1] | type[Child1]") - else: - reveal_type(m, expected_text="Meta1") - - -def func8(cls: type): - if isinstance(cls, Meta1): - reveal_type(cls, expected_text="Meta1") - else: - reveal_type(cls, expected_text="type") - - -class Meta2(type): - pass - - -class Class2(metaclass=Meta2): - pass - - -def func9(v: type[Class2] | Iterable[type[Class2]]): - if isinstance(v, Meta2): - reveal_type(v, expected_text="type[Class2]") - else: - reveal_type(v, expected_text="Iterable[type[Class2]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance2.py deleted file mode 100644 index 0b6d45e7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance2.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample verifies that type narrowing for isinstance works -# on "self" and other bound TypeVars. - - -from typing import Self, TypeVar - - -class ClassA: - def get_value(self) -> int: - if isinstance(self, ChildB): - return self.calculate() - return 7 - - -class ChildB(ClassA): - def calculate(self) -> int: - return 2 * 2 - - -TC = TypeVar("TC") - - -class ClassC: - @classmethod - def test(cls: type[TC], id: int | TC): - if isinstance(id, cls): - reveal_type(id, expected_text="object*") - else: - reveal_type(id, expected_text="int | object*") - - -TD = TypeVar("TD", bound="ClassD") - - -class ClassD: - @classmethod - def test(cls: type[TD], id: int | TD): - if isinstance(id, cls): - reveal_type(id, expected_text="ClassD*") - else: - reveal_type(id, expected_text="int | ClassD*") - - -class ClassE: - @classmethod - def test(cls: type[Self], id: int | Self): - if isinstance(id, cls): - reveal_type(id, expected_text="Self@ClassE") - else: - reveal_type(id, expected_text="int | ClassE*") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance20.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance20.py deleted file mode 100644 index 345fb62a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance20.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the case where an isinstance type narrowing is used -# with a generic class with a type parameter that has a default value. - -from typing import Generic -from typing_extensions import TypeVar # viper: ignore[reportMissingModuleSource] - - -T = TypeVar("T", bound=int, default=int) - - -class ClassA(Generic[T]): ... - - -def func1(obj: object): - if isinstance(obj, ClassA): - reveal_type(obj, expected_text="ClassA[Unknown]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance21.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance21.py deleted file mode 100644 index ad25dd61..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance21.py +++ /dev/null @@ -1,77 +0,0 @@ -# This sample tests the case where the filter type is a class object. - -# viper: reportMissingModuleSource=false - -from typing import Any -from typing_extensions import TypeIs - - -class Sentinel: - pass - - -def is_sentinel(value: object) -> TypeIs[type[Sentinel]]: ... - - -def _(a: dict[str, int] | type[Sentinel]): - if is_sentinel(a): - reveal_type(a, expected_text="type[Sentinel]") - else: - reveal_type(a, expected_text="dict[str, int]") - - -def is_str_type(typ: object) -> TypeIs[type[str]]: - return typ is str - - -def test_typevar[T](typ: type[T], val: T) -> None: - if is_str_type(typ): - reveal_type(typ, expected_text="type[str]*") - - -def func1(v: Sentinel | type[Sentinel]): - if isinstance(v, Sentinel): - reveal_type(v, expected_text="Sentinel") - else: - reveal_type(v, expected_text="type[Sentinel]") - - -class A: - pass - - -class B: - pass - - -def guard3(t: type[Any]) -> TypeIs[type[A]]: - return True - - -def func3(t: type[B]): - if guard3(t): - reveal_type(t, expected_text="type[]") - else: - reveal_type(t, expected_text="type[B]") - - -def guard4(t: Any) -> TypeIs[type[A]]: - return True - - -def func4(t: B): - if guard4(t): - reveal_type(t, expected_text="") - else: - reveal_type(t, expected_text="B") - - -class CParent: ... - - -class CChild(CParent): ... - - -def func5(val: CChild, t: type[CParent]): - if not isinstance(val, t): - reveal_type(val, expected_text="CChild") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance3.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance3.py deleted file mode 100644 index 75db837b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance3.py +++ /dev/null @@ -1,93 +0,0 @@ -# This sample tests the handling of isinstance and issubclass type -# narrowing in the case where there is no overlap between the -# value type and the test type. - -from typing import TypeVar, final - - -class A: - a_val: int - - -class B: - b_val: int - - -class C: - c_val: int - - -@final -class D: - d_val: int - - -def func1(val: A): - if isinstance(val, B): - val.a_val - val.b_val - - # This should generate an error - val.c_val - - reveal_type(val, expected_text="") - - if isinstance(val, C): - val.a_val - val.b_val - val.c_val - reveal_type(val, expected_text=" and C>") - - else: - val.a_val - - # This should generate an error - val.b_val - - reveal_type(val, expected_text="A") - - -def func2(val: type[A]): - if issubclass(val, B): - val.a_val - val.b_val - - # This should generate an error - val.c_val - - reveal_type(val, expected_text="type[]") - - if issubclass(val, C): - val.a_val - val.b_val - val.c_val - reveal_type( - val, expected_text="type[ and C>]" - ) - - else: - val.a_val - - # This should generate an error - val.b_val - - reveal_type(val, expected_text="type[A]") - - -_T1 = TypeVar("_T1", bound=A) - - -def func3(val: _T1) -> _T1: - if isinstance(val, B): - return val - return val - - -def func4(val: D): - if isinstance(val, A): - reveal_type(val, expected_text="Never") - - -def func5(val: type[int]): - if isinstance(val, str): - x: type = val diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance4.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance4.py deleted file mode 100644 index 505b8d9d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance4.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample checks the handling of callable types that are narrowed -# to a particular type using an isinstance type narrowing test. - -from typing import Callable, ParamSpec, Protocol, Union, runtime_checkable - -P = ParamSpec("P") - - -class ClassA: - def __call__(self, arg: int, bar: str) -> None: - raise NotImplementedError - - -@runtime_checkable -class ClassB(Protocol): - def __call__(self, arg: int) -> None: - raise NotImplementedError - - -@runtime_checkable -class ClassC(Protocol): - def __call__(self, arg: str) -> None: - raise NotImplementedError - - -def check_callable1(val: Union[Callable[[int, str], None], Callable[[int], None]]): - if isinstance(val, ClassA): - reveal_type(val, expected_text="ClassA") - else: - # This doesn't get narrowed because `ClassA` is not a runtime checkable protocol. - reveal_type(val, expected_text="((int, str) -> None) | ((int) -> None)") - - -def check_callable2(val: Union[Callable[[int, str], None], Callable[[int], None]]): - if isinstance(val, ClassB): - reveal_type(val, expected_text="((int, str) -> None) | ((int) -> None)") - else: - reveal_type(val, expected_text="Never") - - -def check_callable3(val: Union[Callable[[int, str], None], Callable[[int], None]]): - if isinstance(val, ClassC): - reveal_type(val, expected_text="((int, str) -> None) | ((int) -> None)") - else: - reveal_type(val, expected_text="Never") - - -def check_callable4(val: Union[type, Callable[[int], None]]): - if isinstance(val, type): - reveal_type(val, expected_text="type") - else: - reveal_type(val, expected_text="(int) -> None") - - -def check_callable5(fn: Callable[P, None]) -> None: - if isinstance(fn, ClassA): - reveal_type(fn, expected_text="ClassA") - else: - reveal_type(fn, expected_text="(**P@check_callable5) -> None") - - -def check_callable6(o: object | Callable[[int], int]): - if isinstance(o, Callable): - reveal_type(o, expected_text="((...) -> Unknown) | ((int) -> int)") - else: - reveal_type(o, expected_text="object") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance5.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance5.py deleted file mode 100644 index 4981b135..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance5.py +++ /dev/null @@ -1,66 +0,0 @@ -# This sample tests isinstance type narrowing when the class list -# includes "Callable". - -from typing import Callable, Sequence, TypeVar, final - - -class A: ... - - -class B: - def __call__(self, x: str) -> int: ... - - -class C: ... - - -class D(C): ... - - -TCall1 = TypeVar("TCall1", bound=Callable[..., int]) - - -def func1( - obj: Callable[[int, str], int] | list[int] | A | B | C | D | TCall1, -) -> TCall1 | None: - if isinstance(obj, (Callable, Sequence, C)): - reveal_type( - obj, - expected_text="((int, str) -> int) | Sequence[Unknown] | C | list[int] | B | D | TCall1@func1", - ) - else: - reveal_type(obj, expected_text="A") - - if isinstance(obj, Callable): - reveal_type(obj, expected_text="((int, str) -> int) | B | TCall1@func1") - else: - reveal_type(obj, expected_text="Sequence[Unknown] | C | list[int] | D | A") - - -class CB1: - def __call__(self, x: str) -> None: ... - - -def func2(c1: Callable[[int], None], c2: Callable[..., None]): - if isinstance(c1, CB1): - reveal_type(c1, expected_text="Never") - - if isinstance(c2, CB1): - reveal_type(c2, expected_text="CB1") - - -class IsNotFinal: ... - - -def func3(c1: Callable[[int], None]): - if isinstance(c1, IsNotFinal): - reveal_type(c1, expected_text="IsNotFinal") - - -@final -class IsFinal: ... - - -def func4(c1: Callable[[int], None]): - if isinstance(c1, IsFinal): - reveal_type(c1, expected_text="Never") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance6.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance6.py deleted file mode 100644 index 099f3356..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance6.py +++ /dev/null @@ -1,91 +0,0 @@ -# This sample tests the case where isinstance or issubclass is used to -# narrow the type of a specialized class to a subclass where the type -# arguments are implied by the type arguments of the wider class. - -from typing import Any, Generic, Iterable, Sequence, TypeVar - -_T1 = TypeVar("_T1") - - -class ParentA(Generic[_T1]): ... - - -class ChildA1(ParentA[_T1]): ... - - -def func1(a: ParentA[int], b: ParentA[str] | ParentA[complex]) -> None: - if isinstance(a, ChildA1): - reveal_type(a, expected_text="ChildA1[int]") - - if isinstance(b, ChildA1): - reveal_type(b, expected_text="ChildA1[str] | ChildA1[complex]") - - -def func2( - a: type[ParentA[int]], b: type[ParentA[str]] | type[ParentA[complex]] -) -> None: - if issubclass(a, ChildA1): - reveal_type(a, expected_text="type[ChildA1[int]]") - - if issubclass(b, ChildA1): - reveal_type(b, expected_text="type[ChildA1[str]] | type[ChildA1[complex]]") - - -def func3(value: Iterable[_T1]) -> Sequence[_T1] | None: - if isinstance(value, Sequence): - return value - - -_T2 = TypeVar("_T2", bound=float, covariant=True) - - -class ParentB(Generic[_T2]): - pass - - -class ChildB1(ParentB[_T2]): - pass - - -def func4(var: ParentB[int]): - if isinstance(var, ChildB1): - reveal_type(var, expected_text="ChildB1[int]") - - -def func5(var: ParentB[Any]): - if isinstance(var, ChildB1): - reveal_type(var, expected_text="ChildB1[Any]") - - -_T3 = TypeVar("_T3", float, str) - - -class ParentC(Generic[_T3]): - pass - - -class ChildC1(ParentC[_T3]): - pass - - -def func6(var: ParentC[int]): - if isinstance(var, ChildC1): - reveal_type(var, expected_text="ChildC1[float]") - - -class ParentD(Generic[_T1]): - x: _T1 - - -class ChildD1(ParentD[_T1]): ... - - -class ChildD2(ParentD[int]): ... - - -def func7(a: ParentD[_T1]) -> _T1 | None: - if isinstance(a, ChildD1): - reveal_type(a, expected_text="ChildD1[_T1@func7]") - - elif isinstance(a, ChildD2): - reveal_type(a, expected_text="ChildD2") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance7.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance7.py deleted file mode 100644 index 1bcc49c7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance7.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where an isinstance call uses -# a union of class types, some of which are tuples of other types -# and some of which are not. - -from typing import TypeVar, Iterator - -T1 = TypeVar("T1", bound="X") -T2 = TypeVar("T2", bound="X") - - -class X: - element_list: list["X"] - - def return_iter( - self, cls: type[T1] | tuple[type[T1], type[T2]] - ) -> Iterator[T1 | T2]: - for item in self.element_list: - if isinstance(item, cls): - yield item diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance8.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance8.py deleted file mode 100644 index 75914d09..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingIsinstance8.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the case where an issubclass type guard narrows -# to an abstract base class. When attempting to instantiate the -# class, there should be no "cannot instantiate ABC" error. - -# viper: strict - -from abc import ABC, abstractmethod -from typing import Any - - -class Base(ABC): - @abstractmethod - def f(self) -> None: ... - - -def func1(cls: Any): - assert issubclass(cls, Base) - reveal_type(cls, expected_text="type[Base]") - _ = cls() - - -def func2(cls: Any): - assert isinstance(cls, type) - reveal_type(cls, expected_text="type") - assert issubclass(cls, Base) - reveal_type(cls, expected_text="type[Base]") - _ = cls() diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral1.py deleted file mode 100644 index a0e90dc2..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral1.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests the type analyzer's type narrowing -# logic for literals. - -from typing import Literal, LiteralString, TypeVar, Union - - -def func1(p1: Literal["a", "b", "c"]): - if p1 != "b": - if p1 == "c": - reveal_type(p1, expected_text="Literal['c']") - pass - else: - reveal_type(p1, expected_text="Literal['a']") - - if p1 != "a": - reveal_type(p1, expected_text="Literal['c', 'b']") - else: - reveal_type(p1, expected_text="Literal['a']") - - -def func2(p1: Literal[1, 4, 7]): - if p1 == 4 or p1 == 1: - reveal_type(p1, expected_text="Literal[4, 1]") - else: - reveal_type(p1, expected_text="Literal[7]") - - -def func3(a: Union[int, None]): - if a == 1 or a == 2: - reveal_type(a, expected_text="Literal[1, 2]") - - -T = TypeVar("T", bound=Literal["a", "b"]) - - -def func4(x: T) -> T: - if x == "a": - reveal_type(x, expected_text="Literal['a']") - return x - else: - reveal_type(x, expected_text="Literal['b']") - return x - - -S = TypeVar("S", Literal["a"], Literal["b"]) - - -def func5(x: S) -> S: - if x == "a": - reveal_type(x, expected_text="Literal['a']") - return x - else: - reveal_type(x, expected_text="Literal['b']") - return x - - -def func6(x: LiteralString): - if x == "a": - reveal_type(x, expected_text="Literal['a']") - else: - reveal_type(x, expected_text="LiteralString") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral2.py deleted file mode 100644 index a768bd6c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteral2.py +++ /dev/null @@ -1,82 +0,0 @@ -# This sample tests the type narrowing capabilities involving -# types that have enumerated literals (bool and enums). - -from enum import Enum -from typing import Any, Literal, Union, reveal_type - - -class SomeEnum(Enum): - SOME_ENUM_VALUE1 = 1 - SOME_ENUM_VALUE2 = 2 - SOME_ENUM_VALUE3 = 3 - - -def func1(a: SomeEnum) -> Literal[3]: - if a == SomeEnum.SOME_ENUM_VALUE1 or a == SomeEnum.SOME_ENUM_VALUE2: - return 3 - else: - return a.value - - -def func2(a: SomeEnum) -> Literal[3]: - if a == SomeEnum.SOME_ENUM_VALUE1: - return 3 - elif a == SomeEnum.SOME_ENUM_VALUE2: - return 3 - else: - return a.value - - -def must_be_true(a: Literal[True]): ... - - -def must_be_false(a: Literal[False]): ... - - -def func3(a: bool): - if a == True: - must_be_true(a) - else: - must_be_false(a) - - -def func4(a: bool): - if not a: - must_be_false(a) - else: - must_be_true(a) - - -class MyEnum(Enum): - ZERO = 0 - ONE = 1 - - -def func5(x: Union[MyEnum, str]): - if x is MyEnum.ZERO: - reveal_type(x, expected_text="Literal[MyEnum.ZERO]") - elif x is MyEnum.ONE: - reveal_type(x, expected_text="Literal[MyEnum.ONE]") - else: - reveal_type(x, expected_text="str") - - -def func6(x: Any): - if x is MyEnum.ZERO: - reveal_type(x, expected_text="Literal[MyEnum.ZERO]") - else: - reveal_type(x, expected_text="Any") - - -def func7(x: Any): - if x == MyEnum.ZERO: - reveal_type(x, expected_text="Literal[MyEnum.ZERO]") - else: - reveal_type(x, expected_text="Any") - - -def func8(x: Literal[0, 1] | None): - if x is 1: - reveal_type(x, expected_text="Literal[1]") - else: - reveal_type(x, expected_text="Literal[0, 1] | None") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteralMember1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteralMember1.py deleted file mode 100644 index 359c1d95..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingLiteralMember1.py +++ /dev/null @@ -1,204 +0,0 @@ -# This sample tests type narrowing based on member accesses -# to members that have literal types. - -from typing import ClassVar, Literal, Union - - -class A: - kind: Literal["A"] - kind_class: ClassVar[Literal["A"]] - d: Literal[1, 2, 3] - is_a: Literal[True] - - -class B: - kind: Literal["B"] - kind_class: ClassVar[Literal["B"]] - d: Literal[3, 4, 5] - is_a: Literal[False] - - -class C: - kind: str - kind_class: str - c: int - is_a: bool - - -class D: - kind: Literal[1, 2, 3] - - -def eq_obj1(c: Union[A, B]): - if c.kind == "A": - reveal_type(c, expected_text="A") - else: - reveal_type(c, expected_text="B") - - -def is_obj1_1(c: Union[A, B]): - if c.kind is "A": - reveal_type(c, expected_text="A | B") - else: - reveal_type(c, expected_text="A | B") - - -def is_obj1_2(c: Union[A, B]): - if c.is_a is False: - reveal_type(c, expected_text="B") - else: - reveal_type(c, expected_text="A") - - -def eq_obj2(c: Union[A, B]): - if c.kind != "A": - reveal_type(c, expected_text="B") - else: - reveal_type(c, expected_text="A") - - -def is_obj2(c: Union[A, B]): - if c.kind is not "A": - reveal_type(c, expected_text="A | B") - else: - reveal_type(c, expected_text="A | B") - - -def eq_obj3(c: Union[A, B, C]): - if c.kind == "A": - reveal_type(c, expected_text="A | C") - else: - reveal_type(c, expected_text="B | C") - - -def is_obj3(c: Union[A, B, C]): - if c.kind is "A": - reveal_type(c, expected_text="A | B | C") - else: - reveal_type(c, expected_text="A | B | C") - - -def eq_obj4(c: Union[A, B]): - if c.d == 1: - reveal_type(c, expected_text="A") - elif c.d == 3: - reveal_type(c, expected_text="A | B") - - -def is_obj4(c: Union[A, B]): - if c.d is 1: - reveal_type(c, expected_text="A | B") - elif c.d is 3: - reveal_type(c, expected_text="A | B") - - -def eq_obj5(d: D): - if d.kind == 1: - reveal_type(d, expected_text="D") - elif d.kind == 2: - reveal_type(d, expected_text="D") - - -def is_obj5(d: D): - if d.kind is 1: - reveal_type(d, expected_text="D") - elif d.kind is 2: - reveal_type(d, expected_text="D") - - -def eq_class2(c: Union[type[A], type[B]]): - if c.kind_class == "A": - reveal_type(c, expected_text="type[A]") - else: - reveal_type(c, expected_text="type[B]") - - -def is_class2(c: Union[type[A], type[B]]): - if c.kind_class is "A": - reveal_type(c, expected_text="type[A] | type[B]") - else: - reveal_type(c, expected_text="type[A] | type[B]") - - -class E: - @property - def type(self) -> Literal[0]: - return 0 - - -class F: - @property - def type(self) -> Literal[1]: - return 1 - - -def test(x: E | F) -> None: - if x.type == 1: - reveal_type(x, expected_type="F") - else: - reveal_type(x, expected_type="E") - - -class G: - type: Literal[0] - - -class H: - type: Literal[1] - - -class I: - thing: G | H - - def method1(self) -> None: - if self.thing.type == 1: - reveal_type(self.thing, expected_text="H") - - local = self.thing - if local.type == 1: - reveal_type(local, expected_text="H") - - -class XA: - data: int - event: Literal["a"] - - -class XB: - data: str - event: Literal["b"] - - -class XC: - data: complex - event: Literal["c"] - - -def func1(event: XA | XC | XB) -> None: - if event.event == "a": - reveal_type(event.data, expected_text="int") - - if event.event == "b": - if event.data: - reveal_type(event.data, expected_text="str") - elif event.event == "c": - reveal_type(event.data, expected_text="complex") - - -class XD: - event: Literal["d"] - - -class XE: - event: None | Literal["e"] - - -def func2(e: XD | XE) -> None: - if e.event == None: - reveal_type(e, expected_text="XE") - - if e.event == "e": - reveal_type(e, expected_text="XE") - - if e.event == "d": - reveal_type(e, expected_text="XD") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingLocalConst1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingLocalConst1.py deleted file mode 100644 index be56f6bc..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingLocalConst1.py +++ /dev/null @@ -1,133 +0,0 @@ -# This sample tests the case where a local (constant) variable that -# is assigned a narrowing expression can be used in a type guard condition. -# These are sometimes referred to as "aliased conditional expressions". - - -import random - - -class A: - a: int - - -class B: - b: int - - -def func1(x: A | B) -> None: - is_a = not not isinstance(x, A) - - if not is_a: - reveal_type(x, expected_text="B") - else: - reveal_type(x, expected_text="A") - - -def func2(x: A | B) -> None: - is_a = isinstance(x, A) - - if random.random() < 0.5: - x = B() - - if is_a: - reveal_type(x, expected_text="B | A") - else: - reveal_type(x, expected_text="B | A") - - -def func3(x: int | None): - is_number = x != None - - if is_number: - reveal_type(x, expected_text="int") - else: - reveal_type(x, expected_text="None") - - -def func4() -> A | None: - return A() if random.random() < 0.5 else None - - -maybe_a1 = func4() -is_a1 = maybe_a1 - -if is_a1: - reveal_type(maybe_a1, expected_text="A") -else: - reveal_type(maybe_a1, expected_text="None") - -maybe_a2 = func4() - - -def func5(): - global maybe_a2 - maybe_a2 = False - - -is_a2 = maybe_a2 - -if is_a2: - reveal_type(maybe_a2, expected_text="A | None") -else: - reveal_type(maybe_a2, expected_text="A | None") - - -def func6(x: A | B) -> None: - is_a = isinstance(x, A) - - for y in range(1): - if is_a: - reveal_type(x, expected_text="A | B") - else: - reveal_type(x, expected_text="A | B") - - if random.random() < 0.5: - x = B() - - -def get_string() -> str: ... - - -def get_optional_string() -> str | None: ... - - -def func7(val: str | None = None): - val = get_optional_string() - - val_is_none = val is None - - if val_is_none: - val = get_string() - - reveal_type(val, expected_text="str") - - -def func8(val: str | None = None): - val = get_optional_string() - - val_is_none = val is None - - val = get_optional_string() - - if val_is_none: - val = get_string() - - reveal_type(val, expected_text="str | None") - - -def func9(var: str | None = None): - if var_not_None := not (var is None): - reveal_type(var, expected_text="str") - - reveal_type(var, expected_text="str | None") - - if var_not_None: - reveal_type(var, expected_text="str") - - if 1 > 1 + 2: - var = None - else: - var = "a" + "b" - - if var_not_None: - reveal_type(var, expected_text="Literal['ab'] | None") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingNoneMember1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingNoneMember1.py deleted file mode 100644 index 4ad49365..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingNoneMember1.py +++ /dev/null @@ -1,100 +0,0 @@ -# This sample tests the type narrowing case for unions of NamedTuples -# where one or more of the entries is tested against type None by attribute. - -from typing import NamedTuple, Union - -IntFirst = NamedTuple( - "IntFirst", - [ - ("first", int), - ("second", None), - ], -) - -StrSecond = NamedTuple( - "StrSecond", - [ - ("first", None), - ("second", str), - ], -) - - -def func1(a: Union[IntFirst, StrSecond]) -> IntFirst: - if a.second is None: - reveal_type(a, expected_text="IntFirst") - return a - else: - reveal_type(a, expected_text="StrSecond") - raise ValueError() - - -UnionFirst = NamedTuple( - "UnionFirst", - [ - ("first", Union[None, int]), - ("second", None), - ], -) - - -def func2(a: Union[UnionFirst, StrSecond]): - if a.first is None: - reveal_type(a, expected_text="UnionFirst | StrSecond") - else: - reveal_type(a, expected_text="UnionFirst") - - -class A: - @property - def prop1(self) -> int | None: ... - - member1: None - member2: int | None - member3: int | None - member4: int | None - - -class B: - @property - def prop1(self) -> int: ... - - member1: int - member2: int | None - member3: None - member4: int - - -def func3(c: Union[A, B]): - if c.prop1 is None: - reveal_type(c, expected_text="A | B") - else: - reveal_type(c, expected_text="A | B") - - -def func4(c: Union[A, B]): - if c.member1 is None: - reveal_type(c, expected_text="A") - else: - reveal_type(c, expected_text="B") - - -def func5(c: Union[A, B]): - if c.member2 is None: - reveal_type(c, expected_text="A | B") - else: - reveal_type(c, expected_text="A | B") - - -def func6(c: Union[A, B]): - if c.member3 is not None: - reveal_type(c, expected_text="A") - else: - reveal_type(c, expected_text="A | B") - - -def func7(c: Union[A, B]): - if c.member4 is not None: - reveal_type(c, expected_text="A | B") - else: - reveal_type(c, expected_text="A") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTuple1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTuple1.py deleted file mode 100644 index 243315a5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTuple1.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the type narrowing for known-length tuples -# that have an entry with a declared literal type. - -from enum import Enum -from typing import Literal - -MsgA = tuple[Literal[1], str] -MsgB = tuple[Literal[2], float] - -MsgAOrB = MsgA | MsgB - - -def func1(m: MsgAOrB): - if m[0] == 1: - reveal_type(m, expected_text="tuple[Literal[1], str]") - else: - reveal_type(m, expected_text="tuple[Literal[2], float]") - - -def func2(m: MsgAOrB): - if m[0] != 1: - reveal_type(m, expected_text="tuple[Literal[2], float]") - else: - reveal_type(m, expected_text="tuple[Literal[1], str]") - - -MsgC = tuple[Literal[True], str] -MsgD = tuple[Literal[False], float] - -MsgCOrD = MsgC | MsgD - - -def func3(m: MsgCOrD): - if m[0] is True: - reveal_type(m, expected_text="tuple[Literal[True], str]") - else: - reveal_type(m, expected_text="tuple[Literal[False], float]") - - -def func4(m: MsgCOrD): - if m[0] is not True: - reveal_type(m, expected_text="tuple[Literal[False], float]") - else: - reveal_type(m, expected_text="tuple[Literal[True], str]") - - -class MyEnum(Enum): - A = 0 - B = 1 - - -MsgE = tuple[Literal[MyEnum.A], str] -MsgF = tuple[Literal[MyEnum.B], float] - -MsgEOrF = MsgE | MsgF - - -def func5(m: MsgEOrF): - if m[0] is MyEnum.A: - reveal_type(m, expected_text="tuple[Literal[MyEnum.A], str]") - else: - reveal_type(m, expected_text="tuple[Literal[MyEnum.B], float]") - - -def func6(m: MsgEOrF): - if m[0] is not MyEnum.A: - reveal_type(m, expected_text="tuple[Literal[MyEnum.B], float]") - else: - reveal_type(m, expected_text="tuple[Literal[MyEnum.A], str]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTupleLength1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTupleLength1.py deleted file mode 100644 index 0301013a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTupleLength1.py +++ /dev/null @@ -1,161 +0,0 @@ -# This sample tests type narrowing of tuples based on len(x) test. - -from typing import Callable, Literal, ParamSpec, TypeVar - -P = ParamSpec("P") - - -def func1(val: tuple[int] | tuple[int, int] | tuple[str, str]): - if len(val) == 1: - reveal_type(val, expected_text="tuple[int]") - else: - reveal_type(val, expected_text="tuple[int, int] | tuple[str, str]") - - if len(val) != 2: - reveal_type(val, expected_text="tuple[int]") - else: - reveal_type(val, expected_text="tuple[int, int] | tuple[str, str]") - - -def func2(val: tuple[int] | tuple[int, ...]): - if len(val) == 1: - reveal_type(val, expected_text="tuple[int]") - else: - reveal_type(val, expected_text="tuple[int, ...]") - - if len(val) != 2: - reveal_type(val, expected_text="tuple[int] | tuple[int, ...]") - else: - reveal_type(val, expected_text="tuple[int, int]") - - -def func3(val: tuple[int] | tuple[()]): - N = 0 - if len(val) == N: - reveal_type(val, expected_text="tuple[()]") - else: - reveal_type(val, expected_text="tuple[int]") - - -_T1 = TypeVar("_T1", bound=tuple[int]) -_T2 = TypeVar("_T2", bound=tuple[str, str]) - - -def func4(val: _T1 | _T2) -> _T1 | _T2: - if len(val) == 1: - reveal_type(val, expected_text="_T1@func4") - else: - reveal_type(val, expected_text="_T2@func4") - - return val - - -def func5( - val: ( - tuple[int, ...] - | tuple[str] - | tuple[str, str, str] - | tuple[int, *tuple[str, ...], str] - | tuple[int, *tuple[float, ...]] - ), - length: Literal[2], -): - if len(val) == length: - reveal_type( - val, expected_text="tuple[int, int] | tuple[int, str] | tuple[int, float]" - ) - else: - reveal_type( - val, - expected_text="tuple[int, ...] | tuple[str] | tuple[str, str, str] | tuple[int, str, *tuple[str, ...], str] | tuple[int, *tuple[float, ...]]", - ) - - -def func10(t: tuple[()] | tuple[int] | tuple[int, int] | tuple[int, int, int]): - if len(t) >= 2: - reveal_type(t, expected_text="tuple[int, int] | tuple[int, int, int]") - else: - reveal_type(t, expected_text="tuple[()] | tuple[int]") - - -def func11(t: tuple[()] | tuple[int] | tuple[int, int] | tuple[int, int, int]): - if len(t) > 1: - reveal_type(t, expected_text="tuple[int, int] | tuple[int, int, int]") - else: - reveal_type(t, expected_text="tuple[()] | tuple[int]") - - -def func12(t: tuple[()] | tuple[int] | tuple[int, int]): - if len(t) >= 0: - reveal_type(t, expected_text="tuple[()] | tuple[int] | tuple[int, int]") - else: - reveal_type(t, expected_text="Never") - - -def func20(t: tuple[int, ...]): - if len(t) >= 2: - reveal_type(t, expected_text="tuple[int, int, *tuple[int, ...]]") - else: - reveal_type(t, expected_text="tuple[()] | tuple[int]") - - -def func21(t: tuple[int, ...]): - if len(t) > 0: - reveal_type(t, expected_text="tuple[int, *tuple[int, ...]]") - else: - reveal_type(t, expected_text="tuple[()]") - - -def func22(t: tuple[str, *tuple[int, ...], str]): - if len(t) < 3: - reveal_type(t, expected_text="tuple[str, str]") - else: - reveal_type(t, expected_text="tuple[str, int, *tuple[int, ...], str]") - - -def func23(t: tuple[str, *tuple[int, ...], str]): - if len(t) <= 3: - reveal_type(t, expected_text="tuple[str, str] | tuple[str, int, str]") - else: - reveal_type(t, expected_text="tuple[str, int, int, *tuple[int, ...], str]") - - -def func24(t: tuple[str, *tuple[int, ...], str]): - if len(t) <= 34: - reveal_type(t, expected_text="tuple[str, *tuple[int, ...], str]") - else: - reveal_type(t, expected_text="tuple[str, *tuple[int, ...], str]") - - -def func25(t: tuple[str, *tuple[int, ...], str]): - if len(t) < 2: - reveal_type(t, expected_text="Never") - else: - reveal_type(t, expected_text="tuple[str, *tuple[int, ...], str]") - - -def func26(fn: Callable[P, None]): - def inner(*args: P.args, **kwargs: P.kwargs): - if len(args) >= 0: - reveal_type(args, expected_text="P@func26.args") - else: - reveal_type(args, expected_text="P@func26.args") - return fn(*args, **kwargs) - - return inner - - -def func27(t: tuple[int, ...]): - if len(t) == 0 or len(t) >= 2: - reveal_type(t, expected_text="tuple[()] | tuple[int, int, *tuple[int, ...]]") - else: - reveal_type(t, expected_text="tuple[int]") - - -def func28(t: tuple[int, *tuple[int, ...]]): - if len(t) == 1 or len(t) >= 3: - reveal_type( - t, expected_text="tuple[int] | tuple[int, int, int, *tuple[int, ...]]" - ) - else: - reveal_type(t, expected_text="tuple[int, int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypeEquals1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTypeEquals1.py deleted file mode 100644 index 137618b9..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypeEquals1.py +++ /dev/null @@ -1,110 +0,0 @@ -# This sample exercises the type analyzer's type narrowing -# logic for tests of the form "type(X) == Y" or "type(X) != Y". - -from typing import Any, Generic, TypeVar, final - - -def func1(a: str | int) -> int: - if type(a) != str: - # This should generate an error because - # "a" is potentially a subclass of str. - return a - - # This should generate an error because - # "a" is provably type str at this point. - return a - - -def func2(a: str | None) -> str: - if type(a) == str: - return a - - # This should generate an error because - # "a" is provably type str at this point. - return a - - -def func3(a: dict[str, Any]) -> str: - val = a.get("hello") - if type(val) == str: - return val - - return "none" - - -class A: - pass - - -class B(A): - pass - - -def func4(a: str | A): - if type(a) == B: - reveal_type(a, expected_text="B") - else: - reveal_type(a, expected_text="str | A") - - -T = TypeVar("T") - - -class C(Generic[T]): - def __init__(self, a: T): - self.a = a - - -class D: - pass - - -E = C[T] | D - - -def func5(x: E[T]) -> None: - if type(x) == C: - reveal_type(x, expected_text="C[T@func5]") - - -@final -class AFinal: - pass - - -@final -class BFinal: - pass - - -def func6(val: AFinal | BFinal) -> None: - if type(val) == AFinal: - reveal_type(val, expected_text="AFinal") - else: - reveal_type(val, expected_text="BFinal") - - -def func7(val: Any): - if type(val) == int: - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="Any") - - reveal_type(val, expected_text="int | Any") - - -class CParent: ... - - -class CChild(CParent): ... - - -_TC = TypeVar("_TC", bound=CParent) - - -def func8(a: _TC, b: _TC) -> _TC: - if type(a) == CChild: - reveal_type(a, expected_text="CChild*") - return a - reveal_type(a, expected_text="CParent*") - return a diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypeIs1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTypeIs1.py deleted file mode 100644 index a103c98f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypeIs1.py +++ /dev/null @@ -1,153 +0,0 @@ -# This sample exercises the type analyzer's type narrowing -# logic for tests of the form "type(X) is Y" or "type(X) is not Y". - -from typing import Any, Generic, TypeVar, final - - -def func1(a: str | int) -> int: - if type(a) is not str: - # This should generate an error because - # "a" is potentially a subclass of str. - return a - - # This should generate an error because - # "a" is provably type str at this point. - return a - - -def func2(a: str | None) -> str: - if type(a) is str: - return a - - # This should generate an error because - # "a" is provably type str at this point. - return a - - -def func3(a: dict[str, Any]) -> str: - val = a.get("hello") - if type(val) is str: - return val - - return "none" - - -class A: - pass - - -class B(A): - pass - - -def func4(a: str | A): - if type(a) is B: - reveal_type(a, expected_text="B") - else: - reveal_type(a, expected_text="str | A") - - -T = TypeVar("T") - - -class C(Generic[T]): - def __init__(self, a: T): - self.a = a - - -class D: - pass - - -E = C[T] | D - - -def func5(x: E[T]) -> None: - if type(x) is C: - reveal_type(x, expected_text="C[T@func5]") - - -@final -class AFinal: - pass - - -@final -class BFinal: - pass - - -def func6(val: AFinal | BFinal) -> None: - if type(val) is AFinal: - reveal_type(val, expected_text="AFinal") - else: - reveal_type(val, expected_text="BFinal") - - -def func7(val: Any): - if type(val) is int: - reveal_type(val, expected_text="int") - else: - reveal_type(val, expected_text="Any") - - reveal_type(val, expected_text="int | Any") - - -class CParent: ... - - -class CChild(CParent): ... - - -_TC = TypeVar("_TC", bound=CParent) - - -def func8(a: _TC, b: _TC) -> _TC: - if type(a) is CChild: - reveal_type(a, expected_text="CChild*") - return a - reveal_type(a, expected_text="CParent*") - return a - - -class F: - def method1(self, v: object): - if type(self) == type(v): - reveal_type(self, expected_text="Self@F") - else: - reveal_type(self, expected_text="Self@F") - - -class G(str): - @classmethod - def method1(cls, v: str): - if type(v) is cls: - reveal_type(v, expected_text="G*") - else: - reveal_type(v, expected_text="str") - - -class H: - def __init__(self, x): ... - - -def func9[T: H](x: type[T], y: H) -> T: - if type(y) == x: - reveal_type(y, expected_text="H*") - return y - return x(y) - - -class I: - pass - - -class J: - pass - - -def func10[T: I | J](items: list[I | J], kind: type[T]) -> T | None: - for i in items: - if type(i) is kind: - reveal_type(i, expected_text="I* | J*") - return i diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict1.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict1.py deleted file mode 100644 index 2521fdb3..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict1.py +++ /dev/null @@ -1,117 +0,0 @@ -# This sample tests type narrowing for TypedDict types based -# on whether a key is in or not in the dict. - -from typing import TypedDict - - -class TD1(TypedDict): - a: str - b: int - - -class TD2(TypedDict): - a: int - c: str - - -class TD3(TypedDict, total=False): - a: int - d: str - - -def f1(p: TD1 | TD2): - if "b" in p: - # This should technically be TD1 | TD2, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(p, expected_text="TD1") - # reveal_type(p, expected_text="TD1 | TD2") - else: - reveal_type(p, expected_text="TD2") - - -def f2(p: TD1 | TD2): - if "b" not in p: - reveal_type(p, expected_text="TD2") - else: - # This should technically be TD1 | TD2, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(p, expected_text="TD1") - # reveal_type(p, expected_text="TD1 | TD2") - - -def f3(p: TD1 | TD3): - if "d" in p: - # This should technically be TD1 | TD3, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(p, expected_text="TD3") - # reveal_type(p, expected_text="TD1 | TD3") - else: - reveal_type(p, expected_text="TD1 | TD3") - - -def f4(p: TD1 | TD3): - if "d" not in p: - reveal_type(p, expected_text="TD1 | TD3") - else: - # This should technically be TD1 | TD3, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(p, expected_text="TD3") - # reveal_type(p, expected_text="TD1 | TD3") - - -def f5(p: TD1 | TD3): - if "a" in p: - reveal_type(p, expected_text="TD1 | TD3") - else: - reveal_type(p, expected_text="TD3") - - -def f6(p: TD1 | TD2 | TD3): - # This should generate an error for TD3. - v1 = p["a"] - - v2 = p.get("a") - - if "c" in p: - # This should technicall generate two errors for TD1 and TD3 - v3 = p["c"] - # This should technically be Unknown | str, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(v3, expected_text="str") - # reveal_type(v3, expected_text="Unknown | str") - - if "a" in p and "d" in p: - v4 = p["a"] - # This should technically be str | int, but the - # current narrowing logic implements a not-entirely-safe - # narrowing behavior. We can fix this once PEP 728 - # is accepted. - reveal_type(v4, expected_text="int") - # reveal_type(v4, expected_text="str | int") - - # This should generate an error for TD1 and TD2 - v5 = p["d"] - reveal_type(v5, expected_text="Unknown | str") - - # This should generate three errors, two for TD1 and TD2 (because - # "d" is not a valid key) and one for TD3 (because "d" is not required). - v6 = p["d"] - - -def f7(p: TD3): - pass - - -def f8(p: TD3): - if "a" in p: - f7(p) diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict2.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict2.py deleted file mode 100644 index ca02090a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict2.py +++ /dev/null @@ -1,98 +0,0 @@ -# This sample tests type narrowing based on key accesses -# to unions of TypedDicts that have fields with literal types. - -from typing import Literal, TypedDict - - -class Event1(TypedDict): - tag: Literal["new-job"] - job_name: str - config_file_path: str - - -class Event2(TypedDict): - tag: Literal[2] - job_id: int - - -class Event3(TypedDict): - tag: Literal["other-job"] - message: str - - -Event = Event1 | Event2 | Event3 - - -def process_event1(event: Event) -> None: - if event["tag"] == "new-job": - reveal_type(event, expected_text="Event1") - event["job_name"] - elif event["tag"] == 2: - reveal_type(event, expected_text="Event2") - event["job_id"] - else: - reveal_type(event, expected_text="Event3") - event["message"] - - -def process_event2(event: Event) -> None: - if event["tag"] is "new-job": - reveal_type(event, expected_text="Event1") - event["job_name"] - elif event["tag"] is 2: - reveal_type(event, expected_text="Event2") - event["job_id"] - else: - reveal_type(event, expected_text="Event3") - event["message"] - - -class ClassA: - job_event: Event1 | Event3 - - def method1(self): - if self.job_event["tag"] == "new-job": - reveal_type(self.job_event, expected_text="Event1") - else: - reveal_type(self.job_event, expected_text="Event3") - - -class A(TypedDict): - name: Literal["A"] - a: str - - -class BC(TypedDict): - name: Literal["B", "C"] - b: str - - -AorBC = A | BC - - -def func1(val: AorBC, key: Literal["C", "D"]): - if val["name"] == key: - reveal_type(val, expected_text="BC") - else: - reveal_type(val, expected_text="A | BC") - - -def func2(val: AorBC, key: Literal["A", "D"]): - if val["name"] == key: - reveal_type(val, expected_text="A") - else: - reveal_type(val, expected_text="A | BC") - - -def func3(val: AorBC, key: Literal["A", "C"]): - if val["name"] == key: - reveal_type(val, expected_text="A | BC") - else: - reveal_type(val, expected_text="A | BC") - - -def func4(val: AorBC, key: Literal["B", "C"]): - if val["name"] == key: - reveal_type(val, expected_text="BC") - else: - reveal_type(val, expected_text="A | BC") diff --git a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict3.py b/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict3.py deleted file mode 100644 index 25d16939..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeNarrowingTypedDict3.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests assignment-based narrowing for TypedDict values. - -from typing import TypedDict - - -class MyDict1(TypedDict, total=False): - key1: int - key2: str - - -my_dict1: MyDict1 = {"key1": 1} -my_dict1["key1"] - -# This should generate an error because "key2" isn't included in the -# narrowed type. -my_dict1["key2"] - -if "key2" in my_dict1: - my_dict1["key2"] - - -class MyDict2(TypedDict, total=False): - key3: MyDict1 - key4: MyDict1 - key5: MyDict1 - - -my_dict2: MyDict2 = {"key3": {"key1": 3}, "key4": {}} - -my_dict2["key3"] -my_dict2["key4"] - -# This should generate an error because "key5" isn't included in the -# narrowed type. -my_dict2["key5"] - -my_dict2["key3"]["key1"] - -# This should generate an error because "key2" isn't included in the -# narrowed type. -my_dict2["key3"]["key2"] - -# This should generate an error because "key4" isn't included in the -# narrowed type. -my_dict2["key4"]["key1"] diff --git a/packages/vipeye-internal/src/tests/samples/typeParams1.py b/packages/vipeye-internal/src/tests/samples/typeParams1.py deleted file mode 100644 index adbff305..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams1.py +++ /dev/null @@ -1,115 +0,0 @@ -# This sample tests the PEP 695 type parameter syntax for generic classes -# and functions. - -T1 = 0 - - -class ClassA[T1]: ... - - -def func1[T1](): ... - - -T2: str - - -class ClassB[T2]: ... - - -def func2[T2](): ... - - -# This should generate an error because T3 is duplicated. -class ClassC[T3, S1, T3]: ... - - -class ClassD: - class ClassE: ... - - class ClassF: - class A[T]: ... - - int_alias = int - - class B(A[int_alias]): - pass - - # This should generate an error because ClassE is out of scope. - class C(A[ClassE]): - pass - - -class ClassG[T](list["T"]): - pass - - -class ClassH: - def object[T](self, target: object, new: T) -> T: ... - - -# This should generate an error because T3 is duplicated. -def func3[T3, S1, T3](): ... - - -def func4[T4](T4: int): ... - - -def func5[T5](a: int): - # This should generate an error because T5 is already in use. - class ClassA[T5]: ... - - # This should generate an error because T5 is already in use. - def inner_func1[T5](): ... - - -def func6[T6](T7: int): - class ClassA[T7]: ... - - def inner_func1[T7](): ... - - global T2 - - class ClassB[T2]: - global T2 - - class ClassC[T3]: - T3 = 4 - - T3 = 4 - - -def func7[T8: ForwardRefClass[str], T9: "ForwardRefClass[int]"](): - pass - - -def func8[T10: (ForwardRefClass[str], "ForwardRefClass[int]")](): - pass - - -class ForwardRefClass[T]: - pass - - -class ClassI1: ... - - -class ClassI2: - def method1[T](self, v: ClassI1) -> None: ... - - # This should generate an error because ClassJ is - def method2[T](self, v: ClassI3) -> None: ... - - -class ClassI3: ... - - -def func9[T, **P, S](x: T) -> T: - S = 1 - - def inner(): - # This should generate two errors. - nonlocal T, P - - nonlocal S - - return x diff --git a/packages/vipeye-internal/src/tests/samples/typeParams2.py b/packages/vipeye-internal/src/tests/samples/typeParams2.py deleted file mode 100644 index 0fa58aa7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams2.py +++ /dev/null @@ -1,10 +0,0 @@ -# This sample tests that the use of PEP 695 type parameter syntax for generic -# classes and functions is flagged as an error if the version of Python -# is < 3.12. - -# This should generate an error if <3.12 -class ClassA[T, S]: ... - - -# This should generate an error if <3.12 -def func1[T, S](): ... diff --git a/packages/vipeye-internal/src/tests/samples/typeParams3.py b/packages/vipeye-internal/src/tests/samples/typeParams3.py deleted file mode 100644 index 7ccad601..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams3.py +++ /dev/null @@ -1,109 +0,0 @@ -# This sample tests error conditions related to the use of PEP 695 -# type parameters outside of their valid scope. - - -class ClassA[S]: - s: S - - class ClassB[T](dict[S, T]): - s: S - t: T - - def method1[U](self): - s: S - t: T - u: U - lambda: (S, T, U) - - # This should generate an error because T is out of scope. - t: T - - -# This should generate an error because S is out of scope. -s: S - -# This should generate an error because T is out of scope. -t: T - - -def func1[A](): - def func2[B](): - a: A - b: B - - class ClassC[C](dict[B, C]): - a: A - b: B - c: C - - def method1[D](self): - a: A - b: B - c: C - d: D - e = lambda: (A, B, C, D) - - a: A - - # This should generate an error because B is out of scope. - b: B - - -# This should generate an error because A is out of scope. -a: A - -# This should generate an error because B is out of scope. -b: B - -type TA1[A] = list[A] - -# This should generate an error because B is out of scope. -type TA2[A] = list[B] - - -S = 0 - - -def outer1[S](): - S = "" - T = 1 - - def outer2[T](): - def inner1(): - nonlocal S # OK - reveal_type(S, expected_text="Literal['']") - - def inner2(): - global S # OK - reveal_type(S, expected_text="Literal[0]") - - -T = 0 - - -class Outer2[T]: - T = 1 - - reveal_type(T, expected_text="Literal[1]") - - class Inner1: - T = "" - - reveal_type(T, expected_text="Literal['']") - - def inner_method(self): - reveal_type(T, expected_text="TypeVar") - - def outer_method(self): - T = 3j - - reveal_type(T, expected_text="complex") - - def inner_func(): - reveal_type(T, expected_text="complex") - - -class Outer3[T]: - # This should generate an error because Outer3 is - # not bound at this point. - def inner_func1[S](self: Outer3[S]): ... diff --git a/packages/vipeye-internal/src/tests/samples/typeParams4.py b/packages/vipeye-internal/src/tests/samples/typeParams4.py deleted file mode 100644 index f495299d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams4.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests errors related to the use of a Generic -# or Protocol base class with PEP 695 type parameter syntax. - -from typing import Generic, Protocol - - -# This should generate an error because Generic should not -# be used with type parameter syntax. -class ClassA[T](Generic[T]): ... - - -class ClassB[T](Protocol): ... - - -# This should generate an error because Protocol should not be used -# with type parameters when used with type parameter syntax. -class ClassC[T](Protocol[T]): ... diff --git a/packages/vipeye-internal/src/tests/samples/typeParams5.py b/packages/vipeye-internal/src/tests/samples/typeParams5.py deleted file mode 100644 index 75b46c55..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams5.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests the handling of PEP 695 type parameter syntax used for -# bounded and constrained TypeVars, TypeVarTuples, and ParamSpecs. - -from typing import Any - -class ClassA[R, *Ts, **P]: - ... - -class ClassB[R: int | str]: - ... - -# This should generate an error because 'dummy' is not declared. -class ClassC[R: dummy]: - ... - -class ClassD[R: "ClassE[Any]"]: - ... - - -class ClassE[T]: - ... - -# This should generate an error because variadic type params don't -# support bound expressions. -class ClassF[*Ts: int]: ... - -# This should generate an error because ParamSpecs don't -# support bound expressions. -class ClassG[**P: int]: ... - -# This should generate an error because the expression isn't -# a valid type. -class ClassH[R: 1]: ... - -# This should generate an error because a constrained type -# must contain at least two types. -class ClassI[R: ()]: ... - -# This should generate an error because a constrained type -# must contain at least two types. -class ClassJ[R: (int, )]: ... - -class ClassK[R: (bytes, str)]: ... - -t2 = (bytes, str) -# This should generate an error because a literal tuple expression -# must be used for constrained types. -class ClassL[R: t2]: ... - -# This should generate an error because constraints must be legal -# type expressions. -class ClassM[R: (1, str)]: ... - -v: type[int] = int - -# This should generate an error because constraints must be legal -# type expressions. -class ClassN[R: (v, str)]: ... diff --git a/packages/vipeye-internal/src/tests/samples/typeParams6.py b/packages/vipeye-internal/src/tests/samples/typeParams6.py deleted file mode 100644 index 244afb3e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams6.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the interactions between traditional TypeVars and -# PEP 695 type parameter syntax. - -from typing import Generic, TypeVar - - -T1 = TypeVar("T1") -T2 = TypeVar("T2") -T4 = TypeVar("T4") - - -# This should generate an error because traditional type variables -# like T1 cannot be combined with new-style type parameters. -class ClassA[T3](dict[T1, T3]): ... - - -class ClassB(Generic[T1]): - class ClassC[T2](dict[T1, T2]): - def method1[T3](self, a: T1, b: T2, c: T3) -> T1 | T2 | T3: ... - - # This should generate an error because traditional type variables - # like T4 cannot be combined with new-style type parameters. - def method2[T3](self, a: T3, b: T4) -> T3 | T4: ... diff --git a/packages/vipeye-internal/src/tests/samples/typeParams7.py b/packages/vipeye-internal/src/tests/samples/typeParams7.py deleted file mode 100644 index 2509b4d9..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams7.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests the handling of bound and constrained type parameters -# as specified in PEP 695 type parameter statements. - - -class ClassA[**P, R: str]: ... - - -A1 = ClassA[..., str] - -# This should generate an error because str isn't a valid -# specialization for a ParamSpec. -A2 = ClassA[str, str] - -A3 = ClassA[[str], str] - -# This should generate an error because int doesn't conform -# to the bound. -A4 = ClassA[..., int] - - -class StrSubclass(str): ... - - -A5 = ClassA[..., StrSubclass] - - -class ClassB[X: (int, str), Y](dict[Y, X]): ... - - -B1 = ClassB[int, int] - -# This should generate an error because float doesn't conform -# to the constraint. -B2 = ClassB[float, float] - - -class ClassC[*Ts]: ... - - -C1 = ClassC[str, str] - -C2 = ClassC[*tuple[str, ...]] - -# This should generate an error because ... isn't valid. -C3 = ClassC[...] - -C4 = ClassC[*tuple[()]] diff --git a/packages/vipeye-internal/src/tests/samples/typeParams8.py b/packages/vipeye-internal/src/tests/samples/typeParams8.py deleted file mode 100644 index 1e036824..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeParams8.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests the case where a class defined in an inner scope -# uses type variables from an outer scope. - - -class Parent[S, T]: - def task(self, input: S) -> T: ... - - -def outer_func1[S, T](): - class Child(Parent[S, T]): - def task(self, input: S) -> T: ... - - return Child diff --git a/packages/vipeye-internal/src/tests/samples/typePrinter1.py b/packages/vipeye-internal/src/tests/samples/typePrinter1.py deleted file mode 100644 index 5f2ecfa6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typePrinter1.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests that the type printer prints fully-qualified names -# for types that are ambiguous because they have the same local name. - -from . import typePrinter2 - - -class A: - class Inner: ... - - -class B: - class Inner: ... - - -def func1(v: A.Inner | None): - reveal_type(v, expected_text="Inner | None") - - -def func2(v: A.Inner | B.Inner | None): - reveal_type(v, expected_text="typePrinter1.A.Inner | typePrinter1.B.Inner | None") - - -class IntOrStr: ... - - -def func3(v: typePrinter2.IntOrStr | IntOrStr | None): - reveal_type(v, expected_text="int | str | IntOrStr | None") diff --git a/packages/vipeye-internal/src/tests/samples/typePrinter2.py b/packages/vipeye-internal/src/tests/samples/typePrinter2.py deleted file mode 100644 index d6b3d49d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typePrinter2.py +++ /dev/null @@ -1,3 +0,0 @@ -# This sample is used in conjunction with the typePrinter1.py sample. - -IntOrStr = int | str diff --git a/packages/vipeye-internal/src/tests/samples/typePrinter3.py b/packages/vipeye-internal/src/tests/samples/typePrinter3.py deleted file mode 100644 index dd17214b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typePrinter3.py +++ /dev/null @@ -1,18 +0,0 @@ -class A: - class Child1: - pass - - -class B: - class Child1: - pass - - class Child2: - pass - - -# This should generate an error that uses fully-qualified names. -v1: A.Child1 = B.Child1() - -# This should generate an error that uses simple names. -v2: A.Child1 = B.Child2() diff --git a/packages/vipeye-internal/src/tests/samples/typePromotions1.py b/packages/vipeye-internal/src/tests/samples/typePromotions1.py deleted file mode 100644 index ef13b568..00000000 --- a/packages/vipeye-internal/src/tests/samples/typePromotions1.py +++ /dev/null @@ -1,43 +0,0 @@ -# This sample tests handling of special-cased "type promotions". - - -from typing import NewType - - -def func1(float_val: float, int_val: int): - v1: float = int_val - v2: complex = float_val - v3: complex = int_val - - -def func2(mem_view_val: memoryview, byte_array_val: bytearray): - v1: bytes = mem_view_val - v2: bytes = byte_array_val - - -class IntSubclass(int): ... - - -def func3(x: IntSubclass) -> float: - return x - - -IntNewType = NewType("IntNewType", int) - - -def func4(x: IntNewType) -> float: - return x - - -def func5(f: float): - if isinstance(f, float): - reveal_type(f, expected_text="float") - else: - reveal_type(f, expected_text="int") - - -def func6(f: complex): - if isinstance(f, float): - reveal_type(f, expected_text="float") - else: - reveal_type(f, expected_text="complex | int") diff --git a/packages/vipeye-internal/src/tests/samples/typeVar1.py b/packages/vipeye-internal/src/tests/samples/typeVar1.py deleted file mode 100644 index 82bb90c9..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar1.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests that the type checker enforces that the -# assigned name of a TypeVar matches the name provided in -# the TypeVar itself. - -from typing import Any, TypeVar - -T1 = TypeVar("T1") - -# This should generate an error because the TypeVar name -# does not match the name of the variable it is assigned to. -T2 = TypeVar("T3") - -T4: Any = TypeVar("T4") - -my_dict = {} - -# This should generate an error because TypeVars cannot be -# assigned to an index expression. -my_dict["var"] = TypeVar("T5") - -# This should generate an error because a TypeVar with a single -# constraint is an error. -T5 = TypeVar("T5", str) diff --git a/packages/vipeye-internal/src/tests/samples/typeVar10.py b/packages/vipeye-internal/src/tests/samples/typeVar10.py deleted file mode 100644 index e8254673..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar10.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the handling of constrained TypeVars when used -# within call arguments. - -from typing import TypeVar - - -class A: - def method(self, x: "A") -> "A": ... - - -class B: - def method(self, x: "B") -> "B": ... - - -T = TypeVar("T", A, B) - - -def check(x: T, y: T) -> T: - return x.method(y) diff --git a/packages/vipeye-internal/src/tests/samples/typeVar11.py b/packages/vipeye-internal/src/tests/samples/typeVar11.py deleted file mode 100644 index bb31833c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar11.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests that literal values are retained by the constraint -# solver if they are found as type arguments. - -from typing import Literal - - -_L1 = Literal["foo", "bar"] - - -def combine(set1: set[_L1], set2: set[_L1]) -> None: - x = set1 | set2 - reveal_type(x, expected_text="set[Literal['foo', 'bar']]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVar2.py b/packages/vipeye-internal/src/tests/samples/typeVar2.py deleted file mode 100644 index 895eaa83..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar2.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample verifies that the type checker is using -# synthesized type variables for "self" and "cls" variables. - - -class BaseClass: - @classmethod - def c(cls): - return cls - - def f(self): - return self - - -class SubClass(BaseClass): - pass - - -def requires_subclass(p1: SubClass): - pass - - -x = SubClass().f() -requires_subclass(x) - -y = SubClass().c() -requires_subclass(y()) diff --git a/packages/vipeye-internal/src/tests/samples/typeVar3.py b/packages/vipeye-internal/src/tests/samples/typeVar3.py deleted file mode 100644 index 8fb13429..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar3.py +++ /dev/null @@ -1,73 +0,0 @@ -# This sample tests various diagnostics related to TypeVar usage. - -from typing import Callable, Generic, TypeVar, AnyStr - -_T = TypeVar("_T") -_S = TypeVar("_S") - - -class OuterClass(Generic[_T, AnyStr]): - # This should generate an error because _S - # isn't defined in this context. - my_var1: _S - - my_var2: AnyStr - - # This should generate an error because _T - # is already in use. - class InnerClass1(Generic[_T]): ... - - # This should generate an error because AnyStr - # is already in use. - class InnerClass2(Generic[_S, AnyStr]): - my_var1: _S - - # This should generate an error because _T - # is already in use in the outer class. - my_var2: _T - - class InnerClass3: - # This should generate an error. - x: list[_T] - - def f(self, x: _T, y: _S, z: _S) -> _T: ... - - def g(self, x: AnyStr) -> None: - # This should generate an error. - y: list[_T] - - -def func1(a: _T) -> _T | None: - my_var1: _T - - # This should generate an error - my_var2: _S - - # This should generate an error because _T - # is already in use. - class InnerClass3(Generic[_T]): ... - - -# This should generate an error. -a: _S = 3 - -# This should generate an error. -b: list[_T] = [] - -# This should generate an error. -c: list[AnyStr] = [] - - -T = TypeVar("T") - - -def foo() -> Callable[[T], T]: - def inner(v: T) -> T: - reveal_type(v, expected_text="T@foo") - return v - - return inner - - -# This should generate an error. -list[T]() diff --git a/packages/vipeye-internal/src/tests/samples/typeVar4.py b/packages/vipeye-internal/src/tests/samples/typeVar4.py deleted file mode 100644 index 3383358f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar4.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests the logic that emits errors when -# covariant and contravariant TypeVars are used incorrectly -# for method parameters and return types. - -from typing import Generic, TypeVar - -_T = TypeVar("_T") -_T_co = TypeVar("_T_co", covariant=True) -_T_contra = TypeVar("_T_contra", contravariant=True) - - -class ClassA(Generic[_T, _T_co, _T_contra]): - def func1(self, a: _T): - pass - - # This should generate an error because covariant - # TypeVars are not allowed for input parameters. - def func2(self, a: _T_co): - def inner(b: _T_co) -> None: - pass - - return inner - - def func3(self, a: int | _T_co): - pass - - def func4(self, a: list[_T_co]): - pass - - def func5(self, a: _T_contra): - pass - - def func6(self) -> _T | None: - pass - - def func7(self) -> _T_co | None: - pass - - # This should generate an error because contravariant - # TypeVars are not allowed for return parameters. - def func8(self) -> _T_contra: ... - - # This should generate an error because contravariant - # TypeVars are not allowed for return parameters. - def func9(self) -> _T_contra | int: - return 3 - - # This should generate an error because contravariant - # TypeVars are not allowed for return parameters. - def func10(self, x: _T_contra): - return x - - def func11(self) -> list[_T_contra]: - return [] - - -class ClassB: - def func1(self, a: _T_co) -> _T_co: - return a - - def func2(self, a: _T_contra) -> _T_contra: - return a diff --git a/packages/vipeye-internal/src/tests/samples/typeVar5.py b/packages/vipeye-internal/src/tests/samples/typeVar5.py deleted file mode 100644 index a84330ff..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar5.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests that generic type variables -# with no bound type properly generate errors. It tests -# both class-defined and function-defined type variables. - -from typing import Generic, TypeVar - - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - - -class ClassA(Generic[_T1, _T2]): - async def func1(self, a: _T1): - # This should generate an error. - _ = a.temp - - # This should generate an error. - _ = a(3) - - # This should generate an error. - _ = a[0] - - # This should generate an error. - _ = a.temp - - # This should generate an error. - _ = a + 1 - - # This should generate an error. - _ = -a - - # This should generate an error. - a += 3 - - # This should generate an error. - _ = await a - - # This should generate an error. - for _ in a: - pass - - _ = a.__class__ - _ = a.__doc__ - - async def func2(self, a: _T2): - # This should generate an error. - _ = a.temp - - # This should generate an error. - _ = a(3) - - # This should generate an error. - _ = a[0] - - # This should generate an error. - _ = a.temp - - # This should generate an error. - _ = a + 1 - - # This should generate an error. - _ = -a - - # This should generate an error. - a += 3 - - # This should generate an error. - _ = await a - - # This should generate an error. - for _ in a: - pass - - _ = a.__class__ - _ = a.__doc__ diff --git a/packages/vipeye-internal/src/tests/samples/typeVar6.py b/packages/vipeye-internal/src/tests/samples/typeVar6.py deleted file mode 100644 index fca8fba3..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar6.py +++ /dev/null @@ -1,115 +0,0 @@ -# This sample tests that generic type variables -# with a bound type properly generate errors. It tests -# both class-defined and function-defined type variables. - -from typing import Generic, TypeVar, Union - - -class Foo: - var1: int - - def __call__(self, val: int): - pass - - def do_stuff(self) -> int: - return 0 - - -class Bar: - var1: int - var2: int - - def __call__(self, val: int): - pass - - def do_stuff(self) -> float: - return 0 - - def do_other_stuff(self) -> float: - return 0 - - -_T1 = TypeVar("_T1", bound=Foo) -_T2 = TypeVar("_T2", bound=Union[Foo, Bar]) - - -class ClassA(Generic[_T1]): - async def func1(self, a: _T1) -> _T1: - _ = a.var1 - - # This should generate an error. - _ = a.var2 - - _ = a(3) - - # This should generate an error. - _ = a(3.3) - - # This should generate an error. - _ = a[0] - - # This should generate an error. - _ = a + 1 - - # This should generate an error. - _ = -a - - # This should generate an error. - a += 3 - - # This should generate an error. - _ = await a - - # This should generate an error. - for _ in a: - pass - - a.do_stuff() - - # This should generate an error. - a.do_other_stuff() - - _ = a.__class__ - _ = a.__doc__ - - return a - - async def func2(self, a: _T2) -> _T2: - _ = a.var1 - - # This should generate an error. - _ = a.var2 - - _ = a(3) - - # This should generate an error. - _ = a(3.3) - - # This should generate two errors. - _ = a[0] - - # This should generate an error. - _ = a + 1 - - # This should generate an error. - _ = -a - - # This should generate an error. - a += 3 - - # This should generate an error. - _ = await a - - # This should generate an error. - for _ in a: - pass - - a.do_stuff() - - # This should generate an error. - a.do_other_stuff() - - _ = a.__class__ - _ = a.__doc__ - - return a diff --git a/packages/vipeye-internal/src/tests/samples/typeVar7.py b/packages/vipeye-internal/src/tests/samples/typeVar7.py deleted file mode 100644 index 3ab94d8f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar7.py +++ /dev/null @@ -1,167 +0,0 @@ -# This sample tests that generic type variables -# with constrained types properly generate errors. It tests -# both class-defined and function-defined type variables. - -from typing import Generic, TypeVar - - -class Foo: - var1: int - - def __call__(self, val: int): - pass - - def do_stuff(self) -> int: - return 0 - - def __add__(self, val: "Foo") -> "Foo": - return val - - -class Bar: - var1: int - var2: int - - def __call__(self, val: int): - pass - - def do_stuff(self) -> float: - return 0 - - def do_other_stuff(self) -> float: - return 0 - - def __add__(self, val: "Bar") -> "Bar": - return val - - -_T1 = TypeVar("_T1", Foo, Bar) -_T2 = TypeVar("_T2", Foo, Bar, str) - - -class ClassA(Generic[_T1, _T2]): - async def func1(self, a: _T1) -> _T1: - _ = a.var1 - - # This should generate an error. - _ = a.var2 - - # This should generate an error. - _ = a(3.3) - - # This should generate two errors. - _ = a[0] - - # This should generate an error. - _ = a + 1 - - _ = a + a - - a += a - - # This should generate an error. - _ = -a - - # This should generate an error. - a += 3 - - # This should generate an error. - _ = await a - - # This should generate two errors. - for _ in a: - pass - - a.do_stuff() - - # This should generate an error. - a.do_other_stuff() - - _ = a.__class__ - _ = a.__doc__ - - return a - - async def func2(self, a: _T2, b: _T1) -> _T1: - # This should generate two errors. - _ = a.var2 - - # This should generate an error. - _ = a(3.3) - - # This should generate two errors. - _ = a[0] - - # This should generate an error. - _ = a + 1 - - _ = a + a - - a += a - - # This should generate an error. - _ = a + b - - # This should generate an error. - _ = -a - - # This should generate an error. - a += 3 - - # This should generate an error. - _ = await a - - # This should generate an error. - for _ in a: - pass - - # This should generate an error. - a.do_other_stuff() - - _ = a.__class__ - _ = a.__doc__ - - return b - - -_T3 = TypeVar("_T3", float, int, str) -_T4 = TypeVar("_T4", float, int) - - -def custom_add(a: _T3, b: _T4) -> float: - if isinstance(a, str): - return 0 - c = a + b - reveal_type(c, expected_text="float* | int*") - return c - - -class Thing1: - def __add__(self, value: float) -> "Thing1": ... - - def __radd__(self, value: float) -> "Thing1": ... - - -class Thing2: - def __add__(self, value: float) -> "Thing2": ... - - def __radd__(self, value: float) -> "Thing2": ... - - -TThing = TypeVar("TThing", Thing1, Thing2) - - -def func1(x: TThing) -> TThing: - if isinstance(x, Thing1): - return 2 + x - else: - assert isinstance(x, Thing2) - return 3 + x - - -def func2(x: TThing) -> TThing: - if isinstance(x, Thing1): - return x + 2 - else: - assert isinstance(x, Thing2) - return x + 3 diff --git a/packages/vipeye-internal/src/tests/samples/typeVar8.py b/packages/vipeye-internal/src/tests/samples/typeVar8.py deleted file mode 100644 index 21eec072..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar8.py +++ /dev/null @@ -1,82 +0,0 @@ -# This sample tests the handling of a TypeVar symbol when it is -# used as a runtime object rather than a special form. - -import typing as t -import typing_extensions as te # viper: ignore[reportMissingModuleSource] - - -T1 = t.TypeVar("T1") -S1 = t.TypeVar("S1", bound=str) -Ts1 = t.TypeVarTuple("Ts1") -P1 = t.ParamSpec("P1") - -# In these cases, the TypeVar symbol simply represents the TypeVar -# object itself, rather than representing a type variable. -T1.__name__ -S1.__name__ -S1.__bound__ -Ts1.__name__ -P1.__name__ - - -def func1(x: bool, a: T1, b: S1) -> T1 | S1: - reveal_type(T1.__name__, expected_text="str") - reveal_type(S1.__name__, expected_text="str") - reveal_type(Ts1.__name__, expected_text="str") - reveal_type(P1.__name__, expected_text="str") - - # This should generate an error. - a.__name__ - - # This should generate an error. - b.__name__ - - if x: - return a - else: - return b - - -T2 = te.TypeVar("T2") -S2 = te.TypeVar("S2", bound=str) -Ts2 = te.TypeVarTuple("Ts2") -P2 = te.ParamSpec("P2") - -T2.__name__ -S2.__name__ -S2.__bound__ -Ts2.__name__ -P2.__name__ - - -def func2(x: bool, a: T2, b: S2) -> T2 | S2: - reveal_type(T2.__name__, expected_text="str") - reveal_type(S2.__name__, expected_text="str") - reveal_type(Ts2.__name__, expected_text="str") - reveal_type(P2.__name__, expected_text="str") - - if x: - return a - else: - return b - - -def func3(t: t.TypeVar, ts: t.TypeVarTuple = ..., p: t.ParamSpec = ...) -> None: ... - - -func3(T1, Ts1, P1) - -# This should generate an error for Python 3.12 and older because the runtime -# object typing.TypeVar is not the same as typing_extensions.TypeVar. -func3(T2) - - -def func4(t: te.TypeVar, ts: te.TypeVarTuple = ..., p: te.ParamSpec = ...) -> None: ... - - -func4(T2, Ts2, P2) - - -# This should generate an error for Python 3.12 and older because the runtime -# object typing.TypeVar is not the same as typing_extensions.TypeVar. -func4(T1) diff --git a/packages/vipeye-internal/src/tests/samples/typeVar9.py b/packages/vipeye-internal/src/tests/samples/typeVar9.py deleted file mode 100644 index 234473f3..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVar9.py +++ /dev/null @@ -1,148 +0,0 @@ -# This sample tests the reporting of incorrect TypeVar usage within -# a generic function. A TypeVar must appear at least twice to be -# considered legitimate. - -# viper: reportInvalidTypeVarUse=true - -from typing import AnyStr, Callable, Generic, overload -from typing_extensions import TypeVar # viper: ignore[reportMissingModuleSource] - - -_T = TypeVar("_T") -_S = TypeVar("_S") - - -class A(Generic[_T]): - def m1(self, v1: _T) -> None: ... - - # This should generate an error because _S - # is a local typeVar and appears only once. - def m2(self, v1: _S) -> None: ... - - # This should generate an error because _S - # is a local typeVar and appears only once. - def m3(self, v1: _T) -> _S: ... - - -# This should generate an error because _T -# is a local typeVar and appears only once. -def f1(v1: _T) -> None: ... - - -def f2(v1: _T, v2: list[_T]) -> None: ... - - -def f3(v1: _T) -> _T: ... - - -def f4() -> dict[_T, _T]: ... - - -# This should generate an error because _T -# is a local typeVar and appears only once. -def f5() -> list[_T]: ... - - -_T_Bound = TypeVar("_T_Bound", bound=int) -_T_Constrained = TypeVar("_T_Constrained", int, str) - - -# Constrained TypeVars are exempt. -def f6(v1: _T_Constrained): ... - - -# Bound TypeVars are not exempt. -def f7(v1: _T_Bound): ... - - -# Bound TypeVars as type arguments are exempt when used in an -# input parameter annotation. -def f8(v1: list[_T_Bound]): ... - - -# Bound TypeVars as type arguments are not exempt when used in a -# return annotation. -def f9() -> list[_T_Bound]: ... - - -# TypeVars used as type args to a generic type alias are exempt. -MyCallable = Callable[[_T], _T] - - -def f10() -> MyCallable[_T]: ... - - -# This should generate an error because AnyStr can go unsolved. -def f11(x: AnyStr = ...) -> AnyStr: ... - - -# This should generate an error because AnyStr can go unsolved. -def f12(x: AnyStr = ...) -> list[AnyStr]: ... - - -def f13(x: AnyStr = ...) -> AnyStr | None: ... - - -def f14(x: AnyStr = "") -> AnyStr: ... - - -# This should generate an error because AnyStr can go unsolved. -def f15(x: AnyStr = ...) -> list[AnyStr] | None: ... - - -class B(Generic[AnyStr]): - # This should generate an error because AnyStr can go unsolved. - def __init__(self, *, mode: AnyStr = ...) -> None: ... - - -class C(Generic[AnyStr]): - def __init__(self, *, mode: AnyStr = "") -> None: ... - - -@overload -def f16(default: int = ...) -> list[int]: ... - - -@overload -def f16(default: _T) -> list[_T]: ... - - -def f16(default: _T = ...) -> list[int] | list[_T]: ... - - -class ClassA(Generic[_T]): - # This should generate an error because _T can go unsolved. - def __init__(self, x: _T = ...) -> None: ... - - -_T2 = TypeVar("_T2", default=int) - - -class ClassB(Generic[_T2]): - def __init__(self, x: _T2 = ...) -> None: ... - - -# This should generate an error because _T appears only once. -def f17( - arg, # type: _T -): # type: (...) -> int - return 1 - - -def f18( - arg, # type: _T -): # type: (...) -> _T - return arg - - -# This should generate an error because _T appears only once. -def f19( - arg, -): # type: (_T) -> int - return 1 - - -def f20( - arg, # type: _T -): # type: (...) -> _T - return arg diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefault1.py b/packages/vipeye-internal/src/tests/samples/typeVarDefault1.py deleted file mode 100644 index e9d633a7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefault1.py +++ /dev/null @@ -1,99 +0,0 @@ -# This sample tests basic support for PEP 696 -- default types for TypeVars. - -from typing import Any -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVar, - TypeVarTuple, - ParamSpec, - Unpack, -) - -S1 = TypeVar("S1") -S2 = TypeVar("S2", bound=int) -S3 = TypeVar("S3", bytes, str) - -Ts0 = TypeVarTuple("Ts0") - -P0 = ParamSpec("P0") - - -T1 = TypeVar("T1", default=int) - -# This should generate an error because default must be a type expression. -T2 = TypeVar("T2", default=3) - -TInt = TypeVar("TInt", bound=int) -T3 = TypeVar("T3", bound=float, default=TInt) - -# This should generate an error because default must be a subtype of bound. -T4 = TypeVar("T4", bound=int, default=float) - -# This should generate an error because S1 is not a subtype of int. -T6 = TypeVar("T6", bound=int, default=S1) - -T7 = TypeVar("T7", bound=float, default=S2) - -# This should generate an error because S3 is not a subtype of int. -T8 = TypeVar("T8", bound=float, default=S3) - -T9 = TypeVar("T9", bound=list[Any], default=list[S1]) - -T10 = TypeVar("T10", bytes, str, default=str) - -# This should generate an error because str | bytes isn't one of the constrained types. -T11 = TypeVar("T11", bytes, str, default=str | bytes) - -# This should generate an error because S1 isn't one of the constrained types. -T12 = TypeVar("T12", bytes, str, default=S1) - -T13 = TypeVar("T13", int, str) -T14 = TypeVar("T14", int, str, bool, default=T13) - -# This should generate an error because the constraints for T13 are not compatible. -T15 = TypeVar("T15", int, complex, bool, default=T13) - -T16 = TypeVar("T16", bound=int) -T17 = TypeVar("T17", int, complex, bool, default=T16) - -# This should generate an error because the type of T16 is not compatible. -T18 = TypeVar("T18", str, list, default=T16) - - -Ts1 = TypeVarTuple("Ts1", default=Unpack[tuple[int]]) - -# This should generate an error because default must be unpacked tuple. -Ts2 = TypeVarTuple("Ts2", default=tuple[int]) - -# This should generate an error because default must be unpacked tuple. -Ts3 = TypeVarTuple("Ts3", default=int) - -Ts4 = TypeVarTuple("Ts4", default=Unpack[Ts0]) - -# This should generate an error because default must be unpacked. -Ts5 = TypeVarTuple("Ts5", default=Ts0) - -Ts6 = TypeVarTuple("Ts6", default=Unpack[tuple[int, ...]]) - -Ts7 = TypeVarTuple("Ts7", default=Unpack[tuple[S1, S2]]) - - -P1 = ParamSpec("P1", default=[]) - -P2 = ParamSpec("P2", default=[int, str, None, int | None]) - -P3 = ParamSpec("P3", default=[int, S1]) - -P4 = ParamSpec("P4", default=[int]) - -P5 = ParamSpec("P5", default=...) - -# This should generate an error because ParamSpec must be a list of types. -P6 = ParamSpec("P6", default=int) - -# This should generate an error because ParamSpec must be a list of types. -P7 = ParamSpec("P7", default=3) - -# This should generate an error because ParamSpec must be a list of types. -P8 = ParamSpec("P8", default=(1, int)) - -P9 = ParamSpec("P9", default=P0) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefault2.py b/packages/vipeye-internal/src/tests/samples/typeVarDefault2.py deleted file mode 100644 index 1d192c2c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefault2.py +++ /dev/null @@ -1,116 +0,0 @@ -# This sample tests the PEP 695 type parameter syntax extensions introduced -# in PEP 696 (default types for TypeVarLike). - -from typing import Any, ParamSpec, TypeVar, Unpack -from typing_extensions import TypeVarTuple # viper: ignore[reportMissingModuleSource] - -T1 = TypeVar("T1") -Ts1 = TypeVarTuple("Ts1") -P1 = ParamSpec("P1") - - -# This should generate an error because default must be a type expression. -class ClassT1[T = 3]: ... - - -class ClassT2[T: float = int]: ... - - -# This should generate an error because default must be a subtype of bound. -class ClassT3[T: int = float]: ... - - -class ClassT4[T: list[Any] = list[int]]: ... - - -class ClassT5[T: (bytes, str) = str]: ... - - -# This should generate an error because str | bytes isn't one of the constrained types. -class ClassT6[T: (bytes, str) = str | bytes]: ... - - -# This should generate an error because T1 is not a valid default. -class ClassT7[T = T1]: ... - - -# This should generate an error because Ts1 is not a valid default. -class ClassT8[T = Ts1]: ... - - -# This should generate an error because P1 is not a valid default. -class ClassT9[T = P1]: ... - - -class ClassTs1[*Ts = *tuple[int]]: ... - - -class ClassTs2[*Ts = Unpack[tuple[int]]]: ... - - -# This should generate an error because default must be unpacked tuple. -class ClassTs3[*Ts = tuple[int]]: ... - - -# This should generate an error because default must be unpacked tuple. -class ClassTs4[*Ts = int]: ... - - -# This should generate an error because default must be unpacked tuple. -class ClassTs5[*Ts = T1]: ... - - -# This should generate an error because default must be unpacked tuple. -class ClassTs6[*Ts = Ts1]: ... - - -# This should generate an error because default must be unpacked tuple. -class ClassTs7[*Ts = P1]: ... - - -class ClassTs8[*Ts = Unpack[tuple[int, ...]]]: ... - - -# This should generate an error because T1 isn't legal here. -class ClassTs9[*Ts = Unpack[tuple[T1, T1]]]: ... - - -# This should generate an error because ... isn't legal here. -class ClassTs10[*Ts = ...]: ... - - -class ClassP1[**P = [int]]: ... - - -class ClassP2[**P = ...]: ... - - -class ClassP3[**P = []]: ... - - -class ClassP4[**P = [int, str, None, int | None]]: ... - - -# This should generate an error because T1 isn't legal here. -class ClassP5[**P = [T1]]: ... - - -# This should generate an error because ParamSpec must be a list of types. -class ClassP6[**P = int]: ... - - -# This should generate an error because ParamSpec must be a list of types. -class ClassP7[**P = 3]: ... - - -# This should generate an error because ParamSpec must be a list of types. -class ClassP8[**P = [1, int]]: ... - - -# This should generate an error because it combines a traditional ParamSpec -# with a new-style (PEP 695) ParamSpec. -class ClassP9[**P = P1]: ... - - -# This should generate an error because ParamSpec must be a list of types. -class ClassP10[**P = Ts1]: ... diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefault3.py b/packages/vipeye-internal/src/tests/samples/typeVarDefault3.py deleted file mode 100644 index 117aef79..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefault3.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests error handling for PEP 696. TypeVars without default -# types cannot be after TypeVars with default types. - -from typing import Generic -from typing_extensions import TypeVar, TypeVarTuple # viper: ignore[reportMissingModuleSource] - - -T0 = TypeVar("T0", default=object) -T1 = TypeVar("T1") -T2 = TypeVar("T2", default=str) - - -# This should generate an error because T1 is after T2. -class ClassA(Generic[T2, T1]): ... - - -# This should generate an error because T1 is after T2. -class ClassB(dict[T2, T1]): ... - - -class ClassC(dict[T2, T1], Generic[T1, T2]): ... - - -# This should generate an error because T1 is after T2. -def funcA(a: T2, b: T1) -> T1 | T2: ... - - -# This should generate an error because T1 is after T2. -TA_A = dict[T2, T1] - - -class ClassD(Generic[T0]): - def method1(self, a: T0, b: T1, /) -> T0 | T1: ... - - -Ts0 = TypeVarTuple("Ts0") -T3 = TypeVar("T3", default=int) - - -# This should generate an error. -class ClassE(Generic[*Ts0, T3]): ... - - -# This should generate an error. -class ClassF[*Ts0, T1 = bool]: - pass - - -# This should generate an error. -type TA1[*Ts0, T1 = bool] = tuple[*Ts0] | T1 - -# This should generate an error. -TA2 = tuple[*Ts0] | T3 diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefault4.py b/packages/vipeye-internal/src/tests/samples/typeVarDefault4.py deleted file mode 100644 index 5da123d5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefault4.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests error handling for PEP 696. TypeVars without default -# types cannot be after TypeVars with default types. This is the same as -# typeVarDefault3 except that it uses PEP 695 syntax. - -from typing import TypeVar - - -# This should generate an error because T1 is after T2. -class ClassA[T2 = str, T1]: ... - - -# This should generate an error because T1 is after T2. -def funcA[T2 = str, T1](a: T2, b: T1) -> T1 | T2: ... - - -# This should generate an error because T1 is after T2. -type TA_A[T2 = str, T1] = dict[T2, T1] diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefault5.py b/packages/vipeye-internal/src/tests/samples/typeVarDefault5.py deleted file mode 100644 index 67ee439d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefault5.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the handling of TypeVar defaults in classes -# with a constructor that defines an __init__ but no __new__. - -from dataclasses import dataclass -from typing import Any, overload - - -class ClassA: ... - - -@dataclass -class ClassB[T: ClassA = ClassA]: - owner: T - - -def post_comment[T: ClassA](owner: T) -> ClassB[T]: - return ClassB(owner) - - -class ClassC: ... - - -@overload -def func1(x: ClassA) -> ClassA: ... -@overload -def func1[T1 = str](x: ClassC | T1) -> T1: ... -def func1(x: Any) -> Any: ... - - -reveal_type(func1(ClassC()), expected_text="str") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass1.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass1.py deleted file mode 100644 index 71cced3b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass1.py +++ /dev/null @@ -1,130 +0,0 @@ -# This sample tests support for PEP 696 -- default types for TypeVars. -# In particular, it tests the handling of default TypeVar types for -# generic classes. - -from typing import Generic, Self, assert_type - -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - ParamSpec, - TypeVar, - TypeVarTuple, - Unpack, -) - -T1 = TypeVar("T1") -T2 = TypeVar("T2", default=int) -T3 = TypeVar("T3", default=str) - - -class ClassA1(Generic[T2, T3]): - def method1(self) -> Self: - return self - - -reveal_type( - ClassA1.method1, expected_text="(self: ClassA1[int, str]) -> ClassA1[int, str]" -) - - -def func_a1(a: ClassA1, b: ClassA1[float], c: ClassA1[float, float], d: ClassA1[()]): - reveal_type(a, expected_text="ClassA1[int, str]") - reveal_type(b, expected_text="ClassA1[float, str]") - reveal_type(c, expected_text="ClassA1[float, float]") - reveal_type(d, expected_text="ClassA1[int, str]") - - -class ClassA2(Generic[T1, T2, T3]): - def method1(self) -> Self: - return self - - -reveal_type( - ClassA2[int].method1, - expected_text="(self: ClassA2[int, int, str]) -> ClassA2[int, int, str]", -) - - -def func_a2( - a: ClassA2, - b: ClassA2[float], - c: ClassA2[float, float], - d: ClassA2[float, float, float], -): - reveal_type(a, expected_text="ClassA2[Unknown, int, str]") - reveal_type(b, expected_text="ClassA2[float, int, str]") - reveal_type(c, expected_text="ClassA2[float, float, str]") - reveal_type(d, expected_text="ClassA2[float, float, float]") - - -P1 = ParamSpec("P1") -P2 = ParamSpec("P2", default=[int, str]) -P3 = ParamSpec("P3", default=...) - - -class ClassB1(Generic[P2, P3]): ... - - -def func_b1(a: ClassB1, b: ClassB1[[float]], c: ClassB1[[float], [float]]): - reveal_type(a, expected_text="ClassB1[(int, str), ...]") - reveal_type(b, expected_text="ClassB1[(float), ...]") - reveal_type(c, expected_text="ClassB1[(float), (float)]") - - -Ts1 = TypeVarTuple("Ts1") -Ts2 = TypeVarTuple("Ts2", default=Unpack[tuple[int, str]]) -Ts3 = TypeVarTuple("Ts3", default=Unpack[tuple[float, ...]]) -Ts4 = TypeVarTuple("Ts4", default=Unpack[tuple[()]]) - - -class ClassC1(Generic[*Ts2]): ... - - -class ClassC2(Generic[T3, *Ts3]): ... - - -class ClassC3(Generic[T3, *Ts4]): ... - - -def func_c1(a: ClassC1, b: ClassC1[*tuple[float]]): - reveal_type(a, expected_text="ClassC1[int, str]") - reveal_type(b, expected_text="ClassC1[float]") - - -def func_c2(a: ClassC2, b: ClassC2[int], c: ClassC2[int, *tuple[()]]): - reveal_type(a, expected_text="ClassC2[str, *tuple[float, ...]]") - reveal_type(b, expected_text="ClassC2[int, *tuple[float, ...]]") - reveal_type(c, expected_text="ClassC2[int]") - - -def func_c3(a: ClassC3, b: ClassC3[int], c: ClassC3[int, *tuple[float]]): - reveal_type(a, expected_text="ClassC3[str]") - reveal_type(b, expected_text="ClassC3[int]") - reveal_type(c, expected_text="ClassC3[int, float]") - - -P4 = ParamSpec("P4", default=[float, bool]) -P5 = ParamSpec("P5", default=[bool]) -Ts5 = TypeVarTuple("Ts5") - - -class ClassD(Generic[*Ts5, P4, P5]): ... # OK - - -reveal_type( - ClassD[int, str, complex], - expected_text="type[ClassD[int, str, complex, (float, bool), (bool)]]", -) -reveal_type( - ClassD[int, str, [str, complex]], - expected_text="type[ClassD[int, str, (str, complex), (bool)]]", -) - -P6 = ParamSpec("P6", default=[str, int]) - - -class ClassE(Generic[P6]): ... - - -assert_type(ClassE, type[ClassE[str, int]]) -assert_type(ClassE(), ClassE[str, int]) -assert_type(ClassE[[bool, bool]](), ClassE[bool, bool]) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass2.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass2.py deleted file mode 100644 index 9216717b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass2.py +++ /dev/null @@ -1,185 +0,0 @@ -# This sample tests the case where a TypeVar default refers to another -# TypeVar in a class declaration. This sample uses classic TypeVar syntax. -# If you make a change to this file, reflect the change in -# typeVarDefaultClass3.py, which uses PEP 695 syntax. - -from typing import Generic, ParamSpec, TypeVar, TypeVarTuple, Unpack - - -T1 = TypeVar("T1", default=str) -T2 = TypeVar("T2", default=T1) -T3 = TypeVar("T3", default=list[T2]) -T4 = TypeVar("T4", default=dict[T1, T2]) - -# This should generate an error because of the recursive definition. -T5 = TypeVar("T5", default="T5") - - -class ClassA(dict[T1, T2]): ... - - -a1 = ClassA[int]() -reveal_type(a1, expected_text="ClassA[int, int]") - -a2 = ClassA() -reveal_type(a2, expected_text="ClassA[str, str]") - - -# This should generate an error because T2 depends on T1. -class ClassC(Generic[T2, T1]): ... - - -class ClassD(dict[T2, T1], Generic[T1, T2]): ... - - -d1 = ClassD[int]() -reveal_type(d1, expected_text="ClassD[int, int]") - -d2 = ClassD() -reveal_type(d2, expected_text="ClassD[str, str]") - - -# This should generate an error because T5 refers to itself. -class ClassE(Generic[T5]): ... - - -class ClassH(Generic[T1, T2, T3]): ... - - -h1 = ClassH() -reveal_type(h1, expected_text="ClassH[str, str, list[str]]") - -h2 = ClassH[int]() -reveal_type(h2, expected_text="ClassH[int, int, list[int]]") - -h3 = ClassH[int, float]() -reveal_type(h3, expected_text="ClassH[int, float, list[float]]") - - -# This should generate an error because T2 depends on T1. -class ClassI(Generic[T2]): ... - - -# This should generate an error because T4 depends on T2. -class ClassJ(Generic[T1, T4]): ... - - -class ClassK(Generic[T1]): - # This should generate an error because T2 depends on T1, which - # is defined in an outer scope. - class ClassL(Generic[T2]): ... - - -class ClassMChild1(Generic[T1]): - a: T1 - - -class ClassMChild2(Generic[T1]): - b: T1 - - -class ClassM(ClassMChild1[T1], ClassMChild2[T2]): ... - - -m1 = ClassM[int]() -reveal_type(m1.a, expected_text="int") -reveal_type(m1.b, expected_text="int") - -m2 = ClassM() -reveal_type(m2.a, expected_text="str") -reveal_type(m2.b, expected_text="str") - - -class ClassNChild(Generic[T1]): - a: T1 - - -class ClassN(ClassNChild): ... - - -n1 = ClassN() -reveal_type(n1.a, expected_text="str") - - -P1 = ParamSpec("P1", default=...) -P2 = ParamSpec("P2", default=P1) -P3 = ParamSpec("P3", default=P2) -P4 = ParamSpec("P4", default=[int, T1]) - - -class ClassPA(Generic[P1, P2, P3]): ... - - -pa1 = ClassPA() -reveal_type(pa1, expected_text="ClassPA[..., ..., ...]") - -pa2 = ClassPA[[str]]() -reveal_type(pa2, expected_text="ClassPA[(str), (str), (str)]") - -pa3 = ClassPA[..., [float]]() -reveal_type(pa3, expected_text="ClassPA[..., (float), (float)]") - -pa4 = ClassPA[..., [int, int], [float]]() -reveal_type(pa4, expected_text="ClassPA[..., (int, int), (float)]") - - -# This should generate an error because P1 depends on P2. -class ClassPB(Generic[P2, P1]): ... - - -class ClassPC(Generic[T1, P4]): ... - - -pc1 = ClassPC() -reveal_type(pc1, expected_text="ClassPC[str, (int, str)]") - -pc2 = ClassPC[float]() -reveal_type(pc2, expected_text="ClassPC[float, (int, float)]") - -pc3 = ClassPC[float, ...]() -reveal_type(pc3, expected_text="ClassPC[float, ...]") - - -# This should generate an error because P4 depends on T1. -class ClassPD(Generic[P4, T1]): ... - - -Ts1 = TypeVarTuple("Ts1", default=Unpack[tuple[T1, T2]]) -Ts2 = TypeVarTuple("Ts2", default=Unpack[tuple[T1, ...]]) - - -class ClassTA(Generic[T1, T2, *Ts1]): ... - - -ta1 = ClassTA() -reveal_type(ta1, expected_text="ClassTA[str, str, str, str]") - -ta2 = ClassTA[int]() -reveal_type(ta2, expected_text="ClassTA[int, int, int, int]") - -ta3 = ClassTA[int, float]() -reveal_type(ta3, expected_text="ClassTA[int, float, int, float]") - -ta4 = ClassTA[int, float, *tuple[None, ...]]() -reveal_type(ta4, expected_text="ClassTA[int, float, *tuple[None, ...]]") - - -# This should generate an error because Ts1 depends on T2. -# It should also produce an error because T2 comes after a TypeVarTuple. -class ClassTB(Generic[T1, *Ts1, T2]): ... - - -class ClassTC(Generic[T1, *Ts2]): ... - - -tc1 = ClassTC() -reveal_type(tc1, expected_text="ClassTC[str, *tuple[str, ...]]") - -tc2 = ClassTC[int]() -reveal_type(tc2, expected_text="ClassTC[int, *tuple[int, ...]]") - -tc3 = ClassTC[int, *tuple[()]]() -reveal_type(tc3, expected_text="ClassTC[int]") - -tc4 = ClassTC[int, *tuple[None]]() -reveal_type(tc4, expected_text="ClassTC[int, None]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass3.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass3.py deleted file mode 100644 index f276e6bc..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass3.py +++ /dev/null @@ -1,142 +0,0 @@ -# This sample tests the case where a TypeVar default refers to another -# TypeVar in a class declaration. This sample uses PEP 695 syntax. - -from typing import Self, Unpack - - -class ClassA[T1 = str, T2 = T1](dict[T1, T2]): - def method1(self) -> Self: - return self - - -reveal_type( - ClassA[int].method1, expected_text="(self: ClassA[int, int]) -> ClassA[int, int]" -) -reveal_type( - ClassA.method1, expected_text="(self: ClassA[str, str]) -> ClassA[str, str]" -) - -a1 = ClassA[int]() -reveal_type(a1, expected_text="ClassA[int, int]") - -a2 = ClassA() -reveal_type(a2, expected_text="ClassA[str, str]") - - -# This should generate an error because T2 depends on T1. -class ClassC[T2 = T1, T1 = str]: ... - - -class ClassD[T1 = str, T2 = T1](dict[T2, T1]): ... - - -d1 = ClassD[int]() -reveal_type(d1, expected_text="ClassD[int, int]") - -d2 = ClassD() -reveal_type(d2, expected_text="ClassD[str, str]") - - -# This should generate an error because T5 refers to itself. -class ClassE[T5 = T5]: ... - - -class ClassH[T1 = str, T2 = T1, T3 = list[T2]]: ... - - -h1 = ClassH() -reveal_type(h1, expected_text="ClassH[str, str, list[str]]") - -h2 = ClassH[int]() -reveal_type(h2, expected_text="ClassH[int, int, list[int]]") - -h3 = ClassH[int, float]() -reveal_type(h3, expected_text="ClassH[int, float, list[float]]") - - -# This should generate an error because T2 depends on T1. -class ClassI[T2 = T1]: ... - - -# This should generate an error because T4 depends on T2. -class ClassJ[T1 = str, T4 = dict[T1, T2]]: ... - - -class ClassK[T1 = str]: - # This should generate an error because T2 depends on T1, which - # is defined in an outer scope. - class ClassL[T2 = T1]: ... - - -class ClassPA[**P1, **P2 = P1, **P3 = P2]: ... - - -pa1 = ClassPA() -reveal_type(pa1, expected_text="ClassPA[..., ..., ...]") - -pa2 = ClassPA[[str]]() -reveal_type(pa2, expected_text="ClassPA[(str), (str), (str)]") - -pa3 = ClassPA[..., [float]]() -reveal_type(pa3, expected_text="ClassPA[..., (float), (float)]") - -pa4 = ClassPA[..., [int, int], [float]]() -reveal_type(pa4, expected_text="ClassPA[..., (int, int), (float)]") - - -# This should generate an error because P1 depends on P2. -class ClassPB[**P2 = P1, **P1 = ...]: ... - - -class ClassPC[T1 = str, **P4 = [int, T1]]: ... - - -pc1 = ClassPC() -reveal_type(pc1, expected_text="ClassPC[str, (int, str)]") - -pc2 = ClassPC[float]() -reveal_type(pc2, expected_text="ClassPC[float, (int, float)]") - -pc3 = ClassPC[float, ...]() -reveal_type(pc3, expected_text="ClassPC[float, ...]") - - -# This should generate an error because P4 depends on T1. -class ClassPD[**P4 = [int, T1], T1 = str]: ... - - -class ClassTA[T1 = str, T2 = T1, *Ts1 = Unpack[tuple[T1, T2]]]: ... - - -ta1 = ClassTA() -reveal_type(ta1, expected_text="ClassTA[str, str, str, str]") - -ta2 = ClassTA[int]() -reveal_type(ta2, expected_text="ClassTA[int, int, int, int]") - -ta3 = ClassTA[int, float]() -reveal_type(ta3, expected_text="ClassTA[int, float, int, float]") - -ta4 = ClassTA[int, float, *tuple[None, ...]]() -reveal_type(ta4, expected_text="ClassTA[int, float, *tuple[None, ...]]") - - -# This should generate an error because Ts1 depends on T2. -# It will generate a second error because T2 follows a TypeVarTuple. -class ClassTB[T1 = str, *Ts1 = Unpack[tuple[T1, T2]], T2 = T1]: ... - - -class ClassTC[T1 = str, *Ts2 = Unpack[tuple[T1, ...]]]: ... - - -tc1 = ClassTC() -reveal_type(tc1, expected_text="ClassTC[str, *tuple[str, ...]]") - -tc2 = ClassTC[int]() -reveal_type(tc2, expected_text="ClassTC[int, *tuple[int, ...]]") - -tc3 = ClassTC[int, *tuple[()]]() -reveal_type(tc3, expected_text="ClassTC[int]") - -tc4 = ClassTC[int, *tuple[None]]() -reveal_type(tc4, expected_text="ClassTC[int, None]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass4.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass4.py deleted file mode 100644 index d49a061c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultClass4.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the handling of TypeVar defaults with isinstance type -# narrowing. - -from typing import Any, Generic, ParamSpec, TypeVar - - -P = ParamSpec("P", default=...) -R = TypeVar("R", default=Any) - - -class ParentA(Generic[P, R]): ... - - -class ChildA(ParentA[P, R]): - pass - - -def func(x: ParentA[[int], int]): - if isinstance(x, ChildA): - reveal_type(x, expected_text="ChildA[(int), int]") - else: - reveal_type(x, expected_text="ParentA[(int), int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction1.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction1.py deleted file mode 100644 index 5c32d8d3..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction1.py +++ /dev/null @@ -1,60 +0,0 @@ -# This sample tests support for PEP 696 -- default types for TypeVars. -# In particular, it tests the case where a TypeVarLike goes unsolved -# in a call, and a default value is used rather than Unknown. - -from typing import Callable, Generic, Unpack -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - ParamSpec, - TypeVar, - TypeVarTuple, -) - -T = TypeVar("T", default=str) - - -def func1(x: int | T) -> list[T]: ... - - -v1_1 = func1(3.4) -reveal_type(v1_1, expected_text="list[float]") - -v1_2 = func1(3) -reveal_type(v1_2, expected_text="list[str]") - - -P = ParamSpec("P", default=[int, str, str]) - - -class ClassA(Generic[P]): - def __init__(self, x: Callable[P, None]) -> None: ... - - -def func2(x: int | ClassA[P]) -> ClassA[P]: ... - - -def callback1(x: str) -> None: ... - - -v2_1 = func2(ClassA(callback1)) -reveal_type(v2_1, expected_text="ClassA[(x: str)]") - - -v2_2 = func2(3) -reveal_type(v2_2, expected_text="ClassA[(int, str, str)]") - - -Ts = TypeVarTuple("Ts", default=Unpack[tuple[int, str, float]]) - - -def func3(x: int | Callable[[*Ts], None]) -> tuple[*Ts]: ... - - -v3_1 = func3(callback1) -reveal_type(v3_1, expected_text="tuple[str]") - -v3_2 = func3(3) -reveal_type(v3_2, expected_text="tuple[int, str, float]") - - -P2 = ParamSpec("P2", default=...) -P3 = ParamSpec("P3", default="...") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction2.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction2.py deleted file mode 100644 index 32f4b81b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction2.py +++ /dev/null @@ -1,63 +0,0 @@ -# This sample tests support for PEP 696 (default types for TypeVars) -# when used to define generic functions and with defaults type -# expressions that refer to other type variables. - -from typing import Generic, Self -from typing_extensions import TypeVar # viper: ignore[reportMissingModuleSource] - -T1 = TypeVar("T1", default=str) -T2 = TypeVar("T2", default=list[T1]) - - -def func1(x: T1, y: int | T2 = 0) -> T2 | list[T1]: ... - - -v1_1 = func1("hi", 3.4) -reveal_type(v1_1, expected_text="float | list[str]") - -v1_2 = func1("") -reveal_type(v1_2, expected_text="list[str]") - - -# This should generate an error because T1 depends on T2. -def func2(x: T2, y: T1) -> list[T1 | T2]: ... - - -T3 = TypeVar("T3", default=int) - - -class ClassA(Generic[T3]): - def __init__(self, value: T3): - self.value = value - - def func1(self, value: T3) -> Self: - self.value = value - return self - - -T4 = TypeVar("T4", default=int) -T5 = TypeVar("T5", default=T4) - - -class ClassB(Generic[T4, T5]): - @property - def x(self) -> T4: ... - - @property - def y(self) -> T5: ... - - -b1 = ClassB() -reveal_type(b1.x, expected_text="int") -reveal_type(b1.y, expected_text="int") - - -T6 = TypeVar("T6", default=int) -T7 = TypeVar("T7", default=T6) -T8 = TypeVar("T8", default=int | None) - - -class ClassC(Generic[T6, T7, T8]): - def __new__(cls, x: T7, /) -> Self: ... - - def method1(self) -> T7: ... diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction3.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction3.py deleted file mode 100644 index d3f3876a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultFunction3.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests support for PEP 696 (default types for TypeVars) -# when used to define generic functions and with defaults type -# expressions that refer to other type variables. This is the same -# as typeVarDefaultFunction2 except that it uses the PEP 695 syntax. - -from typing import TypeVar - - -def func1[T1, T2 = list[T1]](x: T1, y: int | T2 = 0) -> T2 | list[T1]: ... - - -v1_1 = func1("hi", 3.4) -reveal_type(v1_1, expected_text="float | list[str]") - -v1_2 = func1("") -reveal_type(v1_2, expected_text="list[str]") - - -# This should generate an error because T1 depends on T2. -def func2[T2 = list[T1], T1 = str]() -> None: ... diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias1.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias1.py deleted file mode 100644 index 01e3559e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias1.py +++ /dev/null @@ -1,98 +0,0 @@ -# This sample tests support for PEP 696 -- default types for TypeVars. -# In particular, it tests the handling of default TypeVar types for -# generic type aliases. - -from collections.abc import Callable -from typing import Any, TypeAlias -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVar, - ParamSpec, - TypeVarTuple, - Unpack, -) - - -T1 = TypeVar("T1") -T2 = TypeVar("T2", default=int) -T3 = TypeVar("T3", default=str) - -TA1: TypeAlias = dict[T2, T3] - - -def func_a1(a: TA1, b: TA1[float], c: TA1[float, float]): - reveal_type(a, expected_text="dict[int, str]") - reveal_type(b, expected_text="dict[float, str]") - reveal_type(c, expected_text="dict[float, float]") - - -TA2: TypeAlias = dict[T1, T2] | list[T3] - - -def func_a2(a: TA2, b: TA2[float], c: TA2[float, float], d: TA2[float, float, float]): - reveal_type(a, expected_text="dict[Unknown, int] | list[str]") - reveal_type(b, expected_text="dict[float, int] | list[str]") - reveal_type(c, expected_text="dict[float, float] | list[str]") - reveal_type(d, expected_text="dict[float, float] | list[float]") - - -P1 = ParamSpec("P1") -P2 = ParamSpec("P2", default=[int, str]) -P3 = ParamSpec("P3", default=...) - -TA3: TypeAlias = Callable[P2, Any] | Callable[P3, Any] - - -def func_b1(a: TA3, b: TA3[[float]], c: TA3[[float], [list[float]]]): - reveal_type(a, expected_text="((int, str) -> Any) | ((...) -> Any)") - reveal_type(b, expected_text="((float) -> Any) | ((...) -> Any)") - reveal_type(c, expected_text="((float) -> Any) | ((list[float]) -> Any)") - - -Ts1 = TypeVarTuple("Ts1") -Ts2 = TypeVarTuple("Ts2", default=Unpack[tuple[int, str]]) -Ts3 = TypeVarTuple("Ts3", default=Unpack[tuple[float, ...]]) -Ts4 = TypeVarTuple("Ts4", default=Unpack[tuple[()]]) - -TA4: TypeAlias = tuple[*Ts2] - -TA5: TypeAlias = tuple[T3, *Ts3] - -TA6: TypeAlias = tuple[T3, *Ts4] - - -def func_c1(a: TA4, b: TA4[*tuple[float]]): - reveal_type(a, expected_text="tuple[int, str]") - reveal_type(b, expected_text="tuple[float]") - - -def func_c2(a: TA5, b: TA5[int], c: TA5[int, *tuple[()]]): - reveal_type(a, expected_text="tuple[str, *tuple[float, ...]]") - reveal_type(b, expected_text="tuple[int, *tuple[float, ...]]") - reveal_type(c, expected_text="tuple[int]") - - -def func_c3(a: TA6, b: TA6[int], c: TA6[int, *tuple[float]]): - reveal_type(a, expected_text="tuple[str]") - reveal_type(b, expected_text="tuple[int]") - reveal_type(c, expected_text="tuple[int, float]") - - -P4 = ParamSpec("P4", default=[float, bool]) -P5 = ParamSpec("P5", default=[bool]) -Ts5 = TypeVarTuple("Ts5") - -TA7 = tuple[*Ts5] | Callable[P4, Any] | Callable[P5, Any] - - -def func_d1(x: TA7[int, str, complex]): - reveal_type( - x, - expected_text="tuple[int, str, complex] | ((float, bool) -> Any) | ((bool) -> Any)", - ) - - -def func_d2(x: TA7[int, str, [str, complex]]): - reveal_type( - x, - expected_text="tuple[int, str] | ((str, complex) -> Any) | ((bool) -> Any)", - ) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias2.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias2.py deleted file mode 100644 index 8ba7c5ff..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias2.py +++ /dev/null @@ -1,139 +0,0 @@ -# This sample tests support for PEP 696 (default types for TypeVars). -# In particular, it tests the handling of default TypeVar types for -# generic type aliases when one TypeVar default expression refers -# to another. - -from typing import Callable, Generic, Unpack -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - ParamSpec, - TypeVar, - TypeVarTuple, -) - -T1 = TypeVar("T1", default=str) -T2 = TypeVar("T2", default=T1) -T3 = TypeVar("T3", default=list[T2]) -T4 = TypeVar("T4", default=dict[T1, T2]) - -# This should generate an error because of the recursive definition. -T5 = TypeVar("T5", default="T5") - -TA_A = dict[T1, T2] - - -def func1(a1: TA_A[int], a2: TA_A): - reveal_type(a1, expected_text="dict[int, int]") - reveal_type(a2, expected_text="dict[str, str]") - - -# This should generate an error because T2 depends on T1. -TA_B = dict[T2, T1] - -# This should generate an error because T5 refers to itself. -TA_C = list[T5] - -TA_D = tuple[T1, T2, T3] - - -def func2(d1: TA_D, d2: TA_D[int], d3: TA_D[int, float]): - reveal_type(d1, expected_text="tuple[str, str, list[str]]") - reveal_type(d2, expected_text="tuple[int, int, list[int]]") - reveal_type(d3, expected_text="tuple[int, float, list[float]]") - - -# This should generate an error because T2 depends on T1. -TA_E = list[T2] - -# This should generate an error because T4 depends on T2. -TA_F = dict[T2, T4] - - -class ClassK(Generic[T1]): - # This should generate an error because T2 depends on T1, which - # is defined in an outer scope. - TA_G = list[T2] - - -P1 = ParamSpec("P1", default=...) -P2 = ParamSpec("P2", default=P1) -P3 = ParamSpec("P3", default=P2) -P4 = ParamSpec("P4", default=[int, T1]) - -TA_PA = tuple[Callable[P1, None], Callable[P2, None], Callable[P3, None]] - - -def func3( - pa1: TA_PA, - pa2: TA_PA[[str]], - pa3: TA_PA[..., [float]], - pa4: TA_PA[..., [int, int], [float]], -): - reveal_type(pa1, expected_text="tuple[(...) -> None, (...) -> None, (...) -> None]") - reveal_type(pa2, expected_text="tuple[(str) -> None, (str) -> None, (str) -> None]") - reveal_type( - pa3, expected_text="tuple[(...) -> None, (float) -> None, (float) -> None]" - ) - reveal_type( - pa4, expected_text="tuple[(...) -> None, (int, int) -> None, (float) -> None]" - ) - - -# This should generate an error because P1 depends on P2. -TA_PB = tuple[Callable[P2, None], Callable[P1, None]] - -TA_PC = T1 | Callable[P4, T1] - - -def func4(pc1: TA_PC, pc2: TA_PC[float], pc3: TA_PC[float, ...]): - reveal_type(pc1, expected_text="str | ((int, str) -> str)") - reveal_type(pc2, expected_text="float | ((int, float) -> float)") - reveal_type(pc3, expected_text="float | ((...) -> float)") - - -# This should generate an error because P4 depends on T1. -TA_PD = Callable[P4, T1] - - -Ts1 = TypeVarTuple("Ts1", default=Unpack[tuple[T1, T2]]) -Ts2 = TypeVarTuple("Ts2", default=Unpack[tuple[T1, ...]]) - - -class ClassTA(Generic[T1, T2, *Ts1]): ... - - -TA_TA = ClassTA[T1, T2, *Ts1] - - -def func5( - ta1: TA_TA, - ta2: TA_TA[int], - ta3: TA_TA[int, float], - ta4: TA_TA[int, float, *tuple[None, ...]], -): - reveal_type(ta1, expected_text="ClassTA[str, str, str, str]") - reveal_type(ta2, expected_text="ClassTA[int, int, int, int]") - reveal_type(ta3, expected_text="ClassTA[int, float, int, float]") - reveal_type(ta4, expected_text="ClassTA[int, float, *tuple[None, ...]]") - - -# This should generate an error because Ts1 depends on T2. -# It should also generate a second error because T2 follows a TypeVarTuple. -TA_TB = tuple[T1, *Ts1, T2] - - -class ClassTC(Generic[T1, *Ts2]): ... - - -TA_TC = ClassTC[T1, *Ts2] - - -def func6( - tc1: TA_TC, - tc2: TA_TC[int], - tc3: TA_TC[int, *tuple[()]], - tc4: TA_TC[int, *tuple[None]], -): - reveal_type(tc1, expected_text="ClassTC[str, *tuple[str, ...]]") - reveal_type(tc2, expected_text="ClassTC[int, *tuple[int, ...]]") - reveal_type(tc3, expected_text="ClassTC[int]") - reveal_type(tc4, expected_text="ClassTC[int, None]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias3.py b/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias3.py deleted file mode 100644 index bbc23c04..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarDefaultTypeAlias3.py +++ /dev/null @@ -1,125 +0,0 @@ -# This sample tests support for PEP 696 (default types for TypeVars). -# In particular, it tests the handling of default TypeVar types for -# generic type aliases when one TypeVar default expression refers -# to another. This is the same as typeVarDefaultTypeAlias2 except -# that it uses PEP 695 syntax. - -from typing import Callable, Unpack - -type TA_A[T1 = str, T2 = T1] = dict[T1, T2] - - -def func1(a1: TA_A[int], a2: TA_A): - reveal_type(a1, expected_text="dict[int, int]") - reveal_type(a2, expected_text="dict[str, str]") - - -# This should generate an error because T2 depends on T1. -type TA_B[T2 = T1, T1 = str] = None - -# This should generate an error because T5 refers to itself. -type TA_C[T5 = T5] = None - -type TA_D[T1 = str, T2 = T1, T3 = list[T2]] = tuple[T1, T2, T3] - - -def func2(d1: TA_D, d2: TA_D[int], d3: TA_D[int, float]): - reveal_type(d1, expected_text="tuple[str, str, list[str]]") - reveal_type(d2, expected_text="tuple[int, int, list[int]]") - reveal_type(d3, expected_text="tuple[int, float, list[float]]") - - -# This should generate an error because T2 depends on T1. -type TA_E[T2 = T1] = list[T2] - -# This should generate two errors because T4 depends on T2 and T1. -type TA_F[T2 = T1, T4 = dict[T1, T2]] = dict[T2, T4] - - -class ClassK[T1]: - # This should generate an error because T2 depends on T1, which - # is defined in an outer scope. - type TA_G[T2 = T1] = list[T2] - - -type TA_PA[**P1, **P2 = P1, **P3 = P2] = tuple[ - Callable[P1, None], Callable[P2, None], Callable[P3, None] -] - - -def func3( - pa1: TA_PA, - pa2: TA_PA[[str]], - pa3: TA_PA[..., [float]], - pa4: TA_PA[..., [int, int], [float]], -): - reveal_type(pa1, expected_text="tuple[(...) -> None, (...) -> None, (...) -> None]") - reveal_type(pa2, expected_text="tuple[(str) -> None, (str) -> None, (str) -> None]") - reveal_type( - pa3, expected_text="tuple[(...) -> None, (float) -> None, (float) -> None]" - ) - reveal_type( - pa4, expected_text="tuple[(...) -> None, (int, int) -> None, (float) -> None]" - ) - - -# This should generate an error because P1 depends on P2. -type TA_PB[**P2 = P1, **P1 = ...] = tuple[Callable[P2, None], Callable[P1, None]] - -type TA_PC[ - T1 = str, - **P4 = [ - int, - T1, - ], -] = T1 | Callable[P4, T1] - - -def func4(pc1: TA_PC, pc2: TA_PC[float], pc3: TA_PC[float, ...]): - reveal_type(pc1, expected_text="str | ((int, str) -> str)") - reveal_type(pc2, expected_text="float | ((int, float) -> float)") - reveal_type(pc3, expected_text="float | ((...) -> float)") - - -# This should generate an error because P4 depends on T1. -type TA_PD[**P4 = [int, T1], T1 = str] = Callable[P4, T1] - - -class ClassTA[T1, T2, *Ts1]: ... - - -type TA_TA[T1 = str, T2 = T1, *Ts1 = Unpack[tuple[T1, T2]]] = ClassTA[T1, T2, *Ts1] - - -def func5( - ta1: TA_TA, - ta2: TA_TA[int], - ta3: TA_TA[int, float], - ta4: TA_TA[int, float, *tuple[None, ...]], -): - reveal_type(ta1, expected_text="ClassTA[str, str, str, str]") - reveal_type(ta2, expected_text="ClassTA[int, int, int, int]") - reveal_type(ta3, expected_text="ClassTA[int, float, int, float]") - reveal_type(ta4, expected_text="ClassTA[int, float, *tuple[None, ...]]") - - -# This should generate an error because Ts1 depends on T2. -type TA_TB[T1 = str, *Ts1 = Unpack[tuple[T1, T2]], T2 = T1] = tuple[T1, *Ts1, T2] - - -class ClassTC[T1, *Ts2]: ... - - -type TA_TC[T1 = str, *Ts2 = Unpack[tuple[T1, ...]]] = ClassTC[T1, *Ts2] - - -def func6( - tc1: TA_TC, - tc2: TA_TC[int], - tc3: TA_TC[int, *tuple[()]], - tc4: TA_TC[int, *tuple[None]], -): - reveal_type(tc1, expected_text="ClassTC[str, *tuple[str, ...]]") - reveal_type(tc2, expected_text="ClassTC[int, *tuple[int, ...]]") - reveal_type(tc3, expected_text="ClassTC[int]") - reveal_type(tc4, expected_text="ClassTC[int, None]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple1.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple1.py deleted file mode 100644 index de5c9e7a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple1.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests various conditions under which variadic -# type variables can and cannot be used. - -# viper: reportMissingModuleSource=false - -from typing import Generic, TypeVar, Union -from typing_extensions import TypeVarTuple, Unpack - - -_T = TypeVar("_T") -_Xs = TypeVarTuple("_Xs") - - -class ClassA(Generic[_T, Unpack[_Xs]]): - def __init__(self, *args: Unpack[_Xs]) -> None: - reveal_type(args, expected_text="tuple[*_Xs@ClassA]") - - # This should generate two errors. - def func2(self) -> Union[_Xs]: ... - - def func3(self) -> tuple[Unpack[_Xs]]: ... - - # This should generate an error. - def func4(self) -> tuple[_Xs]: ... - - def func5(self) -> "ClassA[int, str, Unpack[_Xs]]": ... - - # This should be an error because list doesn't accept a variadic TypeVar. - x: list[_Xs] = [] - - # This should generate an error. - y: _Xs = () - - # This should generate an error. - z: tuple[_Xs, ...] - - -# This should generate an error. -class ClassB(Generic[_Xs]): ... - - -# This should generate an error. -x: list[_Xs] = [] - -# This should generate an error. -y: _Xs = () - - -# This should generate an error because of the name mismatch. -BadName = TypeVarTuple("Ts1") - -# This should generate TypeVarTuple cannot have constraints. -Ts2 = TypeVarTuple("Ts2", int, str) - -# This should generate TypeVarTuple cannot be covariant. -Ts3 = TypeVarTuple("Ts3", covariant=True) - -# This should generate TypeVarTuple cannot be contravariant. -Ts4 = TypeVarTuple("Ts4", contravariant=True) - -# This should generate TypeVarTuple does not accept other keyword arguments. -Ts5 = TypeVarTuple("Ts5", other=True) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple10.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple10.py deleted file mode 100644 index e2ebe8f0..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple10.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests the handling of variadic type variables when used -# in conjunction with unpacked tuples. - -from __future__ import annotations -from typing import Any, Generic, NewType, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -DType = TypeVar("DType") -Shape = TypeVarTuple("Shape") - -Batch = NewType("Batch", int) -Height = NewType("Height", int) -Width = NewType("Width", int) -Channels = NewType("Channels", int) - - -class Array(Generic[DType, Unpack[Shape]]): - def __abs__(self) -> Array[DType, Unpack[Shape]]: ... - - def __add__( - self, other: Array[DType, Unpack[Shape]] - ) -> Array[DType, Unpack[Shape]]: ... - - -def process_batch_channels( - x: Array[Batch, Unpack[tuple[Any, ...]], Channels], -) -> None: ... - - -def expect_variadic_array1(x: Array[Batch, Unpack[Shape]]) -> tuple[Unpack[Shape]]: ... - - -def expect_variadic_array2(x: Array[Batch, Unpack[tuple[Any, ...]]]) -> None: ... - - -def expect_precise_array(x: Array[Batch, Height, Width, Channels]) -> None: ... - - -def func1(x: Array[Batch, Height, Width, Channels]): - process_batch_channels(x) - - expect_precise_array(x) - - -def func2(y: Array[Batch, Channels]): - process_batch_channels(y) - - # This should generate an error because the type args don't match. - expect_precise_array(y) - - -def func3(z: Array[Batch]): - # This should generate an error because Channels is missing - process_batch_channels(z) - - -def func4(y: Array[Any, Unpack[tuple[Any, ...]]]): - reveal_type(y, expected_text="Array[Any, *tuple[Any, ...]]") - expect_variadic_array1(y) - expect_variadic_array2(y) - expect_precise_array(y) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple11.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple11.py deleted file mode 100644 index 23ac43ed..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple11.py +++ /dev/null @@ -1,71 +0,0 @@ -# This sample tests packing and unpacking operations with -# variadic type variables. It is the same as variadicTypeVar4.py -# except that it uses the * operator rather than Unpack. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import Generic, NewType, Union -from typing_extensions import TypeVarTuple # viper: ignore[reportMissingModuleSource] - - -Shape = TypeVarTuple("Shape") - - -class Array(Generic[*Shape]): - def __init__(self, *shape: *Shape): - self.shape = shape - - def __abs__(self) -> "Array[*Shape]": ... - - def __add__(self, other: "Array[*Shape]") -> "Array[*Shape]": ... - - -Height = NewType("Height", int) -Width = NewType("Width", int) -x: Array[Height, Width] = Array(Height(480), Width(640)) -reveal_type(x.shape, expected_text="tuple[Height, Width]") -reveal_type(abs(x), expected_text="Array[Height, Width]") -reveal_type(x + abs(x), expected_text="Array[Height, Width]") - - -_Xs = TypeVarTuple("_Xs") - - -def func1(a: tuple[*_Xs], b: tuple[*_Xs]) -> Union[*_Xs]: ... - - -def func2(a: tuple[int, *_Xs], b: tuple[int, *_Xs]) -> Union[*_Xs]: ... - - -def func3(p1: tuple[int], p2: tuple[int, str], p3: tuple[int, int]): - # This should generate an error. - v1 = func1(p1, p2) - - # This should generate an error. - v2 = func2(p1, p2) - - v3 = func2(p2, p2) - reveal_type(v3, expected_text="str") - - v4 = func2((3, "hi"), p2) - reveal_type(v4, expected_text="str") - - # This should generate an error. - func2((3, 3), p2) - - v5 = func2((3, 3), p3) - reveal_type(v5, expected_text="int") - - -def func4(a: int, *args: *_Xs, **kwargs: str) -> tuple[int, *_Xs]: ... - - -c1 = func4(4, 5.4, 6j, b="3", c="5") -reveal_type(c1, expected_text="tuple[int, float, complex]") - -c2 = func4(4, b="3", c="5") -reveal_type(c2, expected_text="tuple[int]") - -# This should generate an error. -c3 = func4(b="3", c="5") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple12.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple12.py deleted file mode 100644 index af3ccf6a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple12.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the case where a variadic TypeVar is used in -# conjunction with a keyword-only parameter. It also tests protocol -# invariance validation when a TypeVarTuple is used in the protocol -# along with a non-variadic TypeVar. - -# viper: strict - -from typing import Protocol, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -class CallbackA(Protocol[*Ts, T]): - def __call__(self, *args: *Ts, keyed: T) -> tuple[Unpack[Ts], T]: ... - - -def example(a: int, b: str, *, keyed: bool) -> tuple[int, str, bool]: - return (a, b, keyed) - - -a: CallbackA[int, str, bool] = example - -reveal_type( - a, expected_text="(a: int, b: str, *, keyed: bool) -> tuple[int, str, bool]" -) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple13.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple13.py deleted file mode 100644 index 96952c9b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple13.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the case where a variadic TypeVar is unpacked -# in a call expression that invokes a call that accepts an unpacked -# TypeVarTuple. - -from typing import Protocol, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -class CallbackPosOnly(Protocol[Unpack[Ts]]): - def __call__(self, *args: *Ts) -> tuple[Unpack[Ts]]: ... - - -def invoke_posonly(fn: CallbackPosOnly[Unpack[Ts]], *args: *Ts) -> tuple[Unpack[Ts]]: - return fn(*args) - - -class CallbackKeyed(Protocol[Unpack[Ts]]): - def __call__(self, *args: *Ts, keyed: bool) -> tuple[Unpack[Ts]]: ... - - -def invoke_keyed(fn: CallbackKeyed[Unpack[Ts]], *args: *Ts) -> tuple[Unpack[Ts]]: - return fn(*args, keyed=True) - - -def invoke_keyed_should_fail( - fn: CallbackKeyed[Unpack[Ts]], *args: *Ts -) -> tuple[Unpack[Ts]]: - # This should generate an error because "keyed" should - # be interpreted as a keyword-only parameter. - return fn(*args, True) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple14.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple14.py deleted file mode 100644 index 1a7c922b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple14.py +++ /dev/null @@ -1,109 +0,0 @@ -# This sample tests the matching of a traditional *args parameter -# and a *args unpacked Tuple to a *args TypeVarTuple. - -from typing import Callable, TypeVar -from typing_extensions import TypeVarTuple # viper: ignore[reportMissingModuleSource] - -Ts = TypeVarTuple("Ts") -R = TypeVar("R") - - -def call_with_params(func: Callable[[*Ts], R], *params: *Ts) -> R: - # This should generate an error because it's missing a *. - func(params) - - return func(*params) - - -def callback1(*args: int) -> int: ... - - -def callback2(*args: *tuple[int, int]) -> int: ... - - -call_with_params(callback1) -call_with_params(callback1, 1, 2, 3) - -# This should generate an error. -call_with_params(callback1, "1") - -# This should generate an error. -call_with_params(callback2) - -call_with_params(callback2, 1, 1) - -# This should generate an error. -call_with_params(callback2, 1, "") - - -def callback3(*args: *tuple[int, *tuple[str, ...], int]) -> int: ... - - -# This should generate an error. -call_with_params(callback3) - -call_with_params(callback3, 1, 2) - -call_with_params(callback3, 1, "hi", 2) - -call_with_params(callback3, 1, "hi", "hi", 2) - -# This should generate an error. -call_with_params(callback3, 1, 1, 2) - - -class ClassA: - @classmethod - def method1(cls, *shape: *Ts) -> tuple[*Ts]: ... - - -def func1(target: Callable[[*Ts], int]) -> tuple[*Ts]: ... - - -def func2(a: int, b: str, /) -> int: ... - - -def func3(action: Callable[[int, str], int]): - v1 = func1(func2) - reveal_type(v1, expected_text="tuple[int, str]") - - v2 = func1(action) - reveal_type(v2, expected_text="tuple[int, str]") - - -def func4(*args: *tuple[int, str]): ... - - -func4(1, "") - -# This should generate an error. -func4() - -# This should generate an error. -func4(1) - -# This should generate an error. -func4(1, "", "") - - -def func5(*args: *tuple[int, *tuple[str, ...], int]): ... - - -func5(1, 1) -func5(1, "", 1) -func5(1, "", "", 1) - -# This should generate an error. -func5() - -# This should generate an error. -func5(1) - -# This should generate an error. -func5("") - -# This should generate an error. -func5(1, "") - -# This should generate an error. -func5(1, "", "") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple15.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple15.py deleted file mode 100644 index 2edcf425..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple15.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the capture of an unbounded (unknown-length) tuple -# by a TypeVarTuple. - -from typing import Any, Generic -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -Shape = TypeVarTuple("Shape") - - -class Array(Generic[Unpack[Shape]]): ... - - -def func0(x: Array[Unpack[Shape]]) -> Array[Unpack[Shape]]: ... - - -def func1(y: Array[int, Unpack[tuple[Any, ...]]]): - reveal_type(func0(y), expected_text="Array[int, *tuple[Any, ...]]") - - -def func2(y: Array[Unpack[tuple[int, ...]], int]): - reveal_type(func0(y), expected_text="Array[*tuple[int, ...], int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple16.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple16.py deleted file mode 100644 index 22ed1b47..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple16.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the case where a classmethod or staticmethod are -# used with a TypeVarTuple that requires specialization. - -from typing import Generic - -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -T2 = TypeVarTuple("T2") - - -class Base(Generic[Unpack[T2]]): - @classmethod - def method1(cls, *args: Unpack[T2]) -> int: ... - - @staticmethod - def method2(*args: Unpack[T2]) -> int: ... - - -class Child(Base[int, str]): ... - - -Child.method1(1, "") -Child.method2(1, "") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple17.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple17.py deleted file mode 100644 index 979d8b83..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple17.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the case where an unpacked tuple argument in a call -# expression is matched to an `*args` parameter that has a declared type -# that includes an unpacked TypeVarTuple. - -from typing_extensions import TypeVarTuple # viper: ignore[reportMissingModuleSource] - -Ts = TypeVarTuple("Ts") - - -def call0(*args: *Ts) -> tuple[*Ts]: ... - - -def call1(*args: *tuple[int, *Ts]) -> tuple[*Ts]: ... - - -def call2(*args: *tuple[*Ts, float]) -> tuple[*Ts]: ... - - -def call3(*args: *tuple[int, *Ts, float]) -> tuple[*Ts]: ... - - -def call4(*args: *tuple[*tuple[int, *tuple[*Ts], float]]) -> tuple[*Ts]: ... - - -def func1(*args: *tuple[int, str]): - reveal_type(call0(*args), expected_text="tuple[int, str]") - - -def func2(*args: *tuple[int, ...]): - reveal_type(call0(*args), expected_text="tuple[int, ...]") - - -def func3(*args: *tuple[int, *tuple[str, ...], float]): - reveal_type(call0(*args), expected_text="tuple[int, *tuple[str, ...], float]") - - -def func4(*args: *Ts) -> tuple[*Ts]: - call0(*args) - return args - - -def func5(x: int, y: str, z: float): - v1 = call1(*(x, y, z)) - reveal_type(v1, expected_text="tuple[str, float]") - - v2 = call2(*(x, y, z)) - reveal_type(v2, expected_text="tuple[int, str]") - - v3 = call3(*(x, y, z)) - reveal_type(v3, expected_text="tuple[str]") - - v4 = call4(*(x, *(y, z))) - reveal_type(v4, expected_text="tuple[str]") - - -def func6(*args: *tuple[int, *tuple[None, ...], float]): - reveal_type(call2(*args), expected_text="tuple[int, *tuple[None, ...]]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple18.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple18.py deleted file mode 100644 index cbe5778c..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple18.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the case where an unpacked TypeVar is used in -# an iterator. - -from typing import Any, Callable, TypeVarTuple - - -Ts = TypeVarTuple("Ts") - - -def func1(f: Callable[[*Ts], Any], p: tuple[*Ts]): - f(*p) - - # This should generate an error because p is not unpacked. - f(p) - - for i in p: - # This should generate an error. - f(i) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple19.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple19.py deleted file mode 100644 index b81b2307..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple19.py +++ /dev/null @@ -1,76 +0,0 @@ -# This sample tests the case where an unpacked TypeVarTuple is used -# as one or more type arguments for a tuple. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import Generator, Iterable, TypeVar, TypeVarTuple, Union - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -def func1(a: Iterable[T], b: Iterable[T]): - i = iter(a) - j = iter(b) - while True: - try: - yield (next(i), next(j)) - except StopIteration: - break - - -reveal_type( - func1, - expected_text="(a: Iterable[T@func1], b: Iterable[T@func1]) -> Generator[tuple[T@func1, T@func1], Any, None]", -) - - -def func2(a: tuple[*Ts], b: tuple[*Ts]): - for i in func1(a, b): - yield i - - -reveal_type( - func2, - expected_text="(a: tuple[*Ts@func2], b: tuple[*Ts@func2]) -> Generator[tuple[Union[*Ts@func2], Union[*Ts@func2]], Any, None]", -) - - -def func3(): - v1 = func2((1, "foo"), (2, "bar")) - reveal_type(v1, expected_text="Generator[tuple[int | str, int | str], Any, None]") - - for i in v1: - reveal_type(i, expected_text="tuple[int | str, int | str]") - - -def func5(x: "Iterable[Union[*Ts]]") -> Iterable[Union[*Ts]]: ... - - -def func6(): - v1: list[int] = [i for i in func5([1, 2, 3])] - v2: list[int | str] = [i for i in func5([1, "foo"])] - - -def func7(t: "tuple[*Ts]") -> "tuple[Union[*Ts], ...]": ... - - -def func8(a: int, b: str): - v1 = func7(((a, b),)) - reveal_type(v1, expected_text="tuple[tuple[int, str], ...]") - - -def func9(x: "tuple[T, ...]", y: "tuple[*Ts]") -> Generator[T | Union[*Ts], None, None]: - z = x + y - reveal_type(z, expected_text="tuple[T@func9 | Union[*Ts@func9], ...]") - for e in z: - reveal_type(e, expected_text="T@func9 | Union[*Ts@func9]") - yield e - - -def func10(x: tuple[*Ts]): ... - - -def func11(x: tuple[*Ts, int, int]): - func10(x) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple2.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple2.py deleted file mode 100644 index d67c45cc..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple2.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests various conditions under which Unpack -# can and cannot be used. - -# viper: reportMissingModuleSource=false - -from typing import Generic, TypeVar, Union -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - - -_T = TypeVar("_T") -_Xs = TypeVarTuple("_Xs") - - -class ClassA(Generic[_T, Unpack[_Xs]]): - def __init__(self, *shape: Unpack[_Xs]): - self.x: tuple[Unpack[_Xs]] = shape - - # This should generate an error - self.y: _Xs = shape - - # This should generate two errors - def func1(self) -> Union[Unpack[_Xs]]: ... - - # This should generate an error - def func2(self) -> tuple[Unpack[_T]]: ... - - # This should generate an error - def func3(self) -> tuple[Unpack[int]]: ... - - # This should generate an error - def func4(self) -> tuple[Unpack[_Xs, _Xs]]: ... - - # This should generate an error. - a: list[Unpack[_Xs]] = [] - - # This should generate an error. - b: Unpack[_Xs] = () - - -# This should generate an error. -x: list[Unpack[_Xs]] = [] - -# This should generate an error. -y: Unpack[_Xs] = () - -# This should generate an error. -z: Unpack = () - - -class Array(Generic[Unpack[_Xs]]): ... - - -# This should generate two errors because _Xs must be unpacked. -def func0(value: Array[_Xs]) -> tuple[complex, _Xs, str]: ... diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple20.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple20.py deleted file mode 100644 index a27b9d18..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple20.py +++ /dev/null @@ -1,26 +0,0 @@ -# This sample tests the case where an unpacked TypeVarTuple is assigned -# to a non-variadic TypeVar during constraint solving. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import TypeVar, Tuple, Union -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - reveal_type, - TypeVarTuple, -) - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -def func1(*args: T) -> Tuple[T, ...]: - return args - - -def func2(x: "Tuple[*Ts]") -> list[Union[*Ts]]: - r = func1(*x) - reveal_type(r, expected_text="Tuple[Union[*Ts@func2], ...]") - v = [i for i in r] - reveal_type(v, expected_text="list[Union[*Ts@func2]]") - return v diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple21.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple21.py deleted file mode 100644 index 2987476b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple21.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the case where a tuple including an unpacked -# TypeVarTuple is used in an unpacked argument and assigned to another -# TypeVarTuple parameter. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import TypeVar, TypeVarTuple, Union, Unpack - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -def f(*args: Unpack[Ts]) -> Union[Unpack[Ts]]: ... - - -def g(x: tuple[T, Unpack[Ts]]) -> Union[T, Unpack[Ts]]: - f(*x) - return x[0] diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple22.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple22.py deleted file mode 100644 index 72c853f2..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple22.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample tests the case where a TypeVarTuple is solved using -# a tuple with literal values. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import Callable, Literal, TypeVarTuple, Union, Unpack - -Ts = TypeVarTuple("Ts") - - -def func1( - f: Callable[[Unpack[Ts]], None], vs: tuple[Unpack[Ts]] -) -> Union[Unpack[Ts]]: ... - - -def func2(f: Callable[[Literal[1, 2]], None], vs: tuple[Literal[1, 2]]): - v1 = func1(f, vs) - reveal_type(v1, expected_text="Literal[1, 2]") - - -def func3(f: Callable[[Literal[1, 2, 3]], None], vs: tuple[Literal[1, 2]]): - v1 = func1(f, vs) - reveal_type(v1, expected_text="Literal[1, 2]") - - -def func4(f: Callable[[int], None], vs: tuple[Literal[1, 2]]): - v1 = func1(f, vs) - reveal_type(v1, expected_text="int") - - -def func5(f: Callable[[Literal[1, 2]], None], vs: tuple[Literal[1, 2, 3]]): - # This should result in an error. - func1(f, vs) - - -def func6(f: Callable[[Literal[1, 2]], None], vs: tuple[int]): - # This should result in an error. - func1(f, vs) - - -def func7(f: Callable[[int, int, int], None], vs: tuple[int, ...]): - # This should result in an error because of a size mismatch. - func1(f, vs) - - -def func8(f: Callable[[Unpack[tuple[int, ...]]], None], vs: tuple[int]): - v1 = func1(f, vs) - reveal_type(v1, expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple23.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple23.py deleted file mode 100644 index a2a11790..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple23.py +++ /dev/null @@ -1,84 +0,0 @@ -# This sample tests a complex combination of TypeVarTuple, -# unpacking, bidirectional type inference, and recursive calls. - -from dataclasses import dataclass -from typing import Generic, TypeVar, TypeVarTuple, Callable - -X = TypeVar("X") -Y = TypeVar("Y") -Z = TypeVar("Z") -Xs = TypeVarTuple("Xs") -Ys = TypeVarTuple("Ys") - - -def nil() -> tuple[()]: - return () - - -def cons( - f: Callable[[X], Y], - g: Callable[[*Xs], tuple[*Ys]], -) -> Callable[[X, *Xs], tuple[Y, *Ys]]: - def wrapped(x: X, *xs: *Xs) -> tuple[Y, *Ys]: - y, ys = f(x), g(*xs) - return y, *ys - - return wrapped - - -def star(f: Callable[[X], Y]) -> Callable[[*tuple[X, ...]], tuple[Y, ...]]: - def wrapped(*xs: X): - if not xs: - return nil() - return cons(f, star(f))(*xs) - - return wrapped - - -@dataclass(frozen=True) -class Tree(Generic[X, Y]): - left: X - right: Y - - -def lift( - f: Callable[[*Xs], tuple[*Ys]], -) -> Callable[[Tree[Z, tuple[*Xs]]], Tree[Z, tuple[*Ys]]]: ... - - -def test( - f: Callable[[X], Y], -) -> Callable[[Tree[Z, tuple[X, ...]]], Tree[Z, tuple[Y, ...]]]: - return lift(star(f)) - - -def parallel( - f: Callable[[X], Y], - g: Callable[[*Xs], tuple[*Ys]], -) -> Callable[[X, *Xs], tuple[Y, *Ys]]: - def wrapped(a: X, *bs: *Xs): - return f(a), *g(*bs) - - return wrapped - - -def identity(x: X) -> X: - return x - - -def parallel_identity(*xs: *Xs) -> tuple[*Xs]: - return xs - - -Shape = TypeVarTuple("Shape") -DType = TypeVar("DType") - - -class NDArray(Generic[*Shape, DType]): ... - - -def insert(values: NDArray[*Shape, DType]) -> NDArray[int, *Shape, DType]: ... - - -def prepend(values: NDArray[*Shape, DType]) -> NDArray[int, *Shape, DType]: - return insert(values) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple24.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple24.py deleted file mode 100644 index a94e134e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple24.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the handling of `Union[*Ts]` in certain cases. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import Generic, TypeVarTuple, Union - -Ts = TypeVarTuple("Ts") - - -class ClassA(Generic[*Ts]): - def __init__(self) -> None: - self.x: list[Union[*Ts]] = [] - - reveal_type(self.x, expected_text="list[Union[*Ts@ClassA]]") - - def method(self) -> Union[*Ts]: ... - - -a1 = ClassA[int, bool, str]() - -reveal_type(a1.method(), expected_text="int | bool | str") -reveal_type(a1.x, expected_text="list[int | bool | str]") - - -def func1(t0: tuple[*Ts], t1: tuple[*Ts]): - return all(v0 == v1 for v0, v1 in zip(t0, t1)) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple25.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple25.py deleted file mode 100644 index e5a75c37..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple25.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a TypeVarTuple is used in a -# nested callable type. - -from typing import Callable, TypeVarTuple - -Ts = TypeVarTuple("Ts") - - -def func1(g: Callable[[Callable[[*Ts], None]], None]) -> tuple[*Ts]: ... - - -def func2(cb: Callable[[bytes, int], None]) -> None: ... - - -reveal_type(func1(func2), expected_text="tuple[bytes, int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple26.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple26.py deleted file mode 100644 index 18bb712d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple26.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the case where a `*args: *Ts` parameter captures -# a callable with an indeterminate number of parameters because -# some of them have default arguments. - -from typing import Callable, Literal, TypeVar, TypeVarTuple - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -def func1(x: int, y: str = "", z: int | None = None) -> None: ... - - -def func2(callback: Callable[[*Ts], None], *args: *Ts) -> tuple[*Ts]: ... - - -v1 = func2(func1, 1) -reveal_type(v1, expected_text="tuple[int]") - -v2 = func2(func1, 1, "") -reveal_type(v2, expected_text="tuple[int, str]") - -v3 = func2(func1, 1, "", 3) -reveal_type(v3, expected_text="tuple[int, str, int]") - -v4 = func2(func1, 1, "", None) -reveal_type(v4, expected_text="tuple[int, str, None]") - -# This should generate an error. -func2(func1) - -# This should generate an error. -func2(func1, "") - -# This should generate an error. -func2(func1, 3, "", None, None) - - -def func3(callback: Callable[[*Ts], None]) -> tuple[*Ts]: ... - - -v5 = func3(func1) -reveal_type(v5, expected_text="tuple[int, str, int | None]") - - -def func4(a: Literal["day", "hour"]) -> None: ... - - -def func5(x: bool): - func2(func4, "day" if x else "hour") - - -def func6(x: T, y: T, z: int | None = None) -> None: ... - - -def func7(x: T, y: T) -> None: - func2(func6, x, y) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple27.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple27.py deleted file mode 100644 index ef20fcf1..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple27.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests the case where a Callable uses an unpacked TypeVarTuple -# followed by another positional parameter. - -from typing import TypeVarTuple, TypeVar, Generic, Callable - -T = TypeVar("T") -Ts = TypeVarTuple("Ts") - - -class A(Generic[*Ts, T]): ... - - -def deco1(x: Callable[[*tuple[*Ts, int]], None]) -> tuple[*Ts]: ... - - -def deco2(x: Callable[[*tuple[*Ts, str]], None]) -> tuple[*Ts]: ... - - -def deco3(x: Callable[[*tuple[str, int]], None]) -> None: ... - - -def deco4(x: Callable[[*Ts, T], None]) -> A[*Ts, T]: - return A() - - -def func1(a: str, b: int) -> None: ... - - -def func2(a: str, b: str, c: int) -> None: ... - - -v1 = deco1(func1) -reveal_type(v1, expected_text="tuple[str]") - -v2 = deco1(func2) -reveal_type(v2, expected_text="tuple[str, str]") - -# This should generate an error. -deco2(func1) - -deco3(func1) - -v3 = deco4(func1) -reveal_type(v3, expected_text="A[str, int]") - -v4 = deco4(func2) -reveal_type(v4, expected_text="A[str, str, int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple28.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple28.py deleted file mode 100644 index 195b9f7d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple28.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the case where a generic type alias with a TypeVarTuple -# also contains other TypeVars, and it is specialized with an unpacked tuple. - -from typing import TypeVar, TypeVarTuple - -Ts = TypeVarTuple("Ts") -T1 = TypeVar("T1") -T2 = TypeVar("T2") - -TA1 = tuple[T1, *Ts, T2] -TA1_Spec1 = TA1[*tuple[int, ...]] -TA1_Spec2 = TA1[float, *tuple[int, ...]] -TA1_Spec3 = TA1[*tuple[int, ...], str] -TA1_Spec4 = TA1[float, *tuple[int, ...], str] - -TA2 = tuple[*Ts, T1, T2] -TA2_Spec1 = TA2[*tuple[int, ...]] - -TA3 = tuple[T1, T2, *Ts] -TA3_Spec1 = TA3[*tuple[int, ...]] - -TA4 = tuple[T1, T1, *Ts, T2, T2] -TA4_Spec1 = TA4[*tuple[int, ...]] - - -def func1( - ta1_1: TA1_Spec1, - ta1_2: TA1_Spec2, - ta1_3: TA1_Spec3, - ta1_4: TA1_Spec4, - ta2: TA2_Spec1, - ta3: TA3_Spec1, - ta4: TA4_Spec1, -): - reveal_type(ta1_1, expected_type="tuple[int, *tuple[int, ...], int]") - reveal_type(ta1_2, expected_type="tuple[float, *tuple[int, ...], int]") - reveal_type(ta1_3, expected_type="tuple[int, *tuple[int, ...], str]") - reveal_type(ta1_4, expected_type="tuple[float, *tuple[int, ...], str]") - reveal_type(ta2, expected_type="tuple[*tuple[int, ...], int, int]") - reveal_type(ta3, expected_type="tuple[int, int, *tuple[int, ...]]") - reveal_type(ta4, expected_type="tuple[int, int, *tuple[int, ...], int, int]") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple29.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple29.py deleted file mode 100644 index d551f768..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple29.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the case where a function parameterized with -# a TypeVarTuple is called in a nested manner. - -from typing import Callable, TypeVar, TypeVarTuple - - -def f(a: str, b: int, c: bool) -> None: ... - - -def curry1[First, *Rest, Result]( - function: Callable[[First, *Rest], Result], -) -> Callable[[*Rest], Callable[[First], Result]]: ... - - -applied_twice1 = curry1(curry1(f)) -reveal_type(applied_twice1, expected_text="(bool) -> ((int) -> ((str) -> None))") - - -First = TypeVar("First") -Rest = TypeVarTuple("Rest") -Result = TypeVar("Result") - - -def curry2( - function: Callable[[First, *Rest], Result], -) -> Callable[[*Rest], Callable[[First], Result]]: ... - - -applied_twice2 = curry2(curry2(f)) -reveal_type(applied_twice2, expected_text="(bool) -> ((int) -> ((str) -> None))") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple3.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple3.py deleted file mode 100644 index 1434425d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple3.py +++ /dev/null @@ -1,129 +0,0 @@ -# This sample tests the TypeVar matching logic related to -# variadic type variables. - -from typing import Any, Generic, Literal, TypeAlias, TypeVar, overload -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - - -_T = TypeVar("_T") -_Xs = TypeVarTuple("_Xs") - - -class Array(Generic[Unpack[_Xs]]): - def __init__(self, *args: Unpack[_Xs]) -> None: - self.x: tuple[Unpack[_Xs]] = args - reveal_type(args, expected_text="tuple[*_Xs@Array]") - - # This should generate an error because _Xs is not unpacked. - def foo(self, *args: _Xs) -> None: ... - - -def linearize(value: Array[Unpack[_Xs]]) -> tuple[Unpack[_Xs]]: ... - - -def array_to_tuple(value: Array[Unpack[_Xs]]) -> tuple[complex, Unpack[_Xs]]: ... - - -def func1(x: Array[int, str, str, float], y: Array[()]): - reveal_type(x, expected_text="Array[int, str, str, float]") - - reveal_type(y, expected_text="Array[*tuple[()]]") - - a1 = Array(3, 3.5, "b") - reveal_type(a1, expected_text="Array[int, float, str]") - - a2 = linearize(a1) - reveal_type(a2, expected_text="tuple[int, float, str]") - - b1 = Array() - reveal_type(b1, expected_text="Array[*tuple[()]]") - - b2 = linearize(b1) - reveal_type(b2, expected_text="tuple[()]") - - e = array_to_tuple(x) - reveal_type(e, expected_text="tuple[complex, int, str, str, float]") - - f = array_to_tuple(y) - reveal_type(f, expected_text="tuple[complex]") - - -class ArrayIntStr(Array[int, str, _T]): - def __init__(self, val: _T) -> None: - pass - - -v1 = ArrayIntStr(3) - -v2: Array[int, str, int] = v1 - -# This should generate an error. -v3: Array[int, str, str] = v1 - -# This should generate an error. -v4: Array[int, str, int, int] = v1 - -# This should generate an error. -v5: Array[int, str] = v1 - - -def func2(p1: tuple[str, int], p2: list[str]): - v6 = Array(*p1) - reveal_type(v6, expected_text="Array[str, int]") - - v7 = Array(1, *p1, "") - reveal_type(v7, expected_text="Array[int, str, int, str]") - - v8 = Array(*p2) - reveal_type(v8, expected_text="Array[*tuple[str, ...]]") - - -def func3(x: Array[Unpack[_Xs]]) -> Array[Unpack[_Xs]]: - y: Array[Unpack[tuple[Any, ...]]] = x - return x - - -@overload -def func4(signal: Array[*_Xs], *args: *_Xs) -> None: ... - - -@overload -def func4(signal: str, *args: Any) -> None: ... - - -def func4(signal: Array[*_Xs] | str, *args: *_Xs) -> None: ... - - -def func5(a1: Array[Literal["a", "b"]], a2: Array[Literal["a"], Literal["b"]]): - func4(a1, "a") - func4(a2, "a", "b") - - -def func6(a: Array): - reveal_type(a, expected_text="Array[*tuple[Unknown, ...]]") - - -def func7(): - x1: Array[*tuple[int, str], *tuple[str]] - x2: Array[*tuple[int, ...], *tuple[str]] - x3: Array[*tuple[str], *tuple[int, ...], *tuple[str]] - - # This should generate an error because only one unpacked unbounded - # tuple can be used. - x4: Array[*tuple[str, ...], *tuple[int, ...], *tuple[str]] - - -ArrayAlias: TypeAlias = Array[Unpack[_Xs]] - - -def func8(): - x1: ArrayAlias[*tuple[int, str], *tuple[str]] - x2: ArrayAlias[*tuple[int, ...], *tuple[str]] - x3: ArrayAlias[*tuple[str], *tuple[int, ...], *tuple[str]] - - # This should generate an error because only one unpacked unbounded - # tuple can be used. - x4: ArrayAlias[*tuple[str, ...], *tuple[int, ...], *tuple[str]] diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple30.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple30.py deleted file mode 100644 index f1924035..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple30.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample tests the case where a TypeVarTuple is used in a class -# and a `Self` type is involved. - - -class Parent[*Ts]: - def __init__(self, *args: *Ts): ... - - def method(self): - Child(self) - - -class Child(Parent[*tuple[Parent, ...]]): ... diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple31.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple31.py deleted file mode 100644 index 81189294..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple31.py +++ /dev/null @@ -1,81 +0,0 @@ -# This sample tests the case where a TypeVarTuple is used in a method -# called on an instance whose type arguments contain deeply nested -# recursive tuple type aliases. The deep nesting previously caused the -# solved TypeVar to "escape" because type var transformation bailed out -# early on deeply nested tuples. - -from typing import final, override -from collections.abc import Callable - - -@final -class Ok[T]: - __match_args__ = ("_value",) - - def __init__(self, value: T): - self._value: T = value - - -@final -class Err[E]: - def __init__(self, value: E): - self._value: E = value - - -type Result[T, E] = Ok[T] | Err[E] - -type ParserResult[O, E] = Result[tuple[int, O], E] -type ParserFunc[O, E] = Callable[[str, int], ParserResult[O, E]] - - -class Parser[O, E]: - def __init__(self, func: ParserFunc[O, E]): - self._func: ParserFunc[O, E] = func - - def then[OO, OE](self, _other: "Parser[OO, OE]") -> "Parser[tuple[O, OO], E | OE]": - raise NotImplementedError - - def unpack_then[*TS, OO, OE]( - self: "Parser[tuple[*TS], E]", _other: "Parser[OO, OE]" - ) -> "Parser[tuple[*TS, OO], E | OE]": - raise NotImplementedError - - -def produce[T](_: T | None = None) -> T: - raise NotImplementedError - - -class ForwardRefParser[O, E](Parser[O, E]): - @override - def __init__(self, func: Callable[[], Parser[O, E]]): - self._meta_func: Callable[[], Parser[O, E]] = func - super().__init__(produce()) - - -type Whitespace = tuple[tuple[tuple[tuple[Whitespace]]]] -type Implementations = tuple[tuple[tuple[Whitespace], Implementations]] -type BlockItem = tuple[tuple[Implementations]] | tuple[BlockItem] - -ws: ForwardRefParser[Whitespace, None] = produce() -implementations: ForwardRefParser[Implementations, None] = produce() -block: Parser[tuple[BlockItem], None] = produce() - -# This should not generate an error. Previously the "OO" TypeVar from -# "unpack_then" escaped into the inferred type of this assignment. -forloop: ForwardRefParser[ - tuple[ - Whitespace, - Whitespace, - tuple[BlockItem], - Whitespace, - ], - None, -] = ForwardRefParser(lambda: ws.then(ws).unpack_then(block).unpack_then(ws)) - -# Pin the inferred type of the same constructor call (using an unannotated -# target so the inferred, rather than declared, type is checked). This makes -# the fix self-evident and guards against a future regression where the type -# is inferred incorrectly (e.g. the solved "OO" TypeVar leaking back in) -# without necessarily producing an assignment error. -inferred = ForwardRefParser(lambda: ws.then(ws).unpack_then(block).unpack_then(ws)) -reveal_type(inferred) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple4.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple4.py deleted file mode 100644 index 765bd9c7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple4.py +++ /dev/null @@ -1,75 +0,0 @@ -# This sample tests packing and unpacking operations with -# variadic type variables. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import Generic, NewType, Union -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - - -Shape = TypeVarTuple("Shape") - - -class Array(Generic[Unpack[Shape]]): - def __init__(self, *shape: Unpack[Shape]): - self.shape = shape - - def __abs__(self) -> "Array[Unpack[Shape]]": ... - - def __add__(self, other: "Array[Unpack[Shape]]") -> "Array[Unpack[Shape]]": ... - - -Height = NewType("Height", int) -Width = NewType("Width", int) -x: Array[Height, Width] = Array(Height(480), Width(640)) -reveal_type(x.shape, expected_text="tuple[Height, Width]") -reveal_type(abs(x), expected_text="Array[Height, Width]") -reveal_type(x + abs(x), expected_text="Array[Height, Width]") - - -_Xs = TypeVarTuple("_Xs") - - -def func1(a: tuple[Unpack[_Xs]], b: tuple[Unpack[_Xs]]) -> Union[Unpack[_Xs]]: ... - - -def func2( - a: tuple[int, Unpack[_Xs]], b: tuple[int, Unpack[_Xs]] -) -> Union[Unpack[_Xs]]: ... - - -def func3(p1: tuple[int], p2: tuple[int, str], p3: tuple[int, int]): - # This should generate an error. - v1 = func1(p1, p2) - - # This should generate an error. - v2 = func2(p1, p2) - - v3 = func2(p2, p2) - reveal_type(v3, expected_text="str") - - v4 = func2((3, "hi"), p2) - reveal_type(v4, expected_text="str") - - # This should generate an error. - func2((3, 3), p2) - - v5 = func2((3, 3), p3) - reveal_type(v5, expected_text="int") - - -def func4(a: int, *args: Unpack[_Xs], **kwargs: str) -> tuple[int, Unpack[_Xs]]: ... - - -c1 = func4(4, 5.4, 6j, b="3", c="5") -reveal_type(c1, expected_text="tuple[int, float, complex]") - -c2 = func4(4, b="3", c="5") -reveal_type(c2, expected_text="tuple[int]") - -# This should generate an error. -c3 = func4(b="3", c="5") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple5.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple5.py deleted file mode 100644 index 33e8e28a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple5.py +++ /dev/null @@ -1,127 +0,0 @@ -# This sample tests the handling of variadic type variables used -# within Callable types. - -from typing import Any, Callable, Protocol -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -_Xs = TypeVarTuple("_Xs") - - -def func1(func: Callable[[int, Unpack[_Xs]], Any]) -> Callable[[Unpack[_Xs]], int]: ... - - -def func2(func: Callable[[Unpack[_Xs]], int]) -> Callable[[Unpack[_Xs]], int]: ... - - -def callback1(a: int) -> int: ... - - -def callback2(a: str) -> int: ... - - -def callback3(a: str) -> None: ... - - -def callback4(a: int, b: complex, c: str) -> int: ... - - -def callback5(a: int, *args: Unpack[_Xs]) -> tuple[Unpack[_Xs]]: ... - - -def callback6(a: int, *args: Any) -> int: ... - - -def callback7(a: int, b: str, c: str, d: str, *args: Any) -> int: ... - - -c1 = func1(callback1) -reveal_type(c1, expected_text="() -> int") -c1_1 = c1() -reveal_type(c1_1, expected_text="int") - -# This should generate an error. -c2 = func1(callback2) - -# This should generate an error. -c3 = func2(callback3) - -c4 = func1(callback4) -reveal_type(c4, expected_text="(complex, str) -> int") -c4_1 = c4(3j, "hi") -reveal_type(c4_1, expected_text="int") - -# This should generate an error. -c4_2 = c4(3j) - -# This should generate an error. -c4_3 = c4(3j, "hi", 4) - -c5 = func1(callback5) -reveal_type(c5, expected_text="(*_Xs@callback5) -> int") - -c6_1 = func1(callback6) -reveal_type(c6_1, expected_text="(*Any) -> int") - -c6_2 = func2(callback6) -reveal_type(c6_2, expected_text="(int, *Any) -> int") - -c7_1 = func1(callback7) -reveal_type(c7_1, expected_text="(str, str, str, *Any) -> int") - -c7_2 = func2(callback7) -reveal_type(c7_2, expected_text="(int, str, str, str, *Any) -> int") - - -class CallbackA(Protocol[Unpack[_Xs]]): - def __call__(self, a: int, *args: Unpack[_Xs]) -> Any: ... - - -def func3(func: CallbackA[Unpack[_Xs]]) -> Callable[[Unpack[_Xs]], int]: ... - - -d1 = func3(callback1) -reveal_type(d1, expected_text="() -> int") - -# This should generate an error. -d2 = func3(callback2) - -# This should generate an error. -d3 = func3(callback3) - -d4 = func3(callback4) -reveal_type(d4, expected_text="(complex, str) -> int") -d4_1 = d4(3j, "hi") -reveal_type(d4_1, expected_text="int") - -# This should generate an error. -d4_2 = d4(3j) - -# This should generate an error. -d4_3 = d4(3j, "hi", 4) - - -def func4(func: Callable[[Unpack[_Xs], int], int]) -> Callable[[Unpack[_Xs]], int]: ... - - -def callback8(a: int, b: str, c: complex, d: int) -> int: ... - - -d5_1 = func4(callback1) -reveal_type(d5_1, expected_text="() -> int") - -# This should generate an error. -d5_2 = func4(callback4) - -d5_3 = func4(callback8) -reveal_type(d5_3, expected_text="(int, str, complex) -> int") - - -def func5(x: Callable[[Unpack[_Xs]], None], y: tuple[Unpack[_Xs]]): - pass - - -def func6(x: Callable[[Unpack[_Xs]], None], y: tuple[Unpack[_Xs]]): - func5(x, y) diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple6.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple6.py deleted file mode 100644 index cc81a1d6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple6.py +++ /dev/null @@ -1,109 +0,0 @@ -# This sample tests the handling of generic type aliases with -# variadic type variables. - -# viper: reportMissingTypeArgument=true, reportMissingModuleSource=false - -from typing import Callable, Generic, TypeVar - -from typing_extensions import TypeVarTuple, Unpack - -_Xs = TypeVarTuple("_Xs") -_T = TypeVar("_T") - - -class Array(Generic[Unpack[_Xs]]): - def __init__(self, *args: Unpack[_Xs]): ... - - -Alias1 = Array[Unpack[_Xs]] - -# This should generate an error. -Alias2 = Array[_Xs] - -# This should generate an error. -Alias3 = Array[_T, int, _Xs] - -# This should generate an error if reportMissingTypeArgument is enabled. -x1: Alias1 | None = None - -x2: Alias1[int] = Array(3) - -# This should generate an error. -x3: Alias1[int, str] = Array(3) - -x4: Alias1[int, dict[str, str]] = Array(3, {}) - -# This should generate an error. -x5: Alias1[()] = Array(3) - -x6 = Alias1[int, int, str](3, 4, "") - -x7: Alias1[int, float, str] = Array(3, 4, "") - -Alias4 = Array[_T, int, Unpack[_Xs]] - -Alias5 = Array[Unpack[_Xs]] - -y1: Alias4[float, str, str] = Array(3.4, 2, "hi", "hi") - -# This should generate an error. -y2: Alias4[float, str, str] = Array("3.4", 2, "hi", "hi") - -y3 = Alias4[float, str, str](3, 2, "hi", "hi") - - -def func1(a: Alias4[_T, Unpack[_Xs]]) -> tuple[_T, Unpack[_Xs]]: ... - - -z1 = func1(Array(3, 4, "hi", 3j)) -reveal_type(z1, expected_text="tuple[int, str, complex]") - -# This should generate an error. -z2 = func1(Array(3, 4.3, "hi", 3j)) - -z3 = func1(Array(3.5, 4)) -reveal_type(z3, expected_text="tuple[float]") - -Alias6 = tuple[int, Unpack[_Xs]] - - -# The type annotation for y will generate an error if -# reportMissingTypeArgument is enabled. -def func2(x: Alias6[float, bool], y: Alias6, z: Alias6[()]): - reveal_type(x, expected_text="tuple[int, float, bool]") - - reveal_type(y, expected_text="tuple[int, *tuple[Unknown, ...]]") - - reveal_type(z, expected_text="tuple[int]") - - -Alias7 = Callable[[Unpack[_Xs]], None] - - -def func3(cb: Alias7[int, Unpack[_Xs]]) -> tuple[Unpack[_Xs]]: ... - - -def func4(a: int, b: str) -> None: ... - - -reveal_type(func3(func4), expected_text="tuple[str]") - - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - -Alias8 = tuple[*_Xs, _T1, _T2] - -# This should generate an error because there are -# enough type arguments. -a8_1: Alias8[int] - -a8_2: Alias8[int, int] - - -class ClassA9(Generic[_T1]): - pass - - -# This should generate an error. -a9_1: ClassA9[*tuple[int]] diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple7.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple7.py deleted file mode 100644 index d37ee16f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple7.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests error handling for variadic type var usage. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import Any, Callable, Generic, TypeVar, Union -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - -_Xs = TypeVarTuple("_Xs") -_Ys = TypeVarTuple("_Ys") -_T1 = TypeVar("_T1") - - -# This should generate an error because only one TypeVarTuple is allowed. -class Class1(Generic[Unpack[_Ys], Unpack[_Xs]]): ... - - -# This should generate an error because only one TypeVarTuple is allowed. -class Class2(dict[tuple[Unpack[_Ys]], tuple[Unpack[_Xs]]]): ... - - -class Class3(dict[tuple[Unpack[_Ys]], _T1]): ... - - -class Class4(dict[_T1, tuple[Unpack[_Ys]]], Generic[Unpack[_Ys], _T1]): ... - - -class Class5(dict[tuple[Unpack[_Ys]], _T1], Generic[_T1, Unpack[_Ys]]): - def func1(self, a: tuple[Unpack[_Ys], int]): - pass - - # This should generate an error because tuple cannot contain multiple - # TypeVarTuples. - def func2(self, *args: Unpack[_Xs]) -> tuple[Unpack[_Ys], Unpack[_Xs]]: ... - - def func3(self) -> Union[Unpack[_Ys], int]: - return 3 - - def func4(self, *args: Unpack[_Xs]) -> Union[int, Unpack[_Ys], Unpack[_Xs]]: - return 3 - - def func5(self, a: Callable[[Unpack[_Ys], int], Any]): - pass - - # This should generate an error because *_Ys cannot appear - # by itself in a return type for a Callable. - def func6(self, a: Callable[[int], Unpack[_Ys]]): - pass - - -Alias1 = Union[tuple[int, Unpack[_Xs]], _T1] - -# This should generate an error because at most one TypeVarTuple is allowed. -Alias2 = Union[tuple[int, Unpack[_Xs]], tuple[Unpack[_Ys]]] diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple8.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple8.py deleted file mode 100644 index ee734751..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple8.py +++ /dev/null @@ -1,116 +0,0 @@ -# This sample tests variadic TypeVar matching for unions. - -# Enable experimental features to support Union[*Ts]. -# viper: enableExperimentalFeatures=true - -from typing import TypeVar, Union -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - - -_T = TypeVar("_T") -_Xs = TypeVarTuple("_Xs") -_Ys = TypeVarTuple("_Ys") - - -def func1(x: Union[Unpack[_Xs]]) -> Union[Unpack[_Xs]]: ... - - -def func2(x: Union[Unpack[_Xs], Unpack[_Ys]]) -> Union[Unpack[_Xs], Unpack[_Ys]]: ... - - -def func3(x: Union[int, Unpack[_Xs]]) -> Union[Unpack[_Xs]]: ... - - -def func4(x: Union[_T, Unpack[_Xs]]) -> Union[_T, Unpack[_Xs]]: ... - - -def func5(x: Union[Unpack[_Xs]], *args: Unpack[_Xs]) -> Union[Unpack[_Xs]]: ... - - -def func6(*args: Unpack[_Xs]) -> Union[Unpack[_Xs]]: ... - - -def func7(a: list[Union[Unpack[_Xs]]]) -> Union[Unpack[_Xs]]: ... - - -def test1(a: int, b: str, c: list[int], d: Union[complex, str]): - v1_1 = func1(a) - reveal_type(v1_1, expected_text="int") - - v1_2 = func1(d) - reveal_type(v1_2, expected_text="complex | str") - - # --------- - - # This behavior isn't defined by PEP 646, but neither - # did PEP 484 define the behavior for multiple (non- - # variadic) TypeVar matching within a Union. So behavior - # is likely to vary between type checkers here. - v2_1 = func2(a) - reveal_type(v2_1, expected_text="int") - - v2_2 = func2(d) - reveal_type(v2_2, expected_text="complex | str") - - # --------- - - v3_1 = func3(a) - reveal_type(v3_1, expected_text="Unknown") - - # This should generate an error - v3_2 = func3(d) - - v3_3 = func3(b) - reveal_type(v3_3, expected_text="str") - - # --------- - - # This behavior isn't defined by PEP 646 or PEP 484. - v4_1 = func4(a) - reveal_type(v4_1, expected_text="int") - - v4_2 = func4(d) - reveal_type(v4_2, expected_text="complex | str") - - # --------- - - v5_1 = func5(a) - reveal_type(v5_1, expected_text="int") - - v5_2 = func5(a, a) - reveal_type(v5_2, expected_text="int") - - # This should generate an error - v5_3 = func5(a, b) - - # This should generate an error - v5_4 = func5(a, b, c) - - # --------- - - v6_1 = func6(a) - reveal_type(v6_1, expected_text="int") - - v6_2 = func6(a, b) - reveal_type(v6_2, expected_text="int | str") - - v6_3 = func6(a, b, d) - reveal_type(v6_3, expected_text="int | str | complex") - - v6_4 = func6() - reveal_type(v6_4, expected_text="Never") - - # --------- - - v7_1 = func7([a]) - reveal_type(v7_1, expected_text="int") - - x: list[Union[int, str]] = [a, b] - v7_2 = func7(x) - reveal_type(v7_2, expected_text="int | str") - - v7_3 = func7([a, b, d]) - reveal_type(v7_3, expected_text="int | str | complex") diff --git a/packages/vipeye-internal/src/tests/samples/typeVarTuple9.py b/packages/vipeye-internal/src/tests/samples/typeVarTuple9.py deleted file mode 100644 index 434b84c1..00000000 --- a/packages/vipeye-internal/src/tests/samples/typeVarTuple9.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the handling of variadic type variables used -# in generic type aliases and with suffixes. - -from typing import Callable, Generic, TypeVar -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - TypeVarTuple, - Unpack, -) - - -Ts = TypeVarTuple("Ts") -T = TypeVar("T", covariant=True) - - -class Call(Generic[Unpack[Ts]]): - def __init__(self, *args: Unpack[Ts]) -> None: - self.args = args - - -class Return(Generic[T]): - def __init__(self, /, result: T) -> None: - self.result = result - - -TailRec = Call[Unpack[Ts]] | Return[T] - - -def tail_rec( - fn: Callable[[Unpack[Ts]], TailRec[Unpack[Ts], T]], -) -> Callable[[Unpack[Ts]], T]: ... - - -@tail_rec -def factorial(n: int, acc: int) -> TailRec[int, int, int]: - if n <= 0: - return Return(acc) - return Call(n - 1, acc * n) - - -reveal_type(factorial, expected_text="(int, int) -> int") - - -Alias10 = tuple[T, *Ts] -Alias11 = tuple[*Ts] -Alias12 = tuple[T, *Ts, T] - - -def func5(a10: Alias10, a11: Alias11, a12: Alias12): - reveal_type(a10, expected_text="tuple[Unknown, *tuple[Unknown, ...]]") - reveal_type(a11, expected_text="tuple[Unknown, ...]") - reveal_type(a12, expected_text="tuple[Unknown, *tuple[Unknown, ...], Unknown]") diff --git a/packages/vipeye-internal/src/tests/samples/typedDict1.py b/packages/vipeye-internal/src/tests/samples/typedDict1.py deleted file mode 100644 index 92240124..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict1.py +++ /dev/null @@ -1,91 +0,0 @@ -# This sample tests the type analyzer's handling of TypedDict classes. - -from typing import Any, TypeVar, TypedDict - -not_total = False - - -# This should generate an error because -# the value of the total argument must -# be a literal "True" or "False". -class TD1(TypedDict, total=not_total): - pass - - -class TD2(TypedDict, total=False): - """This is a test""" - - a: int - - # This should generate an error because "b" - # is redeclared below with a different type. - b: str - - b: float - - c: "dict[Any, Any]" - - # This should generate an error because - # assignments are not allowed. - d: float = 3.0 - - # This should generate an error because - # methods are not allowed. - def foo(self): - pass - - -class TD3(TypedDict, total=True): - a: int - b: float - c: str - - -class TD4(TypedDict): - d: str - - -class TD5(TD3, total=False): - e: str - - # This should generate an error because - # methods are not allowed. - def foo(self): - pass - - -class NotATD: - pass - - -# This should generate an error because non-TypeDict -# base classes shouldn't be allowed for TD classes. -class TD6(TD3, NotATD): - pass - - -# This should generate an error because non-TypeDict -# base classes shouldn't be allowed for TD classes. -class TD7(NotATD, TypedDict): - pass - - -# This should generate an error because TypedDict can't -# be used in a type annotation. -v1: TypedDict | int - -# This should generate an error because TypedDict can't -# be used in a TypeVar bound. -T = TypeVar("T", bound=TypedDict | int) - - -# This should generate an error because TypedDict doesn't support -# a metaclass parameter. -class TD8(TypedDict, metaclass=type): - name: str - - -# This should generate an error because TypedDict doesn't support -# other __init_subclass__ parameters. -class TD9(TypedDict, other=True): - name: str diff --git a/packages/vipeye-internal/src/tests/samples/typedDict10.py b/packages/vipeye-internal/src/tests/samples/typedDict10.py deleted file mode 100644 index 9501513a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict10.py +++ /dev/null @@ -1,34 +0,0 @@ -# This sample tests the type analyzer's handling of a variant -# of the TypedDict "alternate syntax" defined in the Python docs. - -from typing import TypedDict - -Movie = TypedDict("Movie", name=str, year=int) - - -def get_movie_name(movie: Movie): - return movie["name"] - - -name2 = get_movie_name({"name": "ET", "year": 1982}) - -movie1: Movie = {"name": "Blade Runner", "year": 1982} - -movie2: Movie = { - "name": "Blade Runner", - # This should generate an error because - # the type is incorrect. - "year": "1982", -} - -movie3: Movie = { - # This should generate an error because - # all keys are required. - "name": "Blade Runner" -} - -movie4: Movie = { - # This should generate an error because - # the key name is not supported. - "name2": "Blade Runner" -} diff --git a/packages/vipeye-internal/src/tests/samples/typedDict11.py b/packages/vipeye-internal/src/tests/samples/typedDict11.py deleted file mode 100644 index c339bf38..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict11.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests bidirectional type inference (expected type) for -# lists that include TypedDicts. - -from typing import TypeVar, TypedDict - - -MessageTypeDef = TypedDict("MessageTypeDef", {"Id": str, "Handle": str}) - -msgs = [{"Id": "1", "Handle": "2"}] -list2: list[MessageTypeDef] = [ - {"Id": msg["Id"], "Handle": msg["Handle"]} for msg in msgs -] - -TMessage = TypeVar("TMessage", bound=MessageTypeDef) - - -def func1(x: list[TMessage]) -> TMessage: ... - - -func1([{"Id": "", "Handle": ""}]) diff --git a/packages/vipeye-internal/src/tests/samples/typedDict12.py b/packages/vipeye-internal/src/tests/samples/typedDict12.py deleted file mode 100644 index 80460b6f..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict12.py +++ /dev/null @@ -1,123 +0,0 @@ -# This sample tests the synthesized methods get, setdefault -# pop, __delitem__, clear, and popitem for a TypedDict. - -from typing import TypedDict, final -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - NotRequired, - Required, -) - - -class TD1(TypedDict): - bar: NotRequired[str] - - -class TD2(TD1): - foo: Required[str] - - -td1: TD1 = {} -td2: TD2 = {"foo": "hi"} - -v1: str | None = td1.get("bar") - -v2: str = td1.get("bar", "") - -v3: str | int = td1.get("bar", 3) - -v4: str = td1.setdefault("bar", "1") - -# This should generate an error. -td1.setdefault("bar", 3) - -# This should generate an error. -td1.setdefault("bar") - -# This should generate an error. -td1.setdefault("baz", "") - -v6: str = td1.pop("bar") -v7: str | int = td1.pop("bar", 1) -v8: str | int = td1.pop("bar", 3) - -v9 = td2.pop("foo") -reveal_type(v9, expected_text="object") - -v10 = td2.pop("foo", None) -reveal_type(v10, expected_text="object | None") - -td1.__delitem__("bar") - - -@final -class TD3(TypedDict): - foo: int - baz: NotRequired[int] - - -class TD4(TypedDict): - bar: str - - -C = TD3 | TD4 - - -def func1(a: TD3, b: TD4, c: C, s: str) -> int | None: - a1 = a.get("foo") - reveal_type(a1, expected_text="int") - a2 = a.get("foo", 1.0) - reveal_type(a2, expected_text="int") - a3 = a.get("bar") - reveal_type(a3, expected_text="Any | None") - a4 = a.get("bar", 1.0) - reveal_type(a4, expected_text="Any | float") - a5 = a.get("baz") - reveal_type(a5, expected_text="int | None") - a6 = a.get("baz", 1.0) - reveal_type(a6, expected_text="int | float") - a7 = a.get(s) - reveal_type(a7, expected_text="Any | None") - a8 = a.get(s, 1.0) - reveal_type(a8, expected_text="Any | float") - - b1 = b.get("bar") - reveal_type(b1, expected_text="str") - b2 = b.get("bar", 1.0) - reveal_type(b2, expected_text="str") - b3 = b.get("foo") - reveal_type(b3, expected_text="Any | None") - b4 = b.get("foo", 1.0) - reveal_type(b4, expected_text="Any | float") - b5 = b.get(s) - reveal_type(b5, expected_text="Any | None") - b6 = b.get(s, 1.0) - reveal_type(b6, expected_text="Any | float") - - c1 = c.get("foo") - reveal_type(c1, expected_text="int | Any | None") - c2 = c.get("foo", 1.0) - reveal_type(c2, expected_text="int | Any | float") - c3 = c.get("bar") - reveal_type(c3, expected_text="Any | str | None") - c4 = c.get("bar", 1.0) - reveal_type(c4, expected_text="Any | float | str") - c5 = c.get("baz") - reveal_type(c5, expected_text="int | Any | None") - c6 = c.get("baz", 1.0) - reveal_type(c6, expected_text="int | float | Any") - - -class TD7(TypedDict, total=False): - a: dict[str, str] - b: list[str] - - -def func2(td7: TD7): - v1 = td7.get("a", []) - reveal_type(v1, expected_text="dict[str, str] | list[Any]") - - v2 = td7.get("a", {}) - reveal_type(v2, expected_text="dict[str, str]") - - v3 = td7.get("b", []) - reveal_type(v3, expected_text="list[str]") diff --git a/packages/vipeye-internal/src/tests/samples/typedDict13.py b/packages/vipeye-internal/src/tests/samples/typedDict13.py deleted file mode 100644 index eb433256..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict13.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests that TypedDicts that inherit from other -# TypedDicts do not override field names with incompatible types. - -# viper: reportIncompatibleVariableOverride=true - -from typing import Any, NotRequired, Required, TypedDict - - -ParentA = TypedDict("ParentA", {"name": str, "age": int}) - - -class ChildA(ParentA): - # This should generate an error because the type of "age" is redefined. - age: float - - name: str - - -class ParentB(TypedDict): - x: Any - - -class ChildB(ParentB): - x: int - - -class ParentC(TypedDict): - x: Required[int] - - -class ChildC(ParentC): - # This should generate an error because "x" is Required in the parent. - x: NotRequired[int] - - -class ParentD(TypedDict): - x: Required[int] - - -class ChildD(ParentD): - # This should generate an error because "x" is NotRequired in the parent. - x: NotRequired[int] - - -class ParentE(TypedDict, total=True): - x: int - - -class ChildE(ParentE, total=False): - # This should generate an error because "x" is Required in the parent. - x: int diff --git a/packages/vipeye-internal/src/tests/samples/typedDict14.py b/packages/vipeye-internal/src/tests/samples/typedDict14.py deleted file mode 100644 index 24854484..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict14.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests bidirectional type inference when assigning -# a value to a TypedDict element. - -from typing import TypedDict - - -class Thing(TypedDict): - v1: bool - v2: str - - -class Thing2(TypedDict): - v3: Thing | None - v4: list[str | int] | None - - -thing2: Thing2 = {"v3": None, "v4": None} -thing2["v3"] = {"v1": False, "v2": "a"} -thing2["v4"] = [] -thing2["v4"] = [3] -thing2["v4"] = ["hi"] -thing2["v4"] = ["hi", 4] - -# This should generate an error -thing2["v4"] = ["hi", 4.0] diff --git a/packages/vipeye-internal/src/tests/samples/typedDict15.py b/packages/vipeye-internal/src/tests/samples/typedDict15.py deleted file mode 100644 index 86f5cf4e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict15.py +++ /dev/null @@ -1,51 +0,0 @@ -# This sample tests the type compatibility checks when the source -# is a TypedDict and the dest is a protocol. - -from typing import Protocol, TypeVar, TypedDict - - -class HasName(Protocol): - name: str - - -class SupportsClear(Protocol): - def clear(self) -> None: ... - - -_T = TypeVar("_T") - - -class SupportsUpdate(Protocol): - def update(self: _T, __m: _T) -> None: ... - - -class B(TypedDict): - name: str - - -def print_name(x: HasName): - print(x.name) - - -my_typed_dict: B = {"name": "my name"} - -# This should generate an error. The "name" -# attribute of a TypedDict can't be accessed -# through a member access expression. -print_name(my_typed_dict) - - -def do_clear(x: SupportsClear): - x.clear() - - -# This should generate an error. Although a "dict" -# class supports clear, a TypedDict does not. -do_clear(my_typed_dict) - - -def do_update(x: SupportsUpdate): - x.update(x) - - -do_update(my_typed_dict) diff --git a/packages/vipeye-internal/src/tests/samples/typedDict16.py b/packages/vipeye-internal/src/tests/samples/typedDict16.py deleted file mode 100644 index 4de25b79..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict16.py +++ /dev/null @@ -1,80 +0,0 @@ -# This sample tests that type compatibility between TypedDicts. - -from typing import TypedDict, final - - -class TD0(TypedDict): - key: str - - -class TD1(TD0): - value: str - - -class TD2(TypedDict): - key: str - value: str - - -v1: TD2 = TD1(key="", value="") -v2: TD1 = TD2(key="", value="") - -v3 = [v2] -v4: list[TD2] = v3 -v5 = [v1] -v6: list[TD1] = v5 - - -class TD10(TypedDict, total=False): - key: str - - -class TD11(TD10): - value: str - - -class TD12(TypedDict): - key: str - value: str - - -# This should generate an error. -v10: TD12 = TD11(key="", value="") - -# This should generate an error. -v11: TD11 = TD12(key="", value="") - - -v12 = [v10] -# This should generate an error. -v13: list[TD10] = v12 - -v14 = [v11] -# This should generate an error. -v15: list[TD12] = v14 - - -class TD20(TypedDict): - key: str - value: str - - -class TD21(TypedDict): - key: str - value: str - extra: str - - -# This should generate an error. -v20: TD21 = TD20(key="", value="") - -v21: TD20 = TD21(key="", value="", extra="") - - -v22 = [v20] -# This should generate an error. -v23: list[TD20] = v22 - -v24: list[TD20] = [v21] -# This should generate an error. -v25: list[TD21] = v24 diff --git a/packages/vipeye-internal/src/tests/samples/typedDict17.py b/packages/vipeye-internal/src/tests/samples/typedDict17.py deleted file mode 100644 index 202cbd2d..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict17.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests the handling of the "|" and "|=" operators -# for TypedDicts. - -from typing import TypedDict - - -class Person(TypedDict, total=False): - name: str - age: int - - -person: Person = {} - -person.update({"name": "Michael"}) - -person |= {"name": "Michael"} -person = person | {"name": "Michael"} - - -# This should generate an error. -person |= {"name": "Michael", "other": 1} - -# This should generate an error. -person = person | {"name": 1} diff --git a/packages/vipeye-internal/src/tests/samples/typedDict18.py b/packages/vipeye-internal/src/tests/samples/typedDict18.py deleted file mode 100644 index 38025d06..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict18.py +++ /dev/null @@ -1,134 +0,0 @@ -# This sample tests the handling of generic TypedDicts which are -# supported in Python 3.11 and newer. - -from typing import Generic, Literal, TypeVar, TypedDict, Unpack - -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") - - -class TD1(TypedDict, Generic[_T1, _T2]): - a: dict[_T1, _T2] - b: _T1 - - -v1_1: TD1[str, int] = {"a": {"x": 3}, "b": "y"} - -# This should generate an error. -v1_2: TD1[str, str] = {"a": {"x": 3}, "b": "y"} - - -class TD2(TD1[_T1, int]): - c: _T1 - - -v2_1: TD2[int] = {"a": {3: 3}, "b": 1, "c": 5} - - -class TD3(TypedDict): - a: int - - -class TD4(TD3, Generic[_T1]): - b: _T1 - - -v4: TD4[str] = {"a": 3, "b": ""} -v5: TD4[tuple[str]] = {"a": 3, "b": ("",)} - - -def func1(x: TD1[_T1, _T2]) -> dict[_T1, _T2]: - return x["a"] - - -v1_3 = func1({"a": {"x": 3}, "b": "y"}) -reveal_type(v1_3, expected_text="dict[str, int]") - - -class TD5(TypedDict, Generic[_T1]): - x: _T1 - y: _T1 - - -def func2(a: TD5[Literal[1]]): ... - - -func2({"x": 1, "y": 1}) - -# This should generate an error because 2 doesn't match Literal[1]. -func2({"x": 2, "y": 1}) - - -def func3(a: TD5[_T1]) -> _T1: ... - - -reveal_type(func3({"x": 1, "y": 1}), expected_text="int") -reveal_type(func3({"x": "1", "y": 1}), expected_text="str | int") - - -class TD6(TD5[Literal[1]]): - z: str - - -def func4(a: TD6) -> Literal[1]: ... - - -func4({"x": 1, "y": 1, "z": "a"}) -f2: TD6 = {"x": 1, "y": 1, "z": "a"} - -reveal_type(func4({"x": 1, "y": 1, "z": "a"})) - - -class TD7(TD5[_T1], Generic[_T1]): - z: str - - -def func5(a: TD7[Literal[1]]) -> Literal[1]: - return a["x"] - - -func5({"x": 1, "y": 1, "z": "a"}) -f3: TD7[Literal[1]] = {"x": 1, "y": 1, "z": "a"} - -reveal_type(func5({"x": 1, "y": 1, "z": "a"})) - - -class TD8(TD7[Literal[1]]): ... - - -def func6(a: TD8) -> Literal[1]: - return a["x"] - - -func6({"x": 1, "y": 1, "z": "a"}) -f4: TD8 = {"x": 1, "y": 1, "z": "a"} - -reveal_type(func6({"x": 1, "y": 1, "z": "a"})) - - -class TD9(TypedDict, Generic[_T1]): - x: _T1 - - -class ClassA(Generic[_T1]): - def __init__(self, **attrs: Unpack[TD9[_T1]]) -> None: ... - - -f5 = ClassA[int](x=1) - -# This should generate an error because 1 isn't a valid type. -f6 = ClassA[str](x=1) - -f7 = ClassA(x=1) -reveal_type(f7, expected_text="ClassA[int]") - - -class TD10(TypedDict, Generic[_T1]): - x: _T1 - - -class TD11(TypedDict): - y: int - - -class TD12(TD10[str], TD11): ... diff --git a/packages/vipeye-internal/src/tests/samples/typedDict19.py b/packages/vipeye-internal/src/tests/samples/typedDict19.py deleted file mode 100644 index e3366477..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict19.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample tests the handling of type narrowing of a TypedDict based -# on an assignment to a not-required key. - -from typing import TypedDict -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - NotRequired, - Required, - Unpack, -) - - -class TD1(TypedDict): - x: NotRequired[str] - - -class TD2(TypedDict): - x: Required[str] - - -def func1(td: TD1 | TD2): - # This should generate an error because "x" is not required in TD1. - v1 = td["x"] - - -def func2(td: TD1 | TD2): - td["x"] = "hi" - v1 = td["x"] - - -def func3(td: TD1 | TD2, opt: bool): - if opt: - td["x"] = "hi" - - # This should generate an error because "x" is not required in TD1. - v1 = td["x"] - - -def func4(td: TD1 | TD2, opt: bool): - if opt: - td["x"] = "hi" - else: - td["x"] = "hi" - - v1 = td["x"] - - -class TD3(TypedDict): - x: str - y: NotRequired[int] - - -def accepts_td3(**args: Unpack[TD3]): - pass - - -def func5(td: TD3, cond: bool): - if cond: - td["y"] = 5 - accepts_td3(**td) diff --git a/packages/vipeye-internal/src/tests/samples/typedDict2.py b/packages/vipeye-internal/src/tests/samples/typedDict2.py deleted file mode 100644 index 1a150438..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict2.py +++ /dev/null @@ -1,59 +0,0 @@ -# This sample tests the type analyzer's handling of TypedDict classes. - -from typing import TypedDict - - -class Movie(TypedDict, total=False): - name: str - year: int - - -class BookBasedMovie(Movie, total=True): - based_on: str - - -def get_movie_name(movie: Movie): - return movie.get("name") - - -name2 = get_movie_name({"name": "ET", "year": 1982}) - -movie1: Movie = {"name": "Blade Runner", "year": 1982} - -movie2: Movie = { - "name": "Blade Runner", - # This should generate an error because - # the type is incorrect. - "year": "1982", -} - -movie3: Movie = {"name": "Blade Runner"} - -movie4: Movie = { - # This should generate an error because - # the key name is not supported. - "name2": "Blade Runner" -} - -movie5: Movie = Movie(movie3) -movie6: Movie = Movie(movie3, year=2030, name="New movie") - -book1: BookBasedMovie = {"name": "Moonraker", "year": 1979, "based_on": "Moonraker"} - -book2: BookBasedMovie = {"year": 1979, "based_on": "Moonraker"} - -book3: BookBasedMovie = {"based_on": "Moonraker"} - -book4: BookBasedMovie = { - # This should generate an error because 'author' isn't - # a defined field. - "author": "Ian Fleming", - "based_on": "Moonraker", -} - -book5: BookBasedMovie = { - "name": "Moonraker", - "year": 1979, - # This should generate an error because 'based_on' is - # a required field, and it's not provided. -} diff --git a/packages/vipeye-internal/src/tests/samples/typedDict20.py b/packages/vipeye-internal/src/tests/samples/typedDict20.py deleted file mode 100644 index a7679e3a..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict20.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests the case where a TypedDict is narrowed based -# on an "in" type guard, and the narrowed type is later combined -# with the original wider type. We want to verify that this -# doesn't result in a combinatorial explosion. - -from typing import TypedDict - - -class GroupsSettingsDict(TypedDict, total=False): - a: bool | None - b: bool | None - c: bool | None - d: bool | None - e: bool | None - f: bool | None - g: bool | None - h: bool | None - i: bool | None - j: bool | None - k: bool | None - l: bool | None - m: bool | None - n: bool | None - o: bool | None - p: bool | None - - -def foo() -> None: - settings: GroupsSettingsDict = {} - - if "a" in settings: - settings["a"] - if "b" in settings: - settings["b"] - if "c" in settings: - settings["c"] - if "d" in settings: - settings["d"] - if "e" in settings: - settings["e"] - if "f" in settings: - settings["f"] - if "g" in settings: - settings["g"] - if "h" in settings: - settings["h"] - if "i" in settings: - settings["i"] - if "j" in settings: - settings["j"] - if "k" in settings: - settings["k"] - if "l" in settings: - settings["l"] - if "m" in settings: - settings["m"] - if "n" in settings: - settings["n"] - if "o" in settings: - settings["o"] - if "p" in settings: - settings["p"] diff --git a/packages/vipeye-internal/src/tests/samples/typedDict21.py b/packages/vipeye-internal/src/tests/samples/typedDict21.py deleted file mode 100644 index bfcc474b..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict21.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests the handling of dictionary expansion for TypedDicts. - -from typing_extensions import ( # viper: ignore[reportMissingModuleSource] - NotRequired, - Required, - TypedDict, -) - - -class TD1(TypedDict): - v1: Required[int] - - -class TD2(TypedDict): - v2: Required[str] - - -class TD3(TypedDict): - v1: NotRequired[int] - - -class TD4(TD1, TD2): ... - - -td1: TD1 = {"v1": 0} -td2: TD2 = {"v2": ""} -td3_1: TD3 = {} -td3_2: TD3 = {"v1": 0} - -td4_1: TD4 = {**td1, **td2} - -# This should generate an error because td3_1 -# does not include the required "v1" entry. -td4_2: TD4 = {**td3_1, **td2} - -td4_3: TD4 = {**td3_2, **td2} - - -class TD5(TypedDict): - f1: str - f2: str - - -class TD6(TypedDict): - f1: str - f2: int - - -def func1(t1: TD5) -> TD6: - return {**t1, "f2": 0} - - -td6: TD6 = {"f1": 1, "f2": "", "f1": "", "f2": 1} diff --git a/packages/vipeye-internal/src/tests/samples/typedDict22.py b/packages/vipeye-internal/src/tests/samples/typedDict22.py deleted file mode 100644 index 5e4ac2d6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict22.py +++ /dev/null @@ -1,11 +0,0 @@ -# This sample tests that class variables for TypedDict are accessible. - -from typing import TypedDict - - -class TD1(TypedDict): ... - - -reveal_type(TD1.__required_keys__, expected_text="frozenset[str]") -reveal_type(TD1.__optional_keys__, expected_text="frozenset[str]") -reveal_type(TD1.__total__, expected_text="bool") diff --git a/packages/vipeye-internal/src/tests/samples/typedDict23.py b/packages/vipeye-internal/src/tests/samples/typedDict23.py deleted file mode 100644 index 4458b9ef..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict23.py +++ /dev/null @@ -1,45 +0,0 @@ -# This sample tests the synthesized update method for TypedDict classes. - -from typing import NotRequired, Required, TypedDict - - -class TD1(TypedDict): - a: Required[int] - b: NotRequired[str] - - -class TD2(TD1): - c: Required[int] - - -td1: TD1 = {"a": 3} - -reveal_type( - td1.update, - expected_text="Overload[(__m: Iterable[tuple[Literal['a'], int] | tuple[Literal['b'], str]], /) -> None, (__m: Partial[TD1], /) -> None, (*, a: int = ..., b: str = ...) -> None]", -) - -td1.update({}) -td1.update({"b": ""}) - -td2: TD2 = {"a": 0, "c": 3} - -reveal_type( - td2.update, - expected_text="Overload[(__m: Iterable[tuple[Literal['a'], int] | tuple[Literal['b'], str] | tuple[Literal['c'], int]], /) -> None, (__m: Partial[TD2], /) -> None, (*, a: int = ..., b: str = ..., c: int = ...) -> None]", -) - -# This should generate an error because "c" within TD1 may be incompatible with "int". -# A second error is generated to indicate that no overloads are compatible. -td2.update(td1) - - -class TD3(TypedDict): - a: NotRequired[str] - - -td3: TD3 = {} -reveal_type( - td3.update, - expected_text="Overload[(__m: Iterable[tuple[Literal['a'], str]], /) -> None, (__m: Partial[TD3], /) -> None, (*, a: str = ...) -> None]", -) diff --git a/packages/vipeye-internal/src/tests/samples/typedDict24.py b/packages/vipeye-internal/src/tests/samples/typedDict24.py deleted file mode 100644 index 1f8243b6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict24.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the handling of a TypedDict used as a bound -# for a TypeVar. - - -from typing import Generic, TypeVar, TypedDict - - -class TD1(TypedDict): - a: str - - -T1 = TypeVar("T1", bound=TD1) - - -class A(Generic[T1]): - def method1(self) -> T1: - # This should generate an error. - return {"a": ""} diff --git a/packages/vipeye-internal/src/tests/samples/typedDict25.py b/packages/vipeye-internal/src/tests/samples/typedDict25.py deleted file mode 100644 index 5ccb854e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict25.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that member accesses to a TypedDict are properly -# handled even if one of the items in the TypedDict shadows the name -# of a TypedDict attribute. - -from typing import TypedDict - - -class TD1(TypedDict): - items: int - - -td1 = TD1(items=0) -td1.items() diff --git a/packages/vipeye-internal/src/tests/samples/typedDict3.py b/packages/vipeye-internal/src/tests/samples/typedDict3.py deleted file mode 100644 index 68d79dc7..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict3.py +++ /dev/null @@ -1,40 +0,0 @@ -# This sample tests the type analyzer's handling of TypedDict classes. - -from typing import TypeVar, TypedDict - - -class Movie(TypedDict, total=False): - name: str - year: int - - -class BookBasedMovie(Movie, total=True): - based_on: str - - -movie1 = Movie(year=1982, name="Blade Runner") - -# This should generate an error because -# the type is incorrect. -movie2 = Movie(name="Blade Runner", year="1982") - -movie3 = Movie(name="Blade Runner") - -# This should generate an error because -# the key name is not supported. -movie4 = Movie(name2="Blade Runner") - - -book1 = BookBasedMovie(year=1979, name="Moonraker", based_on="Moonraker") - -book2 = BookBasedMovie(based_on="Moonraker", year=1979) - -book3 = BookBasedMovie(based_on="Moonraker") - -# This should generate an error because 'author' isn't -# a defined field. -book4 = BookBasedMovie(based_on="Moonraker", author="Ian Fleming") - -# This should generate an error because 'based_on' is -# a required field, and it's not provided. -book5 = BookBasedMovie(year=1982, name="Blade Runner") diff --git a/packages/vipeye-internal/src/tests/samples/typedDict4.py b/packages/vipeye-internal/src/tests/samples/typedDict4.py deleted file mode 100644 index 8b7373fe..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict4.py +++ /dev/null @@ -1,68 +0,0 @@ -# This sample tests the type analyzer's handling of TypedDict classes. - -from typing import Literal, TypedDict - - -class Movie(TypedDict, total=False): - name: str - year: int - - -class BookBasedMovie(Movie, total=True): - based_on: str - - -movie1 = Movie(name="Blade Runner", year=1982) - - -def get_value(movie: Movie, key: Literal["year", "name"]) -> int | str | None: - if "year" in movie and "name" in movie: - return movie[key] - - -def make_movie(name: str, year: int) -> Movie: - return {"name": name, "year": year} - - -name1 = movie1.get("name", "Blue Nile") -year1 = movie1.get("year", 1921) -movie2 = make_movie(name1, year1) - -# This should generate an error because all indices need -# to be string literals. -year2 = movie1[3] - -# This should generate an error because only one index -# is allowed. -year3 = movie1[3, 3] - -movie1["name"] = "Transformers" -movie1["year"] = 2007 - -# This should generate an error because the RHS is the wrong type. -movie1["name"] = [3] - -# This should generate an error because the RHS is the wrong type. -movie1["year"] = {} - -del movie1["year"] - -# This should generate an error because the key is not in the dictionary. -del movie1["year2"] - -# This should generate an error because entries in a TypedDict -# are not accessible through member access. -name2 = movie1.name - -book1 = BookBasedMovie(based_on="E.T.") -make_movie(name=book1["based_on"], year=1923) - -del book1["name"] - -# This should generate an error because you can't delete a required key. -del book1["based_on"] - -# Make sure "in" operator works with TypedDict. -movie3 = Movie() -if "d" in movie3: - pass diff --git a/packages/vipeye-internal/src/tests/samples/typedDict5.py b/packages/vipeye-internal/src/tests/samples/typedDict5.py deleted file mode 100644 index 5b9abe14..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict5.py +++ /dev/null @@ -1,61 +0,0 @@ -# This sample tests the type analyzer's handling of TypedDict classes. - -from typing import TypedDict - - -class Movie1(TypedDict, total=False): - name: str - year: int - - -class Movie2(TypedDict, total=False): - name: str - year: int - - -class Movie3(TypedDict, total=True): - name: str - year: int - - -class Movie4(TypedDict, total=True): - name: str - year: int - earnings: float - - -class Movie5(TypedDict, total=True): - name: str - year: float - - -movie1: Movie1 = Movie2(name="hello", year=1971) - -# This should generate an error because -# items are required in Movie3 but not Movie2. -movie2: Movie2 = Movie3(name="hello", year=1971) - -# This should generate an error because -# items are required in Movie3 but not Movie2. -movie3: Movie3 = Movie2(name="hello", year=1971) - -# This should generate an error. -movie4: Movie4 = Movie3(name="hello", year=1971) - -movie5: Movie3 = Movie4(name="hello", year=1971, earnings=23) - - -movie6 = Movie2(name="hello", year=1971) -movie6["name"] = "goodbye" - -movie7 = {"name": "hello", "year": 1971} -movie7["name"] = "goodbye" - -movie8: Movie2 = {"year": 1981, "name": "test"} -movie8["year"] = 1982 - -movie9 = Movie3(name="", year=1971) - -# This should generate an error because "year" is mutable, -# so its type must match exactly. -movie10: Movie5 = movie9 diff --git a/packages/vipeye-internal/src/tests/samples/typedDict6.py b/packages/vipeye-internal/src/tests/samples/typedDict6.py deleted file mode 100644 index 8ab7f622..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict6.py +++ /dev/null @@ -1,97 +0,0 @@ -# This sample tests the type analyzer's handling of TypedDict -# "alternate syntax" defined in PEP 589. - -from typing import NotRequired, Required, TypedDict - -Movie = TypedDict("Movie", {"name": str, "year": int}) - -# This should generate an error because the arguments are missing. -Movie2 = TypedDict() - -# This should generate an error because the arguments are missing. -Movie3 = TypedDict("Movie3") - -# This should generate an error because the argument type is wrong. -Movie4 = TypedDict("Movie4", 3) - -# This should generate an error because the argument type is wrong. -Movie5 = TypedDict(3, {}) - -Movie6 = TypedDict("Movie6", {}, total=False) -Movie7 = TypedDict("Movie7", {}, total=True) - -# This should generate an error because the total param -# accepts only True or False. -Movie8 = TypedDict("Movie8", {}, total=3) - -# This should generate an error because the third arg is unknown. -Movie9 = TypedDict("Movie9", {}, random=3) - -# This should generate an error because the third arg is unknown. -Movie10 = TypedDict("Movie10", {}, 3) - -# This should generate an error because a fourth arg -# is not supported. -Movie11 = TypedDict("Movie11", {}, total=True, foo=3) - - -def get_movie_name(movie: Movie): - return movie["name"] - - -name2 = get_movie_name({"name": "ET", "year": 1982}) - -movie1: Movie = {"name": "Blade Runner", "year": 1982} - -movie2: Movie = { - "name": "Blade Runner", - # This should generate an error because - # the type is incorrect. - "year": "1982", -} - -movie3: Movie = { - # This should generate an error because - # all keys are required. - "name": "Blade Runner" -} - -movie4: Movie = { - # This should generate an error because - # the key name is not supported. - "name2": "Blade Runner" -} - -MovieNotTotal = TypedDict("MovieNotTotal", {"name": str, "year": int}, total=False) - -movie5: MovieNotTotal = {"name": "Blade Runner"} - - -def foo(unknown_str_value: str): - a = movie5[unknown_str_value] - - -Movie12 = TypedDict( - "Movie12", {"title": Required[str], "predecessor": NotRequired["Movie12"]} -) - -movie12: Movie12 = {"title": "Two Towers", "predecessor": {"title": "Fellowship"}} - - -# This should generate an error because the name doesn't match. -# the arguments are missing. -Movie13 = TypedDict("NotMovie13", {"name": str, "year": int}) - - -# This should generate an error because CustomType1 is a forward reference -# and is not quoted. -Movie14 = TypedDict("Movie14", {"title": CustomType1, "year": "CustomType2"}) - -# This should generate an error because CustomType2 is a forward reference -# and is not quoted. -Movie15 = TypedDict("Movie15", title="CustomType1", year=CustomType2) - - -class CustomType1: ... -class CustomType2: ... - diff --git a/packages/vipeye-internal/src/tests/samples/typedDict7.py b/packages/vipeye-internal/src/tests/samples/typedDict7.py deleted file mode 100644 index 00910fc6..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict7.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests synthesized get methods in TypedDict classes. - -from typing import TypedDict - -UserType1 = TypedDict("UserType1", {"name": str, "age": int}, total=False) -user1: UserType1 = {"name": "Bob", "age": 40} - -name1: str = user1.get("name", "n/a") -age1: int = user1.get("age", 42) - -UserType2 = TypedDict("UserType2", name=str, age=int) -user2: UserType2 = {"name": "Bob", "age": 40} - -name2: str | None = user2.get("name") - -name3: str = user2.get("name") - -age2: int = user2.get("age", 42) - -age3: int | str = user2.get("age", "42") - -age4: int = user2.get("age", "42") diff --git a/packages/vipeye-internal/src/tests/samples/typedDict8.py b/packages/vipeye-internal/src/tests/samples/typedDict8.py deleted file mode 100644 index abb76fce..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict8.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the ability of the type checker to -# perform bidirectional type inference involving TypedDict -# classes and dict literal expressions. - -from typing import TypedDict - - -class Entry(TypedDict): - index: int - value: str - - -entries1: list[Entry] = [{"index": 2, "value": "a"}, {"index": 5, "value": "b"}] - -# This should generate an error -entries2: list[Entry] = [{"index": 2, "value": "a"}, {"index": "2", "value": "b"}] - -# This should generate an error -entries3: list[Entry] = [{"index": 2, "value": "a"}, 3] diff --git a/packages/vipeye-internal/src/tests/samples/typedDict9.py b/packages/vipeye-internal/src/tests/samples/typedDict9.py deleted file mode 100644 index 0176f469..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDict9.py +++ /dev/null @@ -1,47 +0,0 @@ -# This sample tests the handling of nested TypedDict fields. - -from typing import Literal, TypedDict - - -class Inner1(TypedDict): - inner_key: str - - -class Inner2(TypedDict): - inner_key: Inner1 - - -class Outer1(TypedDict): - outer_key: Inner2 - - -o1: Outer1 = {"outer_key": {"inner_key": {"inner_key": "hi"}}} - -# This should generate an error because the inner-most value -# should be a string. -o2: Outer1 = {"outer_key": {"inner_key": {"inner_key": 1}}} - - -class Inner3(TypedDict): - x: int - - -class Inner4(TypedDict): - x: int - - -class Outer2(TypedDict): - y: str - z: Literal[""] | Inner3 - - -class Outer3(TypedDict): - y: str - z: Literal[""] | Inner4 - - -def func1(td: Outer3): ... - - -o3: Outer2 = {"y": "", "z": {"x": 0}} -o4: Outer3 = o3 diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed1.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed1.py deleted file mode 100644 index 414cc74e..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed1.py +++ /dev/null @@ -1,60 +0,0 @@ -# This sample tests basic usage of "closed" TypedDict classes as -# introduced in PEP 728. - -from typing import NotRequired, Required, TypedDict -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - - -class Movie(TypedDict, extra_items=bool): - name: str - - -m1: Movie = {"name": "Blade Runner", "novel_adaptation": True} - -# This should generate an error because int is not compatible with bool. -m2: Movie = {"name": "Blade Runner", "year": 1982} - - -MovieAlt = TypedDict("MovieAlt", {"name": str}, extra_items=bool) - -m_alt1: MovieAlt = {"name": "Blade Runner", "novel_adaptation": True} - -# This should generate an error because int is not compatible with bool. -m_alt2: MovieAlt = {"name": "Blade Runner", "year": 1982} - - -def func1(movie: Movie) -> None: - reveal_type(movie["name"], expected_text="str") - - if "novel_adaptation" in movie: - reveal_type(movie["novel_adaptation"], expected_text="bool") - - movie["other1"] = True - - # This should generate a type incompatibility error. - movie["other2"] = 1 - - -class MovieBase(TypedDict, extra_items=ReadOnly[str | None]): - name: str - - -# This should generate an error. -class BadTD1(TypedDict, extra_items=Required[str]): - pass - - -# This should generate an error. -class BadTD2(TypedDict, extra_items=NotRequired[str]): - pass - - -# This should generate an error. -class BadTD3(TypedDict, closed=True, extra_items=str): - pass - - -# This should generate an error because "closed" and -# "extra_items" cannot both be specified. -class BadTD4(TypedDict, closed=False, extra_items=bool): - name: str diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed10.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed10.py deleted file mode 100644 index 420e2064..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed10.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the case where a type variable is used to define -# the extra_items in a TypedDict. - -from typing_extensions import TypedDict # viper: ignore[reportMissingModuleSource] - - -class TD1[T](TypedDict, extra_items=T): - a: T - - -d1: TD1 = {"a": 1} -d2: TD1[int] = {"a": 1} - -reveal_type(d1["other"], expected_text="Unknown") -reveal_type(d2["other"], expected_text="int") diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed2.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed2.py deleted file mode 100644 index 3e13fc83..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed2.py +++ /dev/null @@ -1,39 +0,0 @@ -# This sample tests basic usage of "closed" TypedDict classes as -# introduced in PEP 728. - -from typing import TypedDict, Unpack - - -class Movie1(TypedDict, extra_items=int): - name: str - - -def func1(movie: Movie1) -> None: - del movie["year"] - - # This should generate an error. - del movie["name"] - - -class Movie2(TypedDict, extra_items=int): - name: str - - -def func2(**kwargs: Unpack[Movie2]) -> None: ... - - -func2(name="") - -func2(name="", foo=1) - -# This should generate an error. -func2(name=1) - -# This should generate an error. -func2(name="", foo="") - - -m1 = Movie1(name="ET", year=1984) - -# This should generate an error. -m2 = Movie1(name="ET", year="1984") diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed3.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed3.py deleted file mode 100644 index 25382ce0..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed3.py +++ /dev/null @@ -1,152 +0,0 @@ -# This sample tests inheritance rules for closed TypedDicts. - -from typing import Any, Never, NotRequired, Required, TypedDict -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - - -class Parent1(TypedDict, extra_items=int | None): - pass - - -class Child1_1(Parent1, extra_items=int | None): - pass - - -# This should generate an error because of a type mismatch. -class Child1_2(Parent1, extra_items=int): - pass - - -class ParentClosed1(TypedDict, closed=True): - a: int - - -class ChildClosed1_1(ParentClosed1, extra_items=Never): - pass - - -# This should generate an error. -class ChildClosed1_2(ParentClosed1): - b: str - - -# This should generate an error because extra_items is incompatible type. -class ChildClosed1_3(ParentClosed1, extra_items=int): - pass - - -class ParentClosed2(TypedDict, extra_items=Never): - a: int - - -# This should generate an error. -class ChildClosed2(ParentClosed2): - b: str - - -class ParentClosed3(TypedDict, extra_items=int | str): - a: int - - -class ChildClosed3_1(ParentClosed3): - b: NotRequired[int | str] - - -class ChildClosed3_2(ParentClosed3): - b: NotRequired[Any] - - -# This should generate an error. -class ChildClosed3_3(ParentClosed3): - b: NotRequired[int] - - -# This should generate an error. -class ChildClosed3_4(ParentClosed3): - b: int | str - - -class ParentClosed4(TypedDict, extra_items=ReadOnly[int | str]): - a: int - - -class ChildClosed4_1(ParentClosed4): - b: int - - -class ChildClosed4_2(ParentClosed4): - b: Any - - -class ChildClosed4_3(ParentClosed4): - b: Required[int] - - -class ChildClosed4_4(ParentClosed4): - b: NotRequired[int] - - -class ChildClosed4_5(ParentClosed4): - b: ReadOnly[int | str] - - -class ChildClosed4_6(ParentClosed4, extra_items=int | str): - pass - - -# This should generate an error. -class ChildClosed4_7(ParentClosed4): - b: list[str] - - -class MovieBase(TypedDict, extra_items=int | None): - name: str - - -# This should generate an error. -class AdaptedMovie(MovieBase): - adapted_from_novel: bool - - -# This should generate an error. -class MovieRequiredYear(MovieBase): - year: int | None - - -# This should generate an error. -class MovieNotRequiredYear(MovieBase): - year: NotRequired[int] - - -class MovieWithYear(MovieBase): - year: NotRequired[int | None] - - -class ParentNonOpen5(TypedDict, closed=True): - pass - - -# This should generate an error because a subclass of -# a closed TypedDict cannot be open. -class ChildNotClosed5(ParentNonOpen5, closed=False): - pass - - -class ParentNonOpen6(TypedDict, extra_items=str): - pass - - -# This should generate an error because a subclass of -# a closed TypedDict cannot be open. -class ChildNotClosed6(ParentNonOpen6, closed=False): - pass - - -class ParentNonOpen7(TypedDict, extra_items=str): - pass - - -# This should generate an error because added fields -# cannot be ReadOnly. -class ChildNotClosed7(ParentNonOpen7): - a: NotRequired[ReadOnly[str]] diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed4.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed4.py deleted file mode 100644 index 5e4502a9..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed4.py +++ /dev/null @@ -1,70 +0,0 @@ -# This sample tests type consistency rules for closed TypedDicts. - -from typing import NotRequired, TypedDict -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - - -class Movie1(TypedDict, extra_items=int | None): - name: str - - -class MovieDetails1(TypedDict, extra_items=int | None): - name: str - year: NotRequired[int] - - -details1: MovieDetails1 = {"name": "Kill Bill Vol. 1", "year": 2003} - -# This should generate an error because of a type incompatibility. -movie1: Movie1 = details1 - - -class MovieDetails2(TypedDict, extra_items=int | None): - name: str - year: int | None - - -details2: MovieDetails2 = {"name": "Kill Bill Vol. 1", "year": 2003} - -# This should generate an error because "year" is not required. -movie2: Movie1 = details2 - - -class Movie3(TypedDict, extra_items=ReadOnly[str | int]): - name: str - - -class MovieDetails3(TypedDict, extra_items=int): - name: str - year: NotRequired[int] - - -details3: MovieDetails3 = {"name": "Kill Bill Vol. 2", "year": 2004} -movie3: Movie3 = details3 - - -class MovieExtraInt(TypedDict, extra_items=int): - name: str - - -class MovieExtraStr(TypedDict, extra_items=str): - name: str - - -def func1(p1: MovieExtraInt, p2: MovieExtraStr): - # This should generate an error because of a type inconsistency. - extra_int: MovieExtraInt = p2 - - # This should generate an error because of a type inconsistency. - extra_str: MovieExtraStr = p1 - - -class MovieNotClosed(TypedDict): - name: str - - -def func2(p1: MovieExtraInt, p2: MovieNotClosed): - # This should generate an error because of a type inconsistency. - extra_int: MovieExtraInt = p2 - - not_closed: MovieNotClosed = p1 diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed5.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed5.py deleted file mode 100644 index 8b2c9ed5..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed5.py +++ /dev/null @@ -1,56 +0,0 @@ -# This sample tests type compatibility between closed TypedDicts and -# Mapping types. - -from typing import Mapping, TypedDict - - -class MovieExtraStr(TypedDict, extra_items=str): - name: str - - -class MovieExtraInt(TypedDict, extra_items=int): - name: str - - -extra_str: MovieExtraStr = {"name": "Blade Runner", "summary": ""} -extra_int: MovieExtraInt = {"name": "No Country for Old Men", "year": 2007} - -str_mapping: Mapping[str, str] = extra_str - -# This should generate an error. -int_mapping: Mapping[str, int] = extra_int - -int_str_mapping: Mapping[str, int | str] = extra_int - - -def func1(movie: MovieExtraStr) -> None: - reveal_type(movie.items(), expected_text="dict_items[str, str]") - reveal_type(movie.keys(), expected_text="dict_keys[str, str]") - reveal_type(movie.values(), expected_text="dict_values[str, str]") - - -class MovieNotClosed(TypedDict): - name: str - - -def func2(movie: MovieNotClosed) -> None: - reveal_type(movie.items(), expected_text="dict_items[str, object]") - reveal_type(movie.keys(), expected_text="dict_keys[str, object]") - reveal_type(movie.values(), expected_text="dict_values[str, object]") - - -class MovieClosed(TypedDict, closed=True): - name: str - year: int - - -def func3(movie: MovieClosed) -> None: - reveal_type( - movie.items(), expected_text="dict_items[Literal['name', 'year'], str | int]" - ) - reveal_type( - movie.keys(), expected_text="dict_keys[Literal['name', 'year'], str | int]" - ) - reveal_type( - movie.values(), expected_text="dict_values[Literal['name', 'year'], str | int]" - ) diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed6.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed6.py deleted file mode 100644 index 34d866b9..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed6.py +++ /dev/null @@ -1,62 +0,0 @@ -# This sample tests type compatibility between closed TypedDicts and -# dict and MutableMapping types. - -from typing import MutableMapping, NotRequired, TypedDict -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - - -class IntDict1(TypedDict, extra_items=int): - pass - - -class IntDictWithNum(IntDict1): - num: NotRequired[int] - - -def func1(x: IntDict1) -> None: - v: dict[str, int] = x - v.clear() - - -def func2(x: dict[str, int]): - # This should generate an error. - not_required_num: IntDictWithNum = x - - -def func3(p1: IntDictWithNum, p2: dict[str, int]): - d1: dict[str, int] = p1 - m1: MutableMapping[str, int] = p1 - func1(p1) - - # This should generate an error. - d2: IntDictWithNum = p2 - - -class IntDict2(TypedDict, extra_items=int): - num: int - - -def func4(p1: IntDict2): - # This should generate an error. - d1: dict[str, int] = p1 - - # This should generate an error. - m1: MutableMapping[str, int] = p1 - - # This should generate an error. - func1(p1) - - -class IntDict3(TypedDict, extra_items=int): - num: NotRequired[ReadOnly[int]] - - -def func5(p1: IntDict3): - # This should generate an error. - d1: dict[str, int] = p1 - - # This should generate an error. - m1: MutableMapping[str, int] = p1 - - # This should generate an error. - func1(p1) diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed7.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed7.py deleted file mode 100644 index 6cacf132..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed7.py +++ /dev/null @@ -1,69 +0,0 @@ -# This sample tests the synthesis of "clear" and "popitem" within a closed -# TypedDict under certain circumstances. - -from typing import NotRequired, Required, TypedDict -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - - -class TD1(TypedDict, total=False, extra_items=int): - a: int - - -td1: TD1 = {"a": 1} - -reveal_type(td1.clear, expected_text="() -> None") -reveal_type(td1.popitem, expected_text="() -> tuple[str, int]") -td1.clear() -td1.popitem() - - -class TD2(TypedDict, total=False, closed=True): - a: str - - -td2: TD2 = {"a": "1"} - -reveal_type(td2.clear, expected_text="() -> None") -reveal_type(td2.popitem, expected_text="() -> tuple[str, str]") -td2.clear() -td2.popitem() - - -class TD3(TypedDict, total=False, extra_items=ReadOnly[int]): - a: int - - -td3: TD3 = {"a": 1} - -# This should generate an error because extra_items is ReadOnly. -td3.clear() - -# This should generate an error because extra_items is ReadOnly. -td3.popitem() - - -class TD4(TypedDict, closed=True): - a: NotRequired[int] - b: Required[int] - - -td4: TD4 = {"b": 1} - -# This should generate an error because not all elements are NotRequired. -td4.clear() - -# This should generate an error because not all elements are NotRequired. -td4.popitem() - - -class TD5(TypedDict, closed=True): - a: NotRequired[ReadOnly[int]] - - -td5: TD5 = {"a": 1} - -# This should generate an error because some elements are ReadOnly. -td5.clear() - -# This should generate an error because some elements are ReadOnly. -td5.popitem() diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed8.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed8.py deleted file mode 100644 index 4768a8cb..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed8.py +++ /dev/null @@ -1,41 +0,0 @@ -# This sample tests the case where bidirectional type inference is required -# for the extra_items in a closed TypedDict. - -from typing_extensions import TypedDict # viper: ignore[reportMissingModuleSource] - - -class Typed(TypedDict, extra_items=str | int): - type: str - - -class Named(TypedDict, extra_items="str | int | Typed | Named"): - name: str - - -td2_1: Named = { - "name": "Fred", - "birth": { - "type": "date", - "year": 2000, - "month": 12, - "day": 31, - }, -} - -td2_2: Named = { - "name": "Fred", - "extra": { - "name": "test", - "value": "", - }, -} - -td2_3: Named = { - "name": "Fred", -} - -td2_4: Named = { - "name": "Fred", - "test1": 1, - "test2": {"name": "Barb", "value": {"type": "date", "day": 31}}, -} diff --git a/packages/vipeye-internal/src/tests/samples/typedDictClosed9.py b/packages/vipeye-internal/src/tests/samples/typedDictClosed9.py deleted file mode 100644 index 3cf3ac59..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictClosed9.py +++ /dev/null @@ -1,37 +0,0 @@ -# This sample tests the handling of calls with unpacked TypedDicts. - - -from typing_extensions import TypedDict # viper: ignore[reportMissingModuleSource] - - -class ClosedTD1(TypedDict, closed=True): - arg1: str - - -class IntDict1(TypedDict, extra_items=int): - arg1: str - - -td1 = ClosedTD1(arg1="hello") -td2 = IntDict1(arg1="hello", arg2=3) - - -def func1(arg1: str): - pass - - -func1(**td1) - -# This should arguably generate an error because there -# could be extra items, but we'll match mypy's behavior here. -func1(**td2) - - -def func2(arg1: str, **kwargs: str): - pass - - -func2(**td1) - -# This should result in an error. -func2(**td2) diff --git a/packages/vipeye-internal/src/tests/samples/typedDictInline1.py b/packages/vipeye-internal/src/tests/samples/typedDictInline1.py deleted file mode 100644 index 77524544..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictInline1.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests support for inlined TypedDict definitions. - -from typing import NotRequired, ReadOnly, Required, TypedDict - - -td1: TypedDict[{"a": int, "b": str}] = {"a": 0, "b": ""} - -td2: TypedDict[{"a": TypedDict[{"b": int}]}] = {"a": {"b": 0}} - -td3: TypedDict[{"a": "list[float]"}] = {"a": [3]} - -td4: TypedDict[ - {"a": NotRequired[int], "b": Required[int], "c": NotRequired[ReadOnly[int]]} -] = {"b": 3} - -# This should generate an error because dictionary comprehensions -# are not allowed. -err1: TypedDict[{"a": int for _ in range(1)}] - -# This should generate an error because unpacked dictionary -# entries are not allowed. -err2: TypedDict[{**{"a": int}}] - -# This should generate an error because an extra type argument is provided. -err3: TypedDict[{"a": int}, str] - -# This should generate an error because TypedDict cannot be used without -# a subscript in this context. -err4: TypedDict - -# This should generate an error because a dict expression is not a -# valid type expression by itself. -err5: TypedDict[{"a": {"b": int}}] = {"a": {"b": 0}} - - -def func1(val: TypedDict[{"a": int}]) -> TypedDict[{"a": int}]: - return {"a": val["a"] + 1} - - -func1({"a": 3}) - - -type TA1[T] = TypedDict[{"a": int, "b": T, "c": NotRequired[int]}] - - -class Outer1[T]: - attr1: TypedDict[{"a": list[T]}] - - def __init__(self, v: T) -> None: - self.attr1 = {"a": [v]} diff --git a/packages/vipeye-internal/src/tests/samples/typedDictReadOnly1.py b/packages/vipeye-internal/src/tests/samples/typedDictReadOnly1.py deleted file mode 100644 index 24187a59..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictReadOnly1.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests error conditions for TypedDict classes with -# read-only entries as introduced in PEP 705. - -# viper: reportIncompatibleVariableOverride=true - -from typing import NotRequired, Required, TypedDict -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - - -class TD1(TypedDict): - a: ReadOnly[int] - b: Required[ReadOnly[str]] - c: ReadOnly[NotRequired[str]] - - # This should generate an error because nested ReadOnly are not allowed. - d: ReadOnly[ReadOnly[str]] - - -TD2 = TypedDict("TD2", {"a": ReadOnly[str]}, total=True) -TD3 = TypedDict("TD3", {"a": ReadOnly[str]}, total=True) - - -class F1(TypedDict): - a: Required[int] - b: ReadOnly[NotRequired[int]] - c: ReadOnly[Required[int]] - - -class F3(F1): - # This should generate an error because it is redefined as read-only. - a: ReadOnly[int] - - -class F4(F1): - # This should generate an error because it is redefined as not required. - a: NotRequired[int] - - -class F5(F1): - b: ReadOnly[Required[int]] - - -class F6(F1): - # This should generate an error because a "not required" field can't - # override a "required" field. - c: ReadOnly[NotRequired[int]] diff --git a/packages/vipeye-internal/src/tests/samples/typedDictReadOnly2.py b/packages/vipeye-internal/src/tests/samples/typedDictReadOnly2.py deleted file mode 100644 index 96d3f052..00000000 --- a/packages/vipeye-internal/src/tests/samples/typedDictReadOnly2.py +++ /dev/null @@ -1,248 +0,0 @@ -# This sample tests various uses of ReadOnly fields in TypedDict classes -# as specified in PEP 705. - -# viper: reportIncompatibleVariableOverride=true - -from typing import ( - Generic, - Literal, - Mapping, - Never, - NotRequired, - Required, - TypeVar, - TypedDict, - Unpack, -) -from typing_extensions import ReadOnly # viper: ignore[reportMissingModuleSource] - -_T = TypeVar("_T") - - -class TD1(TypedDict, Generic[_T]): - a: ReadOnly[int] - b: Required[str] - c: Required[ReadOnly[list[str]]] - d: ReadOnly[Required[dict[str, str]]] - e: ReadOnly[_T] - - -class TD2(TD1[_T]): - e: _T - f: ReadOnly[str] - - -td1: TD1[float] = {"a": 3, "b": "", "c": [], "d": {}, "e": 0.0} - -reveal_type(td1.get("a"), expected_text="int") -reveal_type(td1.get("b"), expected_text="str") -reveal_type(td1.get("c"), expected_text="list[str]") -reveal_type(td1.get("d"), expected_text="dict[str, str]") -reveal_type(td1.get("e"), expected_text="float") - -td2: TD2[float] = {"a": 3, "b": "", "c": [], "d": {}, "e": 0.0, "f": ""} - -x1: TD1[float] = td2 - - -class TD3(TypedDict, total=True): - a: str - b: NotRequired[str] - c: NotRequired[str] - - -class TD4(TypedDict, total=True): - a: ReadOnly[str] - b: NotRequired[str] - c: NotRequired[str] - - -td3: TD3 = {"a": ""} -td4: TD4 = {"a": ""} - -# This should generate an error because "a" is ReadOnly. -# It generates a second error because no overloads are found. -td4.update({"a", ""}) - -# This should generate an error because "a" is ReadOnly. -td4.update(a="") - -# This should generate an error because "a" is ReadOnly. -# It generates a second error because no overloads are found. -td4.update([("a", "")]) - -td4.update({"b": ""}) -td4.update({"b": "", "c": ""}) -td4.update(b="") -td4.update(c="") -td4.update(c="", b="") -td4.update([("b", "")]) -td4.update([("c", "")]) -td4.update([("b", ""), ("c", "")]) - -td5 = td3 | td4 - -# This should generate an error. -td4["a"] = "" - -# This should generate an error. -x3_0: TD3 = td4 -x3_1: TD3 = td3 -x4_0: TD4 = td3 -x4_1: TD4 = td4 - - -def func1(**kwargs: Unpack[TD4]): - # This should generate an error. - kwargs["a"] = "" - - -m1: Mapping[str, object] = td3 -m2: Mapping[str, object] = td4 - - -class TD5(TypedDict): - a: ReadOnly[float | str] - b: ReadOnly[int] - - -class TD6(TD5): - a: int - - # This should generate an error because str is not - # a subtype of int. - b: ReadOnly[str] - - -class TD7(TD6): - # This should generate an error because Literal[3] is - # not the same type as int. - a: Literal[3] - - -class TD8(TypedDict): - a: ReadOnly[NotRequired[int]] - - -class TD9(TypedDict): - a: NotRequired[int] - - -class TD10(TypedDict): - a: int - - -td10: TD10 = {"a": 0} -n1: TD8 = td10 - -# This should generate an error because "a" is writable -# and required in TD10 but writable and not required in -# TD9, which means it can be deleted. -n2: TD9 = td10 - - -class TD11(TypedDict): - a: int - - -class TD12(TypedDict): - a: ReadOnly[float] - - -class TD13(TypedDict): - a: float - - -v1 = TD11(a=2) -v2: TD12 = v1 - -# This should generate an error because "a" is writable -# and is therefore invariant. -v3: TD13 = v1 - - -class TD14(TypedDict): - x: int - - -class TD15(TypedDict): - x: int - y: ReadOnly[NotRequired[str]] - - -td14: TD14 = {"x": 1} - -# This should generate an error because 'str' is not -# compatible with 'object'. -td15: TD15 = td14 - - -class TD16(TypedDict): - x: int - - -class TD17(TypedDict): - x: int - y: ReadOnly[NotRequired[object]] - - -td16: TD16 = {"x": 1} -ted17: TD17 = td16 - - -class TD18(TypedDict): - x: NotRequired[ReadOnly[int]] - y: int - - -td18_1: TD18 = {"x": 1, "y": 2} -td18_2: TD18 = {"x": 2, "y": 4} - -# This should generate an error because "x" is read-only. -# It generates a second error because no overloads are found. -td18_1.update(td18_2) - - -class TD19(TypedDict): - x: NotRequired[Never] - y: ReadOnly[int] - - -def update_a(a: TD18, b: TD19) -> None: - a.update(b) - - -class TD20(TypedDict): - pass - - -td20 = TD20() -td20.update(TD20()) - - -class TD_A1(TypedDict): - x: int - y: ReadOnly[int] - - -class TD_A2(TypedDict): - x: float - y: ReadOnly[float] - - -# This should generate an error for x but not y. -class TD_A(TD_A1, TD_A2): ... - - -class TD_B1(TypedDict): - x: ReadOnly[NotRequired[int]] - y: ReadOnly[Required[int]] - - -class TD_B2(TypedDict): - x: ReadOnly[Required[int]] - y: ReadOnly[NotRequired[int]] - - -# This should generate an error for x but not y. -class TD_B(TD_B1, TD_B2): ... diff --git a/packages/vipeye-internal/src/tests/samples/unbound1.py b/packages/vipeye-internal/src/tests/samples/unbound1.py deleted file mode 100644 index 24163422..00000000 --- a/packages/vipeye-internal/src/tests/samples/unbound1.py +++ /dev/null @@ -1,18 +0,0 @@ -# This sample tests the type checker's ability to determine which -# symbols are potentially unbound. - -if True: - - class X: - # This should generate an error because 'X' is not yet declared. - def func1(self) -> X: - return X() - - a: X - - class A: - a: X - b = X - - def fn(self) -> X: - return X() diff --git a/packages/vipeye-internal/src/tests/samples/unbound2.py b/packages/vipeye-internal/src/tests/samples/unbound2.py deleted file mode 100644 index fb4a4d48..00000000 --- a/packages/vipeye-internal/src/tests/samples/unbound2.py +++ /dev/null @@ -1,12 +0,0 @@ -# This sample validates that an unbound variable error is reported -# even if that variable has a type declaration. - - -def func1(): - aaa: int - - # This should generate an error because aaa is unbound. - return aaa - - -func1() diff --git a/packages/vipeye-internal/src/tests/samples/unbound3.py b/packages/vipeye-internal/src/tests/samples/unbound3.py deleted file mode 100644 index 3294d5c9..00000000 --- a/packages/vipeye-internal/src/tests/samples/unbound3.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests that "possibly unbound" error messages don't propagate. - - -def func1(a: bool): - if a: - b = 3 - - # This should generate an error. - c = b - - # These should not. - d = c - e = d diff --git a/packages/vipeye-internal/src/tests/samples/unbound4.py b/packages/vipeye-internal/src/tests/samples/unbound4.py deleted file mode 100644 index bdd175f7..00000000 --- a/packages/vipeye-internal/src/tests/samples/unbound4.py +++ /dev/null @@ -1,25 +0,0 @@ -# This sample tests that an unbound variable that is generated in -# a function does not propagate beyond that function to callers. - - -def func1(): - # This should generate an error - return a - - -# This should not. -b = func1() -reveal_type(b, expected_text="Unknown") - - -def func2(val: int): - if val < 3: - return val - - # This should generate an error - return a - - -# This should not. -c = func2(36) -reveal_type(c, expected_text="int | Unknown") diff --git a/packages/vipeye-internal/src/tests/samples/unbound5.py b/packages/vipeye-internal/src/tests/samples/unbound5.py deleted file mode 100644 index 0a9c245a..00000000 --- a/packages/vipeye-internal/src/tests/samples/unbound5.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests the interplay between unbound symbol detection and -# the code that handles conditional narrowing of captured variables. - -from random import random - - -if random() > 0.5: - from datetime import datetime - from math import cos - -# The following should generate an error because datetime -# is "narrowed" across execution scopes. -test0 = lambda: datetime - - -def test1(): - # The following should generate an error because datetime - # is "narrowed" across execution scopes. - return datetime - - -test2 = lambda: cos - - -def test2(): - return cos - - -# This modification means that cos will not be narrowed -# across execution scopes. -cos = None diff --git a/packages/vipeye-internal/src/tests/samples/unbound6.py b/packages/vipeye-internal/src/tests/samples/unbound6.py deleted file mode 100644 index 119d9927..00000000 --- a/packages/vipeye-internal/src/tests/samples/unbound6.py +++ /dev/null @@ -1,64 +0,0 @@ -# This sample tests the case where a variable in an outer scope is captured -# by inner scopes and is potentially unbound. - - -def func1(): - if 1 + 1 > 3: - y = 0 - - class A: - def method1(self): - # This should generate a "possibly unbound" error. - print(y) - - def inner(): - # This should generate a "possibly unbound" error. - print(y) - - # This should generate a "possibly unbound" error. - v = lambda: y - - # This should generate a "possibly unbound" error. - x = [m + y for m in range(3)] - - def func1(self): - # This should generate a "possibly unbound" error. - print(y) - - def inner(): - # This should generate a "possibly unbound" error. - print(y) - - # This should generate a "possibly unbound" error. - v = lambda: y - - # This should generate a "possibly unbound" error. - x = [m + y for m in range(3)] - - # The code below should not generate any errors because - # z is assigned a value later. - if 1 + 1 > 3: - z = 0 - - class B: - def method1(self): - print(z) - - def inner(): - print(z) - - v = lambda: z - - x = [m + z for m in range(3)] - - def func2(self): - print(z) - - def inner(): - print(z) - - v = lambda: z - - x = [m + z for m in range(3)] - - z = 0 diff --git a/packages/vipeye-internal/src/tests/samples/unicode1.py b/packages/vipeye-internal/src/tests/samples/unicode1.py deleted file mode 100644 index 3d261c44..00000000 --- a/packages/vipeye-internal/src/tests/samples/unicode1.py +++ /dev/null @@ -1,42 +0,0 @@ -# This sample tests a variety of unicode characters including those that -# require two-code (surrogate) forms. - -# Old Italic -𐌎𐌘𐌟𐌁 = 42 - -# Egyptian hieroglyphs -𓃘𓐭𓇀𓅨𓆙 = 2 - -# Linear B Ideograms -𐂂𐃪𐃯 = "" - -# Cuneiform -𒀟𒀕𒀰𒁜𒂐𒄊 = "" - -# Old Persian -𐎠𐏊𐏏 = 3 - -# Lydian -𐤢𐤷𐤬𐤮 = 4 - -# Phoenician -𐤔𐤑𐤇 = 4 - -# Nabataean -𐢖𐢊ﬗ = 0 - -# CJK ideographs -㐀䶿一鿿𠀀𪛖𪜀𫜴𫝀𫠝𫠠𬺡𬺰𮯠𣎴 = 1 - -# This should generate an error because "𐢭" is outside the range of -# characters supported by the Python standard. -𐢭 = 0 - -# Other surrogate characters -𝓐 = 3 -𝙰 = 4 -𝚫 = 3 -𞡏 = 4 -𞥁 = 0 - - diff --git a/packages/vipeye-internal/src/tests/samples/uninitializedVariable1.py b/packages/vipeye-internal/src/tests/samples/uninitializedVariable1.py deleted file mode 100644 index c17db89b..00000000 --- a/packages/vipeye-internal/src/tests/samples/uninitializedVariable1.py +++ /dev/null @@ -1,46 +0,0 @@ -# This sample tests the reportUninitializedInstanceVariable functionality. - -from abc import ABC -from dataclasses import dataclass -from typing import Protocol, TypedDict, final - - -class A: - # This should generate an error if reportUninitializedInstanceVariable - # is enabled. - v1: int - v2: int - v3 = 2 - v4: int = 3 - - def __init__(self) -> None: - self.v2 = 3 - super().__init__() - - -@dataclass -class B: - x: int - - -class C(TypedDict): - member1: str - member2: str - - -# Protocol classes are exempt. -class D(Protocol): - x: str - y: str - - -# ABCs are exempt. -class E(ABC): - x: str - y: str - - -# Unless they are final. -@final -class ESub(E): - z: str diff --git a/packages/vipeye-internal/src/tests/samples/uninitializedVariable2.py b/packages/vipeye-internal/src/tests/samples/uninitializedVariable2.py deleted file mode 100644 index a2214e95..00000000 --- a/packages/vipeye-internal/src/tests/samples/uninitializedVariable2.py +++ /dev/null @@ -1,68 +0,0 @@ -# This sample tests the reportUninitializedInstanceVariable when applied -# to a concrete implementation of an abstract base class that defines -# (but does not assign) variables. - -from abc import ABC, abstractmethod -from dataclasses import dataclass, field -from typing import NamedTuple, final - - -class Abstract1(ABC): - x: str - - -@final -# This should generate an error because x is unimplemented. -class A(Abstract1): - pass - - -class B(Abstract1): - pass - - -@final -class C(Abstract1): - x = "" - - -@final -class D(Abstract1): - def __init__(self): - self.x = "" - - -class Abstract2(Abstract1): - y: str - - -@final -# This should generate an error because x and y are unimplemented. -class E(Abstract2): - pass - - -class Abstract3(Abstract1): - x = "" - - -@final -class G(Abstract3): - pass - - -class H(NamedTuple): - x: int - - -@dataclass -class IAbstract(ABC): - p1: str - p2: int = field(init=False) - - -@final -@dataclass -# This should generate an error because p2 is uninitialized. -class I(IAbstract): - p3: int diff --git a/packages/vipeye-internal/src/tests/samples/uninitializedVariable3.py b/packages/vipeye-internal/src/tests/samples/uninitializedVariable3.py deleted file mode 100644 index c66612ac..00000000 --- a/packages/vipeye-internal/src/tests/samples/uninitializedVariable3.py +++ /dev/null @@ -1,13 +0,0 @@ -# This sample tests a special case for the reportUninitializedInstanceVariable -# test involving NamedTuple classes. - -# viper: reportUninitializedInstanceVariable=true - -from typing import final, NamedTuple - - -@final -class A(NamedTuple): - x: int - y: float - diff --git a/packages/vipeye-internal/src/tests/samples/unions1.py b/packages/vipeye-internal/src/tests/samples/unions1.py deleted file mode 100644 index 20951088..00000000 --- a/packages/vipeye-internal/src/tests/samples/unions1.py +++ /dev/null @@ -1,76 +0,0 @@ -# This sample tests the alternative syntax for unions as -# documented in PEP 604. - -from typing import Callable, Generic, TypeVar, Union - - -def func1(a: int | str): - if isinstance(a, int): - return 1 - else: - return 2 - - -B = bytes | None | Callable[[], None] -A = int | str | B - - -def func2(a: A) -> B: - if a == 3 or a is None: - return b"" - elif not isinstance(a, (int, str, bytes)): - a() - - -def func3(A: "int | str"): - return 1 - - -T = TypeVar("T") - - -def func4(a: str): - def helper(value: T) -> T | None: ... - - class Baz(Generic[T]): - qux: T | None - - reveal_type(helper(a), expected_text="str | None") - reveal_type(Baz[str]().qux, expected_text="str | None") - - -T = TypeVar("T") -TT = TypeVar("TT", bound=type) - - -def decorator1(value: type[T]) -> type[T]: ... - - -def decorator2(value: TT) -> TT: ... - - -class ClassA: - class ClassA_A: - pass - - @decorator1 - class ClassA_B: - pass - - @decorator2 - class ClassA_C: - pass - - -a_or_str: "ClassA.ClassA_A | str" -b_or_str: "ClassA.ClassA_B | str" -b_or_str_Union: Union[ClassA.ClassA_B, str] -c_or_str: "ClassA.ClassA_C | str" - -Alias1 = None | str -Alias2 = str | None - -_T = TypeVar("_T") - -Alias3 = _T | str -Alias4 = str | _T diff --git a/packages/vipeye-internal/src/tests/samples/unions2.py b/packages/vipeye-internal/src/tests/samples/unions2.py deleted file mode 100644 index a73b7893..00000000 --- a/packages/vipeye-internal/src/tests/samples/unions2.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample verifies that bitwise or operator is not -# interpreted as a Union operator in cases where it -# shouldn't be. - -from typing import Any - - -class Class1: - def __init__(self, v): - self._v = v - - -def test_bad_syntax(a: Any, b: Any): - r = Class1(a | b) - print(r) diff --git a/packages/vipeye-internal/src/tests/samples/unions3.py b/packages/vipeye-internal/src/tests/samples/unions3.py deleted file mode 100644 index 81c8bcf6..00000000 --- a/packages/vipeye-internal/src/tests/samples/unions3.py +++ /dev/null @@ -1,49 +0,0 @@ -# This sample verifies that the "logical or" operator -# is supported for classes that have a custom metaclass -# with a __or__ or __ror__ method defined. - -# viper: reportIncompatibleMethodOverride=false - -from typing import Type, TypeVar - - -class ClassWithNoMeta1: - pass - - -class ClassWithNoMeta2: - pass - - -NoMetaUnion = ClassWithNoMeta1 | ClassWithNoMeta2 - - -def func1(x: NoMetaUnion): - reveal_type(x, expected_text="ClassWithNoMeta1 | ClassWithNoMeta2") - - -_T = TypeVar("_T") - - -class Metaclass1(type): - def __or__(cls: _T, other: type) -> _T: ... - - -class Metaclass2(type): - def __ror__(cls: _T, other: type) -> _T: ... - - -class ClassWithMeta1(metaclass=Metaclass1): - pass - - -class ClassWithMeta2(metaclass=Metaclass2): - pass - - -def requires_class_with_meta1(val: Type[ClassWithMeta1]): - pass - - -MetaOr1 = ClassWithMeta1 | ClassWithNoMeta1 -requires_class_with_meta1(MetaOr1) diff --git a/packages/vipeye-internal/src/tests/samples/unions4.py b/packages/vipeye-internal/src/tests/samples/unions4.py deleted file mode 100644 index 3ecc2e39..00000000 --- a/packages/vipeye-internal/src/tests/samples/unions4.py +++ /dev/null @@ -1,30 +0,0 @@ -# This sample tests the incorrect usage of Union types. - -from typing import Union - -x = Union[int, str] - -y = Union[int] - -z = Union - -# This should generate an error. -v1: Union[int] - - -# This should generate an error. -def func1() -> Union: ... - - -# This should generate an error. -var1: Union - - -# This should generate two errors. -def func2(x: (list | set)[int]): - reveal_type(x) - - -# This should generate two errors. -def func3(x: Union[list, set][int]): - reveal_type(x) diff --git a/packages/vipeye-internal/src/tests/samples/unions5.py b/packages/vipeye-internal/src/tests/samples/unions5.py deleted file mode 100644 index a6b361bf..00000000 --- a/packages/vipeye-internal/src/tests/samples/unions5.py +++ /dev/null @@ -1,44 +0,0 @@ -# This sample tests the handling of runtime union expressions that -# are used in contexts other than a type annotation. - -from types import UnionType -from typing import Optional, Union - - -class Class1: - a: int - - -class Class2: - a: int - - -# This should generate an error -a1: type[Class1] | type[Class2] = Class1 | Class2 - -# This should generate an error -a2: type[Class1] | type[Class2] = Union[Class1, Class2] - - -b1 = Class1 | Class2 - -# This should generate an error -print(b1.a) - -# This should generate an error -b1() - - -b2 = Union[Class1, Class2] - -# This should generate an error -print(b2.a) - -# This should generate an error -b2() - - -c1: UnionType -c1 = int | str -c1 = Union[int, str] -c1 = Optional[int] diff --git a/packages/vipeye-internal/src/tests/samples/unions6.py b/packages/vipeye-internal/src/tests/samples/unions6.py deleted file mode 100644 index 35e2a3d1..00000000 --- a/packages/vipeye-internal/src/tests/samples/unions6.py +++ /dev/null @@ -1,58 +0,0 @@ -# This sample tests that union type compatibility does not depend on -# the order of the elements in the union. - -from __future__ import annotations - -from typing import ( - Awaitable, - Callable, - MutableSequence, - Protocol, - SupportsIndex, - TypeGuard, - TypeVar, - overload, -) - -T_co = TypeVar("T_co", covariant=True) -_T = TypeVar("_T") - - -class MyList(MutableSequence[_T]): - @overload - def __getitem__(self, index: SupportsIndex) -> _T: # type: ignore - ... - - @overload - def __getitem__(self, index: slice) -> MyList[_T]: ... - - -class NestedSequence(Protocol[T_co]): - @overload - def __getitem__(self, index: int, /) -> T_co | NestedSequence[T_co]: ... - - @overload - def __getitem__(self, index: slice, /) -> NestedSequence[T_co]: ... - - -def func1(b: MyList[int | MyList[int]]): - _: NestedSequence[int] = b - - -def func2(c: MyList[MyList[int] | int]): - _: NestedSequence[int] = c - - -def is_async_callable( - obj: Callable[..., _T] | Callable[..., Awaitable[_T]], -) -> TypeGuard[Callable[..., Awaitable[_T]]]: ... - - -async def func3(fn: Callable[[], _T] | Callable[[], Awaitable[_T]]): - if is_async_callable(fn): - return await fn() - - -async def func4(fn: Callable[[], Awaitable[_T]] | Callable[[], _T]): - if is_async_callable(fn): - return await fn() diff --git a/packages/vipeye-internal/src/tests/samples/unnecessaryCast1.py b/packages/vipeye-internal/src/tests/samples/unnecessaryCast1.py deleted file mode 100644 index 897cf0df..00000000 --- a/packages/vipeye-internal/src/tests/samples/unnecessaryCast1.py +++ /dev/null @@ -1,57 +0,0 @@ -# This sample tests the type checker's reportUnnecessaryCast feature. - -from typing import Annotated, Never, NoReturn, TypeVar, cast - - -def func1(a: int): - # This should generate an error if - # reportUnnecessaryCast is enabled. - v1 = cast(int, a) - - -def func2(a: int | str): - v1 = cast(int, a) - - b: str = "hello" - v2 = cast(int, b) - - -def func3(a: int | None): - v1 = cast(int, a) - - # This should generate an error if - # reportUnnecessaryCast is enabled. - v2 = cast(int | None, a) - - -T = TypeVar("T") - - -def func4(a: list[T]) -> list[T]: - # This should generate an error if - # reportUnnecessaryCast is enabled. - v1 = cast(list[T], a) - - return a - - -def func5(a: Never): - # This should generate an error if - # reportUnnecessaryCast is enabled. - v1 = cast(NoReturn, a) - - -def func6(a: type[int], b: int): - v1 = cast(int, a) - v2 = cast(type[int], b) - - # This should generate an error if - # reportUnnecessaryCast is enabled. - v3 = cast(type[int], a) - - # This should generate an error if - # reportUnnecessaryCast is enabled. - v4 = cast(int, b) - - -AnnotatedInt = cast(type[int], Annotated[int, ...]) diff --git a/packages/vipeye-internal/src/tests/samples/unnecessaryContains1.py b/packages/vipeye-internal/src/tests/samples/unnecessaryContains1.py deleted file mode 100644 index 940ba37f..00000000 --- a/packages/vipeye-internal/src/tests/samples/unnecessaryContains1.py +++ /dev/null @@ -1,65 +0,0 @@ -# This sample tests the "reportUnnecessaryContains" diagnostic rule. - -from enum import Enum -from typing import Literal, TypeVar - -T1 = TypeVar("T1") -T2 = TypeVar("T2", bound=str) - - -def func1(x: str | int): - if x in ("a",): - return - - # This should generate an error if "reportUnnecessaryContains" is enabled. - if x in (b"a",): - return - - -def func2(x: Literal[1, 2, 3]): - if x in ("4", 1): - return - - # This should generate an error if "reportUnnecessaryContains" is enabled. - if x not in ("4", "1"): - pass - - # This should generate an error if "reportUnnecessaryContains" is enabled. - if x in (4, 5): - return - - -def func3(x: list[str]): - if x in (["hi"], [2, 3]): - return - - # This should generate an error if "reportUnnecessaryContains" is enabled. - if x not in ((1, 2), (3,)): - pass - - -def func4(x: list[T1]) -> T1: - if 0 not in x: - pass - return x[0] - - -def func5(x: list[T2]) -> T2: - # This should generate an error if "reportUnnecessaryContains" is enabled. - if 0 not in x: - pass - return x[0] - - -class Enum1(Enum): - a = "a" - b = "b" - c = "c" - - @property - def is_ab(self): - return self in (Enum1.a, Enum1.b) - - @property - def is_c(self): - return self not in (Enum1.a, Enum1.b) diff --git a/packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance1.py b/packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance1.py deleted file mode 100644 index 5b72dcfb..00000000 --- a/packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance1.py +++ /dev/null @@ -1,83 +0,0 @@ -# This sample tests for isinstance calls that always evaluate to true. - -from typing import ClassVar, Protocol, TypedDict, runtime_checkable -from unknown_import import CustomClass1 - - -class CustomClass2(CustomClass1): - pass - - -def func1(p1: int, p2: int | str): - a = isinstance(p2, str) - - b = isinstance(p2, (int, float)) - - # This should generate an error because this is always true. - c = isinstance(p2, (float, dict, int, str)) - - d = isinstance(p1, float) - - e = isinstance(p2, (float, dict, int)) - - # This should generate an error because this is always true. - f = isinstance(p1, int) - - # This should not generate an error because it's within an assert. - assert isinstance(p1, int) - - g = CustomClass2() - # This should not generate an error because CustomClass2 - # derives from an unknown type. - g = isinstance(g, CustomClass1) - - -class SomeTypedDict(TypedDict): - name: str - - -def func2(p1: SomeTypedDict, p2: int | SomeTypedDict): - a = isinstance(p2, dict) - - # This should generate an error because it's always true. - b = isinstance(p1, dict) - - -@runtime_checkable -class BaseClass(Protocol): - text: ClassVar[str] = "FOO" - - -class ClassA: - text: ClassVar[str] = "BAR" - - -class ClassB: - text: ClassVar[str] = "BAZ" - - -class ClassC: - pass - - -def func3(obj: BaseClass): - if isinstance(obj, (ClassA, ClassB)): - reveal_type(obj, expected_text="ClassA | ClassB") - - if isinstance(obj, (ClassA, ClassB, ClassC)): - reveal_type(obj, expected_text="ClassA | ClassB") - - -class A: - pass - - -class B(A): - pass - - -def func4(a: A, cls: type[A]) -> None: - isinstance(a, cls) - - # This should generate an error because it's always true. - isinstance(a, A) diff --git a/packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance2.py b/packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance2.py deleted file mode 100644 index d1c938fb..00000000 --- a/packages/vipeye-internal/src/tests/samples/unnecessaryIsInstance2.py +++ /dev/null @@ -1,35 +0,0 @@ -# This sample tests for isinstance calls that never evaluate to true. - -from typing import final - - -class ABase: ... - - -@final -class AFinal(ABase): ... - - -class BBase: ... - - -@final -class BFinal(BBase): ... - - -def func1(a: AFinal, b: BFinal): - # This should generate an error if reportUnnecessaryIsinstance is true. - if isinstance(a, BBase): - reveal_type(a) - - # This should generate an error if reportUnnecessaryIsinstance is true. - if isinstance(a, BBase): - reveal_type(a) - - -def func2(a: ABase, b: BBase): - if isinstance(a, BBase): - reveal_type(a) - - if isinstance(b, ABase): - reveal_type(b) diff --git a/packages/vipeye-internal/src/tests/samples/unnecessaryIsSubclass1.py b/packages/vipeye-internal/src/tests/samples/unnecessaryIsSubclass1.py deleted file mode 100644 index 2bb54367..00000000 --- a/packages/vipeye-internal/src/tests/samples/unnecessaryIsSubclass1.py +++ /dev/null @@ -1,20 +0,0 @@ -# This sample tests issubclass calls that always evaluate to true. - - -def func1(p1: type[int], p2: type[int] | type[str]): - a = issubclass(p2, str) - - b = issubclass(p2, (int, float)) - - # This should generate an error because this is always true. - c = issubclass(p2, (float, dict, int, str)) - - d = issubclass(p1, float) - - e = issubclass(p2, (float, dict, int)) - - # This should generate an error because this is always true. - f = issubclass(p1, int) - - # This should not generate an error because it's within an assert. - assert issubclass(p1, int) diff --git a/packages/vipeye-internal/src/tests/samples/unpack1.py b/packages/vipeye-internal/src/tests/samples/unpack1.py deleted file mode 100644 index 9c05ef14..00000000 --- a/packages/vipeye-internal/src/tests/samples/unpack1.py +++ /dev/null @@ -1,53 +0,0 @@ -# This sample tests the type checker's handling of the unpack operator. - -# viper: strictListInference=true - - -class Class1: ... - - -class Class2: ... - - -a = [1, "hello", 3.4, Class1()] - -b = [*a] - - -def int_only(a: int): ... - - -for c in b: - if not isinstance(c, (float, str)): - # This should generate an error because c can - # be an int or foo. - int_only(c) - - if not isinstance(c, Class1): - # This should not generate an error. - int_only(c) - -# This should generate an error -x1 = *(1, 2, 3) - -x2 = 2, *(1, 2, 3) - -x3 = *(1, 2, 3), 2 - - -[d1, *e1, f1] = [1, 2, 3, 4] -reveal_type(e1, expected_text="list[int]") - -[*d2, e2, f2] = [1, 2, 3, 4] -reveal_type(d2, expected_text="list[int]") - -[d3, e3, *f3] = (1, 2, 3, 4) -reveal_type(f3, expected_text="list[int]") - -[g1, g2, g3] = (1, 2, 3) - -# This should generate an error. -[g1, g2, g3, g4] = (1, 2, 3) - -# This should generate an error. -[g1, g2] = (1, 2, 3) diff --git a/packages/vipeye-internal/src/tests/samples/unpack2.py b/packages/vipeye-internal/src/tests/samples/unpack2.py deleted file mode 100644 index f2ecf9c5..00000000 --- a/packages/vipeye-internal/src/tests/samples/unpack2.py +++ /dev/null @@ -1,27 +0,0 @@ -# This sample tests the creation of tuples from unpacked values. - -from typing import Any - - -def foo() -> tuple[int, int, int]: - rest = (2, 3) - t = 1, *rest - return t - - -def foo2() -> tuple[int, int, int]: - rest = (3, 4) - t = 1, 2, *rest - # This should generate an error - return t - - -def foo3() -> tuple[Any, ...]: - rest = [1, 2, 3] - t = 1, 2, 3, *rest - requires_list(rest) - return t - - -def requires_list(a: list[int]): - return None diff --git a/packages/vipeye-internal/src/tests/samples/unpack3.py b/packages/vipeye-internal/src/tests/samples/unpack3.py deleted file mode 100644 index 39abdf98..00000000 --- a/packages/vipeye-internal/src/tests/samples/unpack3.py +++ /dev/null @@ -1,16 +0,0 @@ -# This sample tests the reporting of errors related to -# unpack operators within tuple expressions not enclosed -# in parentheses when used with return statements. Support -# for this was added in Python 3.8. - - -def test1(): - a = [1, 2, 3] - b = (4, *a, 5) - return (4, *b, 5) - - -def test2(): - a = [1, 2, 3] - # This should generate an error for versions of Python <3.8 - return 4, *a, 5 diff --git a/packages/vipeye-internal/src/tests/samples/unpack4.py b/packages/vipeye-internal/src/tests/samples/unpack4.py deleted file mode 100644 index aa008647..00000000 --- a/packages/vipeye-internal/src/tests/samples/unpack4.py +++ /dev/null @@ -1,19 +0,0 @@ -# This sample tests the handling of multiple unpack operators in a -# star expression. - -a = [1, 2] -b = ["3", "4"] - -# This should generate an error for versions of Python <3.9 -for x in *a, *b: - print(x) - -c = *a, *b -print(c) - -# This should always generate an error. -*a, *b = (1, 2) - - -def func1(x: str): - "".join([*sorted([x])]) diff --git a/packages/vipeye-internal/src/tests/samples/unpack5.py b/packages/vipeye-internal/src/tests/samples/unpack5.py deleted file mode 100644 index a6038138..00000000 --- a/packages/vipeye-internal/src/tests/samples/unpack5.py +++ /dev/null @@ -1,86 +0,0 @@ -# This sample tests unpacking of tuples that contain PEP 646-style -# tuples with unknown length within them. - - -def suffix() -> tuple[int, str, *tuple[bool, ...]]: - return 1, "a", True - - -def test_suffix(): - a1, a2, a3 = suffix() - reveal_type(a1, expected_text="int") - reveal_type(a2, expected_text="str") - reveal_type(a3, expected_text="bool") - - *b1, b2, b3 = suffix() - # This case is ambiguous. - reveal_type(b1, expected_text="list[int]") - reveal_type(b2, expected_text="str") - reveal_type(b3, expected_text="bool") - - c1, *c2, c3 = suffix() - # This case is ambiguous. - reveal_type(c1, expected_text="int") - reveal_type(c2, expected_text="list[str]") - reveal_type(c3, expected_text="bool") - - d1, d2, *d3 = suffix() - reveal_type(d1, expected_text="int") - reveal_type(d2, expected_text="str") - reveal_type(d3, expected_text="list[bool]") - - -def prefix() -> tuple[*tuple[int, ...], str, bool]: - return 1, "a", True - - -def test_prefix(): - a1, a2, a3 = prefix() - reveal_type(a1, expected_text="int") - reveal_type(a2, expected_text="str") - reveal_type(a3, expected_text="bool") - - *b1, b2, b3 = prefix() - reveal_type(b1, expected_text="list[int]") - reveal_type(b2, expected_text="str") - reveal_type(b3, expected_text="bool") - - c1, *c2, c3 = prefix() - # This case is ambiguous. - reveal_type(c1, expected_text="int") - reveal_type(c2, expected_text="list[str]") - reveal_type(c3, expected_text="bool") - - d1, d2, *d3 = prefix() - # This case is ambiguous. - reveal_type(d1, expected_text="int") - reveal_type(d2, expected_text="str") - reveal_type(d3, expected_text="list[bool]") - - -def middle() -> tuple[int, *tuple[str, ...], bool]: - return 1, "a", True - - -def test_middle(): - a1, a2, a3 = middle() - reveal_type(a1, expected_text="int") - reveal_type(a2, expected_text="str") - reveal_type(a3, expected_text="bool") - - *b1, b2, b3 = middle() - # This case is ambiguous. - reveal_type(b1, expected_text="list[int]") - reveal_type(b2, expected_text="str") - reveal_type(b3, expected_text="bool") - - c1, *c2, c3 = middle() - reveal_type(c1, expected_text="int") - reveal_type(c2, expected_text="list[str]") - reveal_type(c3, expected_text="bool") - - d1, d2, *d3 = middle() - # This case is ambiguous. - reveal_type(d1, expected_text="int") - reveal_type(d2, expected_text="str") - reveal_type(d3, expected_text="list[bool]") diff --git a/packages/vipeye-internal/src/tests/samples/unreachable1.py b/packages/vipeye-internal/src/tests/samples/unreachable1.py deleted file mode 100644 index 43d94896..00000000 --- a/packages/vipeye-internal/src/tests/samples/unreachable1.py +++ /dev/null @@ -1,132 +0,0 @@ -# This sample tests the detection and reporting of unreachable code. - -import os -import sys -from abc import abstractmethod -from typing import NoReturn - - -def func1(): - """ - Docstring - """ - raise NotImplementedError() - - -class Foo: - b: bool - - @staticmethod - def method1(): - """ - Docstring - """ - raise NotImplementedError("Not Implemented") - - def method2(self, a: int): - """ - Docstring - """ - if a < 10 or self.b: - raise NotImplementedError() - - @abstractmethod - def method3(self): - print(self.b) - raise RuntimeError() - - def method4(self) -> None: - print(self.b) - raise RuntimeError() - - def method5(self) -> NoReturn: - print(self.b) - raise RuntimeError() - - -def func2(): - func1() - - # This should not be marked unreachable because NotImplementedError - # is special-cased. - return 3 - - -def func3(foo: Foo): - foo.method1() - return 3 - - -def func4(foo: Foo): - foo.method2(2) - return 3 - - -def func5(foo: Foo): - foo.method3() - return 3 - - -def func6(foo: Foo): - foo.method4() - return 3 - - -def func7(foo: Foo): - foo.method5() - - # This should be marked as unreachable. - # If reportUnreachable is enabled, it should generate a diagnostic. - return 3 - - -def func8() -> NoReturn: - raise NameError() - - -def func9(): - func8() - - # This should be marked unreachable. - # If reportUnreachable is enabled, it should generate a diagnostic. - return 3 - - -def func10(): - e = OSError() - a1 = os.name == "nt" and None == e.errno - reveal_type(a1, expected_text="bool") - - a2 = True and os.name == "nt" - reveal_type(a2, expected_text="bool") - - if os.name == "nt": - # This should be marked unreachable. - b = e.errno - - if sys.version_info >= (4, 0): - # This should be marked unreachable. - b = e.errno - - return - # This should be marked unreachable. - # If reportUnreachable is enabled, it should generate a diagnostic. - b = e.errno - - -def func11(obj: str) -> list: - if isinstance(obj, str): - return [] - else: - # This should be marked as unreachable. - # If reportUnreachable is enabled, it should generate a diagnostic. - return obj - - -def func12(obj: str) -> list: - if isinstance(obj, str): - return [] - - # This should be marked as unreachable. - # If reportUnreachable is enabled, it should generate a diagnostic. - return obj diff --git a/packages/vipeye-internal/src/tests/samples/unusedCallResult1.py b/packages/vipeye-internal/src/tests/samples/unusedCallResult1.py deleted file mode 100644 index 4c4bbdfd..00000000 --- a/packages/vipeye-internal/src/tests/samples/unusedCallResult1.py +++ /dev/null @@ -1,67 +0,0 @@ -# This sample tests the reportUnusedCallResult diagnostic rule. - -from typing import Any, Iterable - - -def func1(): - pass - - -def func2(): - raise RuntimeError() - - -def func3() -> Any: - pass - - -def func4(): - return 3 - - -def func5(a: int) -> int | list[int]: - if a < 0: - return 5 - return [3] - - -def func6() -> Iterable[int]: - return [] - - -func1() - - -def aaa(): - func2() - - -func3() - - -# This should generate a diagnostic if reportUnusedCallResult is enabled. -func4() - -# This should generate a diagnostic if reportUnusedCallResult is enabled. -func5(3) - -# This should generate a diagnostic if reportUnusedCallResult is enabled. -func6() - -_, _ = func5(3), func6() - -_ = func5(3) - -_ = func5(func4()) - -for _ in func6(): - pass - - -async def get_string_async() -> str: - return "A string" - - -async def await_string() -> None: - # This should generate a diagnostic if reportUnusedCallResult is enabled. - await get_string_async() diff --git a/packages/vipeye-internal/src/tests/samples/unusedCoroutine1.py b/packages/vipeye-internal/src/tests/samples/unusedCoroutine1.py deleted file mode 100644 index b6d2c98a..00000000 --- a/packages/vipeye-internal/src/tests/samples/unusedCoroutine1.py +++ /dev/null @@ -1,23 +0,0 @@ -# This sample tests the reportUnusedCoroutine diagnostic rule. - - -async def func1(): - return 3 - - -async def func2() -> str: - return "5" - - -async def func3(): - await func1() - await func2() - - # This should generate an error - func1() - - # This should generate an error - func2() - - _ = func1() - _ = func2() diff --git a/packages/vipeye-internal/src/tests/samples/unusedExpression1.py b/packages/vipeye-internal/src/tests/samples/unusedExpression1.py deleted file mode 100644 index 8631c591..00000000 --- a/packages/vipeye-internal/src/tests/samples/unusedExpression1.py +++ /dev/null @@ -1,50 +0,0 @@ -# This sample tests the reportUnusedExpression diagnostic rule. - -t = 1 - - -# This should generate a diagnostic. --4 - -# This should generate a diagnostic. -4j - -# This should generate a diagnostic. -4j + 4 - -# This should generate a diagnostic. -False - -# This should generate a diagnostic. -t == 1 - -# This should generate a diagnostic. -t != 2 - -# This should generate a diagnostic. -t <= t - -# This should generate a diagnostic. -not t - -# This should generate a diagnostic. -None - -# This should generate a diagnostic. -t - -# This should generate a diagnostic. -(1, 2, 3) - -# This should generate a diagnostic. -{1: 2} - -# This should generate a diagnostic. -{1, 2, 3} - -# This should generate a diagnostic. -[1, 2, 3] - -[x for x in range(3)] -{x: x for x in range(3)} -{x for x in range(3)} diff --git a/packages/vipeye-internal/src/tests/samples/unusedImport1.py b/packages/vipeye-internal/src/tests/samples/unusedImport1.py deleted file mode 100644 index 15d35337..00000000 --- a/packages/vipeye-internal/src/tests/samples/unusedImport1.py +++ /dev/null @@ -1,5 +0,0 @@ -# This sample tests the reportUnusedImport diagnostic rule. -import sys as sys # Assumes export -import os as os2 # Should error -from sys import path as p # Should error -from os import environ as environ # Assumes export diff --git a/packages/vipeye-internal/src/tests/samples/unusedImport2.py b/packages/vipeye-internal/src/tests/samples/unusedImport2.py deleted file mode 100644 index 89b19406..00000000 --- a/packages/vipeye-internal/src/tests/samples/unusedImport2.py +++ /dev/null @@ -1,17 +0,0 @@ -# This sample tests the reportUnusedImport diagnostic rule -# for multipart imports. - -# This should result in an error if reportUnusedImport is enabled. -import package2.module1 - -# This should result in an error if reportUnusedImport is enabled. -import package2.module2 - -import package2.module3 - -import package2.module2 as dummy - - -def func1(): - print(package2.module3.a3) - print(dummy) diff --git a/packages/vipeye-internal/src/tests/samples/unusedVariable1.py b/packages/vipeye-internal/src/tests/samples/unusedVariable1.py deleted file mode 100644 index df6b1c0f..00000000 --- a/packages/vipeye-internal/src/tests/samples/unusedVariable1.py +++ /dev/null @@ -1,21 +0,0 @@ -# This sample tests the reportUnusedVariable diagnostic check. - - -def func1(a: int): - x = 4 - - # This should generate an error if reportUnusedVariable is enabled. - y = x - - _z = 4 - - _ = 2 - - __z__ = 5 - - if x + 1: - # This should generate an error if reportUnusedVariable is enabled. - z = 3 - else: - # This should generate an error if reportUnusedVariable is enabled. - z = 5 diff --git a/packages/vipeye-internal/src/tests/samples/viperComment1.py b/packages/vipeye-internal/src/tests/samples/viperComment1.py deleted file mode 100644 index f3e7289e..00000000 --- a/packages/vipeye-internal/src/tests/samples/viperComment1.py +++ /dev/null @@ -1,28 +0,0 @@ -# This sample tests error handling for pyright comments. - -# This should generate an error because "stricter" isn't a valid directive. -# pyright: basic , stricter - -# This should generate an error because it's missing a directive. -# pyright: - -# This should generate an error because the value is missing. -# viper: reportMissingTypeStubs - -# This should generate an error because the value is missing. -# viper: reportMissingTypeStubs= - -# This should generate two errors because the values are invalid. -# viper: reportMissingTypeStubs = blah , strictListInference = none - -# This should generate two errors because the rule is invalid. -# viper: reportBlahBlah = true - -# This should generate an error because it's not on its own line. -a = 1 # viper: reportGeneralTypeIssues=false - - -def func1(): - # This should generate an error because it's not on its own line. - # viper: reportGeneralTypeIssues=false - pass diff --git a/packages/vipeye-internal/src/tests/samples/viperIgnore1.py b/packages/vipeye-internal/src/tests/samples/viperIgnore1.py deleted file mode 100644 index d18f2363..00000000 --- a/packages/vipeye-internal/src/tests/samples/viperIgnore1.py +++ /dev/null @@ -1,15 +0,0 @@ -# This sample tests the # viper: ignore comment. - -import sys - - -def func1(self, x: int | None) -> str: - # This should suppress the error - x + "hi" # viper: ignore - test - - # This should not suppress the error because the rule doesn't match. - return 3 # viper: ignore [foo] - - -if sys.version_info < (3, 8): - x = 3 # viper: ignore diff --git a/packages/vipeye-internal/src/tests/samples/viperIgnore2.py b/packages/vipeye-internal/src/tests/samples/viperIgnore2.py deleted file mode 100644 index 6bc65aa8..00000000 --- a/packages/vipeye-internal/src/tests/samples/viperIgnore2.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests the use of a pyright ignore comment in conjunction -# with the reportUnnecessaryTypeIgnoreComment mechanism. - - -def func1(self, x: int | None) -> str: - # This should suppress the error - v1 = x + "hi" # viper: ignore - test - - # This is unnecessary - v2 = x + x # viper: ignore - - # This will not suppress the error - # These are both unnecessary - v3 = x + x # viper: ignore [foo, bar] - - # This will not suppress the error - v4 = x + x # viper: ignore [] - - # One of these is unnecessary - v5 = x + "hi" # test # viper: ignore [reportOperatorIssue, foo] - - return 3 # viper: ignore [reportReturnType] diff --git a/packages/vipeye-internal/src/tests/samples/with1.py b/packages/vipeye-internal/src/tests/samples/with1.py deleted file mode 100644 index 06db6ae6..00000000 --- a/packages/vipeye-internal/src/tests/samples/with1.py +++ /dev/null @@ -1,115 +0,0 @@ -# This sample tests various forms of the 'with' statement. - -from typing import Any, Generic, Optional, TypeVar, Self - -_T1 = TypeVar("_T1") - - -class Class1(object): - def __exit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -class Class2(object): - def __enter__(self): - return 1 - - def __exit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -class Class3(object): - def __enter__(self: _T1) -> _T1: - return self - - def __exit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -def requires_int(val: int): - pass - - -def requires_class3(val: Class3): - pass - - -def test1(): - a1 = Class1() - - # This should generate an error because Class1 - # does not implement an __enter__ - with a1 as foo: - pass - - a2 = Class2() - with a2 as foo: - requires_int(foo) - - a3 = Class3() - with a3 as foo: - # This should generate an error because foo - # should be of type Class3. - requires_int(foo) - - requires_class3(foo) - - with a2 as foo2, a3 as foo3: - requires_int(foo2) - requires_class3(foo3) - - -class Class4: - async def __aenter__(self: _T1) -> _T1: - return self - - async def __aexit__( - self, - t: Optional[type] = None, - exc: Optional[BaseException] = None, - tb: Optional[Any] = None, - ) -> bool: - return True - - -async def test2(): - a1 = Class4() - - # This should generate two errors because Class4 does not - # implement __enter__ or __exit__. - with a1 as foo: - pass - - async with a1 as foo: - pass - - -class Class5(Generic[_T1]): - async def __aenter__(self) -> Self: - return self - - async def __aexit__(self, *args: Any) -> None: - return None - - -class Class6(Class5[int]): ... - - -async def do(): - async with Class6() as f: - reveal_type(f, expected_text="Class6") diff --git a/packages/vipeye-internal/src/tests/samples/with2.py b/packages/vipeye-internal/src/tests/samples/with2.py deleted file mode 100644 index fe50054b..00000000 --- a/packages/vipeye-internal/src/tests/samples/with2.py +++ /dev/null @@ -1,78 +0,0 @@ -# This sample tests for the presence of an __exit__ -# or __aexit__ method. - - -from contextlib import AbstractContextManager -from typing import Any, Literal, TypeVar - -_T1 = TypeVar("_T1") - - -class Class2(object): - def __enter__(self): - return 1 - - -class Class3(object): - def __enter__(self: _T1) -> _T1: - return self - - def __exit__( - self, - t: type | None = None, - exc: BaseException | None = None, - tb: Any | None = None, - ) -> bool: - return True - - -def requires_int(val: int): - pass - - -def requires_class3(val: Class3): - pass - - -def test1(): - a2 = Class2() - a3 = Class3() - - # This should generate an error because - # the __exit__ method is missing. - with a2 as foo: - requires_int(foo) - - # This should generate an error because - # the __exit__ method is missing. - with a2 as foo2, a3 as foo3: - requires_int(foo2) - requires_class3(foo3) - - -class Class4: - async def __aenter__(self: _T1) -> _T1: - return self - - -async def test2(): - a1 = Class4() - - # This should generate an error because __aexit__ - # needs to be used with async with. - async with a1 as foo: - pass - - -class Class5(AbstractContextManager[Any]): - def __exit__(self, exc_type: Any, exc_value: Any, tb: Any) -> Literal[True]: - return True - - -def test3(val: str | None): - val = None - with Class5(): - val = "" - raise Exception - - reveal_type(val, expected_text="Literal[''] | None") diff --git a/packages/vipeye-internal/src/tests/samples/with3.py b/packages/vipeye-internal/src/tests/samples/with3.py deleted file mode 100644 index 8034b1f6..00000000 --- a/packages/vipeye-internal/src/tests/samples/with3.py +++ /dev/null @@ -1,81 +0,0 @@ -# This sample verifies the proper type analysis of context managers -# that suppress exceptions, as indicated by a return type of "bool" -# for the __exit__ or __aexit__ method. - -from contextlib import suppress, AsyncExitStack -from typing import Never - - -def test1() -> None: - class A: - b: str - - x = b"" - a = A() - with memoryview(x), suppress(AttributeError): - if a.b: - raise RuntimeError() - return - - # This should generate an error. - c = "hi" + 3 - - with memoryview(x): - raise RuntimeError() - - # This should not generate an error because - # the code is unreachable. - return 3 - - -def test2() -> None: - some_dict = dict() - - with suppress(KeyError): - print(some_dict["missing_key"]) - - # This should generate an error because the - # code is reachable. - return 1 - - -def test3(cm: suppress) -> None: - some_dict = dict() - - with cm: - print(some_dict["missing_key"]) - - # This should generate an error because the - # code is reachable. - return 1 - - -class CMFactory: - def get_cm(self) -> suppress: - return suppress() - - -def test4() -> None: - some_dict = dict() - - with CMFactory().get_cm(): - print(some_dict["missing_key"]) - - # This should generate an error because the - # code is reachable. - return 1 - - -def no_return() -> Never: - raise Exception() - - -def test6(): - val = None - with suppress(): - val = 1 - no_return() - val = 2 - - assert val is not None - reveal_type(val, expected_text="Literal[1, 2]") diff --git a/packages/vipeye-internal/src/tests/samples/with4.py b/packages/vipeye-internal/src/tests/samples/with4.py deleted file mode 100644 index 4eaece7f..00000000 --- a/packages/vipeye-internal/src/tests/samples/with4.py +++ /dev/null @@ -1,24 +0,0 @@ -# This sample tests that parentheses are allowed in with statements -# if using Python 3.9 and later. - -from tempfile import TemporaryFile - -# This should generate an error -with (TemporaryFile() as a, TemporaryFile() as b): - pass - -# This should generate an error -with (TemporaryFile() as c, ): - pass - -# This should generate an error -with (TemporaryFile() as d): - pass - -with (TemporaryFile()): - pass - -# This should generate an error -with (TemporaryFile(), TemporaryFile()): - pass - diff --git a/packages/vipeye-internal/src/tests/samples/with5.py b/packages/vipeye-internal/src/tests/samples/with5.py deleted file mode 100644 index b1a18826..00000000 --- a/packages/vipeye-internal/src/tests/samples/with5.py +++ /dev/null @@ -1,31 +0,0 @@ -# This sample tests the case of a context manager within a try/except block. - -from typing import ContextManager - - -def create_context() -> ContextManager[str]: ... - - -def possible_exception() -> None: ... - - -def func1(): - x: str | None = None - ctx: str | None = None - try: - with create_context() as ctx: - x = "0" - possible_exception() - except Exception: - reveal_type(x, expected_text="Literal['0'] | None") - reveal_type(ctx, expected_text="str | None") - - -def func2(): - ctx: str | None = None - try: - with create_context() as ctx: - possible_exception() - return - except Exception: - reveal_type(ctx, expected_text="str | None") diff --git a/packages/vipeye-internal/src/tests/samples/with6.py b/packages/vipeye-internal/src/tests/samples/with6.py deleted file mode 100644 index e7bc5c96..00000000 --- a/packages/vipeye-internal/src/tests/samples/with6.py +++ /dev/null @@ -1,22 +0,0 @@ -# This sample tests that classes whose metaclass implements a context -# manager work with the "with" statement. - -from types import TracebackType - - -class ClassA(type): - def __enter__(cls) -> "ClassA": - print("Enter A") - return cls - - def __exit__( - cls, exc_typ: type[Exception], exc_val: Exception, exc_tbc: TracebackType - ) -> None: - print("Exit A") - - -class ClassB(metaclass=ClassA): ... - - -with ClassB as b: - ... diff --git a/packages/vipeye-internal/src/tests/samples/with7.py b/packages/vipeye-internal/src/tests/samples/with7.py deleted file mode 100644 index 5cfce84b..00000000 --- a/packages/vipeye-internal/src/tests/samples/with7.py +++ /dev/null @@ -1,38 +0,0 @@ -# Regression test for https://github.com/microsoft/pyright/issues/11483 -# Generic ContextManager[T] should treat __exit__ return type like typing.ContextManager[bool]. - -from typing import Generic, Self, TypeVar, reveal_type - -T = TypeVar("T", bound="bool|None") - - -class ContextManager(Generic[T]): - def __enter__(self) -> Self: ... - - def __exit__(self, exc_type, exc_val, exc_tb) -> T: ... - - -def test_generic_bool_context_manager() -> None: - foo = "str" - with ContextManager[bool]() as ctx: - reveal_type(ctx.__exit__(None, None, None), expected_text="bool") - foo = 1 - reveal_type(foo, expected_text="Literal['str', 1]") - - -TEnter = TypeVar("TEnter") -TExit = TypeVar("TExit", bound="bool|None") - - -class SplitContextManager(Generic[TEnter, TExit]): - def __enter__(self) -> TEnter: ... - - def __exit__(self, exc_type, exc_val, exc_tb) -> TExit: ... - - -def test_multi_typevar_context_manager() -> None: - bar = "str" - with SplitContextManager[int, bool]() as ctx: - reveal_type(ctx, expected_text="int") - bar = 1 - reveal_type(bar, expected_text="Literal['str', 1]")