mypy-dev 1.9.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mypy/__init__.py +1 -0
- mypy/__main__.py +37 -0
- mypy/api.py +94 -0
- mypy/applytype.py +156 -0
- mypy/argmap.py +268 -0
- mypy/binder.py +538 -0
- mypy/bogus_type.py +27 -0
- mypy/build.py +3562 -0
- mypy/checker.py +8372 -0
- mypy/checkexpr.py +6615 -0
- mypy/checkmember.py +1356 -0
- mypy/checkpattern.py +801 -0
- mypy/checkstrformat.py +1109 -0
- mypy/config_parser.py +670 -0
- mypy/constant_fold.py +187 -0
- mypy/constraints.py +1624 -0
- mypy/copytype.py +133 -0
- mypy/defaults.py +46 -0
- mypy/dmypy/__init__.py +0 -0
- mypy/dmypy/__main__.py +6 -0
- mypy/dmypy/client.py +749 -0
- mypy/dmypy_os.py +42 -0
- mypy/dmypy_server.py +1107 -0
- mypy/dmypy_util.py +117 -0
- mypy/erasetype.py +278 -0
- mypy/errorcodes.py +285 -0
- mypy/errors.py +1280 -0
- mypy/evalexpr.py +205 -0
- mypy/expandtype.py +510 -0
- mypy/exprtotype.py +206 -0
- mypy/fastparse.py +2147 -0
- mypy/find_sources.py +243 -0
- mypy/fixup.py +426 -0
- mypy/freetree.py +23 -0
- mypy/fscache.py +309 -0
- mypy/fswatcher.py +106 -0
- mypy/gclogger.py +47 -0
- mypy/git.py +34 -0
- mypy/graph_utils.py +112 -0
- mypy/indirection.py +121 -0
- mypy/infer.py +75 -0
- mypy/inspections.py +627 -0
- mypy/ipc.py +310 -0
- mypy/join.py +866 -0
- mypy/literals.py +306 -0
- mypy/lookup.py +61 -0
- mypy/main.py +1574 -0
- mypy/maptype.py +106 -0
- mypy/meet.py +1140 -0
- mypy/memprofile.py +121 -0
- mypy/message_registry.py +326 -0
- mypy/messages.py +3171 -0
- mypy/metastore.py +225 -0
- mypy/mixedtraverser.py +112 -0
- mypy/modulefinder.py +875 -0
- mypy/moduleinspect.py +184 -0
- mypy/mro.py +62 -0
- mypy/nodes.py +4112 -0
- mypy/operators.py +126 -0
- mypy/options.py +556 -0
- mypy/parse.py +30 -0
- mypy/partially_defined.py +675 -0
- mypy/patterns.py +150 -0
- mypy/plugin.py +901 -0
- mypy/plugins/__init__.py +0 -0
- mypy/plugins/attrs.py +1152 -0
- mypy/plugins/common.py +440 -0
- mypy/plugins/ctypes.py +245 -0
- mypy/plugins/dataclasses.py +1101 -0
- mypy/plugins/default.py +518 -0
- mypy/plugins/enums.py +259 -0
- mypy/plugins/functools.py +104 -0
- mypy/plugins/proper_plugin.py +175 -0
- mypy/plugins/singledispatch.py +224 -0
- mypy/py.typed +1 -0
- mypy/pyinfo.py +78 -0
- mypy/reachability.py +362 -0
- mypy/refinfo.py +92 -0
- mypy/renaming.py +568 -0
- mypy/report.py +924 -0
- mypy/scope.py +125 -0
- mypy/semanal.py +7023 -0
- mypy/semanal_classprop.py +187 -0
- mypy/semanal_enum.py +253 -0
- mypy/semanal_infer.py +128 -0
- mypy/semanal_main.py +511 -0
- mypy/semanal_namedtuple.py +670 -0
- mypy/semanal_newtype.py +273 -0
- mypy/semanal_pass1.py +156 -0
- mypy/semanal_shared.py +490 -0
- mypy/semanal_typeargs.py +265 -0
- mypy/semanal_typeddict.py +575 -0
- mypy/server/__init__.py +0 -0
- mypy/server/astdiff.py +518 -0
- mypy/server/astmerge.py +562 -0
- mypy/server/aststrip.py +281 -0
- mypy/server/deps.py +1137 -0
- mypy/server/mergecheck.py +83 -0
- mypy/server/objgraph.py +101 -0
- mypy/server/subexpr.py +198 -0
- mypy/server/target.py +11 -0
- mypy/server/trigger.py +26 -0
- mypy/server/update.py +1339 -0
- mypy/sharedparse.py +112 -0
- mypy/solve.py +562 -0
- mypy/split_namespace.py +35 -0
- mypy/state.py +28 -0
- mypy/stats.py +489 -0
- mypy/strconv.py +641 -0
- mypy/stubdoc.py +491 -0
- mypy/stubgen.py +1873 -0
- mypy/stubgenc.py +993 -0
- mypy/stubinfo.py +173 -0
- mypy/stubtest.py +2079 -0
- mypy/stubutil.py +807 -0
- mypy/subtypes.py +1967 -0
- mypy/suggestions.py +1046 -0
- mypy/test/__init__.py +0 -0
- mypy/test/config.py +28 -0
- mypy/test/data.py +823 -0
- mypy/test/helpers.py +476 -0
- mypy/test/meta/__init__.py +0 -0
- mypy/test/meta/_pytest.py +72 -0
- mypy/test/meta/test_diff_helper.py +47 -0
- mypy/test/meta/test_parse_data.py +73 -0
- mypy/test/meta/test_update_data.py +135 -0
- mypy/test/test_find_sources.py +376 -0
- mypy/test/test_ref_info.py +45 -0
- mypy/test/testapi.py +45 -0
- mypy/test/testargs.py +77 -0
- mypy/test/testcheck.py +322 -0
- mypy/test/testcmdline.py +152 -0
- mypy/test/testconstraints.py +134 -0
- mypy/test/testdaemon.py +132 -0
- mypy/test/testdeps.py +77 -0
- mypy/test/testdiff.py +67 -0
- mypy/test/testerrorstream.py +46 -0
- mypy/test/testfinegrained.py +438 -0
- mypy/test/testfinegrainedcache.py +18 -0
- mypy/test/testformatter.py +85 -0
- mypy/test/testfscache.py +101 -0
- mypy/test/testgraph.py +83 -0
- mypy/test/testinfer.py +373 -0
- mypy/test/testipc.py +119 -0
- mypy/test/testmerge.py +238 -0
- mypy/test/testmodulefinder.py +278 -0
- mypy/test/testmypyc.py +14 -0
- mypy/test/testparse.py +107 -0
- mypy/test/testpep561.py +211 -0
- mypy/test/testpythoneval.py +117 -0
- mypy/test/testreports.py +55 -0
- mypy/test/testsemanal.py +209 -0
- mypy/test/testsolve.py +285 -0
- mypy/test/teststubgen.py +1412 -0
- mypy/test/teststubinfo.py +12 -0
- mypy/test/teststubtest.py +2492 -0
- mypy/test/testsubtypes.py +303 -0
- mypy/test/testtransform.py +64 -0
- mypy/test/testtypegen.py +83 -0
- mypy/test/testtypes.py +1551 -0
- mypy/test/testutil.py +111 -0
- mypy/test/typefixture.py +415 -0
- mypy/test/update_data.py +87 -0
- mypy/test/visitors.py +63 -0
- mypy/traverser.py +961 -0
- mypy/treetransform.py +800 -0
- mypy/tvar_scope.py +147 -0
- mypy/type_visitor.py +564 -0
- mypy/typeanal.py +2510 -0
- mypy/typeops.py +1082 -0
- mypy/types.py +3686 -0
- mypy/types_utils.py +166 -0
- mypy/typeshed/LICENSE +237 -0
- mypy/typeshed/stdlib/VERSIONS +308 -0
- mypy/typeshed/stdlib/__future__.pyi +36 -0
- mypy/typeshed/stdlib/__main__.pyi +3 -0
- mypy/typeshed/stdlib/_ast.pyi +587 -0
- mypy/typeshed/stdlib/_bisect.pyi +84 -0
- mypy/typeshed/stdlib/_bootlocale.pyi +1 -0
- mypy/typeshed/stdlib/_codecs.pyi +133 -0
- mypy/typeshed/stdlib/_collections_abc.pyi +94 -0
- mypy/typeshed/stdlib/_compat_pickle.pyi +8 -0
- mypy/typeshed/stdlib/_compression.pyi +25 -0
- mypy/typeshed/stdlib/_csv.pyi +90 -0
- mypy/typeshed/stdlib/_ctypes.pyi +205 -0
- mypy/typeshed/stdlib/_curses.pyi +557 -0
- mypy/typeshed/stdlib/_decimal.pyi +281 -0
- mypy/typeshed/stdlib/_dummy_thread.pyi +27 -0
- mypy/typeshed/stdlib/_dummy_threading.pyi +164 -0
- mypy/typeshed/stdlib/_heapq.pyi +11 -0
- mypy/typeshed/stdlib/_imp.pyi +28 -0
- mypy/typeshed/stdlib/_json.pyi +49 -0
- mypy/typeshed/stdlib/_locale.pyi +100 -0
- mypy/typeshed/stdlib/_markupbase.pyi +16 -0
- mypy/typeshed/stdlib/_msi.pyi +91 -0
- mypy/typeshed/stdlib/_operator.pyi +147 -0
- mypy/typeshed/stdlib/_osx_support.pyi +34 -0
- mypy/typeshed/stdlib/_posixsubprocess.pyi +32 -0
- mypy/typeshed/stdlib/_py_abc.pyi +14 -0
- mypy/typeshed/stdlib/_pydecimal.pyi +43 -0
- mypy/typeshed/stdlib/_random.pyi +12 -0
- mypy/typeshed/stdlib/_sitebuiltins.pyi +16 -0
- mypy/typeshed/stdlib/_socket.pyi +802 -0
- mypy/typeshed/stdlib/_stat.pyi +103 -0
- mypy/typeshed/stdlib/_thread.pyi +52 -0
- mypy/typeshed/stdlib/_threading_local.pyi +17 -0
- mypy/typeshed/stdlib/_tkinter.pyi +120 -0
- mypy/typeshed/stdlib/_tracemalloc.pyi +17 -0
- mypy/typeshed/stdlib/_typeshed/__init__.pyi +347 -0
- mypy/typeshed/stdlib/_typeshed/dbapi.pyi +37 -0
- mypy/typeshed/stdlib/_typeshed/wsgi.pyi +44 -0
- mypy/typeshed/stdlib/_typeshed/xml.pyi +9 -0
- mypy/typeshed/stdlib/_warnings.pyi +55 -0
- mypy/typeshed/stdlib/_weakref.pyi +41 -0
- mypy/typeshed/stdlib/_weakrefset.pyi +51 -0
- mypy/typeshed/stdlib/_winapi.pyi +251 -0
- mypy/typeshed/stdlib/abc.pyi +49 -0
- mypy/typeshed/stdlib/aifc.pyi +91 -0
- mypy/typeshed/stdlib/antigravity.pyi +3 -0
- mypy/typeshed/stdlib/argparse.pyi +571 -0
- mypy/typeshed/stdlib/array.pyi +92 -0
- mypy/typeshed/stdlib/ast.pyi +277 -0
- mypy/typeshed/stdlib/asynchat.pyi +21 -0
- mypy/typeshed/stdlib/asyncio/__init__.pyi +41 -0
- mypy/typeshed/stdlib/asyncio/base_events.pyi +440 -0
- mypy/typeshed/stdlib/asyncio/base_futures.pyi +19 -0
- mypy/typeshed/stdlib/asyncio/base_subprocess.pyi +63 -0
- mypy/typeshed/stdlib/asyncio/base_tasks.pyi +9 -0
- mypy/typeshed/stdlib/asyncio/constants.pyi +20 -0
- mypy/typeshed/stdlib/asyncio/coroutines.pyi +26 -0
- mypy/typeshed/stdlib/asyncio/events.pyi +574 -0
- mypy/typeshed/stdlib/asyncio/exceptions.pyi +43 -0
- mypy/typeshed/stdlib/asyncio/format_helpers.pyi +20 -0
- mypy/typeshed/stdlib/asyncio/futures.pyi +57 -0
- mypy/typeshed/stdlib/asyncio/locks.pyi +121 -0
- mypy/typeshed/stdlib/asyncio/log.pyi +3 -0
- mypy/typeshed/stdlib/asyncio/mixins.pyi +9 -0
- mypy/typeshed/stdlib/asyncio/proactor_events.pyi +64 -0
- mypy/typeshed/stdlib/asyncio/protocols.pyi +34 -0
- mypy/typeshed/stdlib/asyncio/queues.pyi +47 -0
- mypy/typeshed/stdlib/asyncio/runners.pyi +32 -0
- mypy/typeshed/stdlib/asyncio/selector_events.pyi +8 -0
- mypy/typeshed/stdlib/asyncio/sslproto.pyi +163 -0
- mypy/typeshed/stdlib/asyncio/staggered.pyi +10 -0
- mypy/typeshed/stdlib/asyncio/streams.pyi +148 -0
- mypy/typeshed/stdlib/asyncio/subprocess.pyi +229 -0
- mypy/typeshed/stdlib/asyncio/taskgroups.pyi +25 -0
- mypy/typeshed/stdlib/asyncio/tasks.pyi +477 -0
- mypy/typeshed/stdlib/asyncio/threads.pyi +9 -0
- mypy/typeshed/stdlib/asyncio/timeouts.pyi +19 -0
- mypy/typeshed/stdlib/asyncio/transports.pyi +47 -0
- mypy/typeshed/stdlib/asyncio/trsock.pyi +98 -0
- mypy/typeshed/stdlib/asyncio/unix_events.pyi +173 -0
- mypy/typeshed/stdlib/asyncio/windows_events.pyi +83 -0
- mypy/typeshed/stdlib/asyncio/windows_utils.pyi +49 -0
- mypy/typeshed/stdlib/asyncore.pyi +90 -0
- mypy/typeshed/stdlib/atexit.pyi +12 -0
- mypy/typeshed/stdlib/audioop.pyi +42 -0
- mypy/typeshed/stdlib/base64.pyi +59 -0
- mypy/typeshed/stdlib/bdb.pyi +102 -0
- mypy/typeshed/stdlib/binascii.pyi +36 -0
- mypy/typeshed/stdlib/binhex.pyi +45 -0
- mypy/typeshed/stdlib/bisect.pyi +4 -0
- mypy/typeshed/stdlib/builtins.pyi +1937 -0
- mypy/typeshed/stdlib/bz2.pyi +146 -0
- mypy/typeshed/stdlib/cProfile.pyi +35 -0
- mypy/typeshed/stdlib/calendar.pyi +206 -0
- mypy/typeshed/stdlib/cgi.pyi +118 -0
- mypy/typeshed/stdlib/cgitb.pyi +32 -0
- mypy/typeshed/stdlib/chunk.pyi +20 -0
- mypy/typeshed/stdlib/cmath.pyi +36 -0
- mypy/typeshed/stdlib/cmd.pyi +45 -0
- mypy/typeshed/stdlib/code.pyi +33 -0
- mypy/typeshed/stdlib/codecs.pyi +285 -0
- mypy/typeshed/stdlib/codeop.pyi +13 -0
- mypy/typeshed/stdlib/collections/__init__.pyi +477 -0
- mypy/typeshed/stdlib/collections/abc.pyi +2 -0
- mypy/typeshed/stdlib/colorsys.pyi +13 -0
- mypy/typeshed/stdlib/compileall.pyi +111 -0
- mypy/typeshed/stdlib/concurrent/__init__.pyi +0 -0
- mypy/typeshed/stdlib/concurrent/futures/__init__.pyi +32 -0
- mypy/typeshed/stdlib/concurrent/futures/_base.pyi +120 -0
- mypy/typeshed/stdlib/concurrent/futures/process.pyi +233 -0
- mypy/typeshed/stdlib/concurrent/futures/thread.pyi +80 -0
- mypy/typeshed/stdlib/configparser.pyi +313 -0
- mypy/typeshed/stdlib/contextlib.pyi +207 -0
- mypy/typeshed/stdlib/contextvars.pyi +63 -0
- mypy/typeshed/stdlib/copy.pyi +16 -0
- mypy/typeshed/stdlib/copyreg.pyi +21 -0
- mypy/typeshed/stdlib/crypt.pyi +12 -0
- mypy/typeshed/stdlib/csv.pyi +147 -0
- mypy/typeshed/stdlib/ctypes/__init__.pyi +187 -0
- mypy/typeshed/stdlib/ctypes/_endian.pyi +19 -0
- mypy/typeshed/stdlib/ctypes/util.pyi +6 -0
- mypy/typeshed/stdlib/ctypes/wintypes.pyi +298 -0
- mypy/typeshed/stdlib/curses/__init__.pyi +21 -0
- mypy/typeshed/stdlib/curses/ascii.pyi +63 -0
- mypy/typeshed/stdlib/curses/has_key.pyi +4 -0
- mypy/typeshed/stdlib/curses/panel.pyi +25 -0
- mypy/typeshed/stdlib/curses/textpad.pyi +13 -0
- mypy/typeshed/stdlib/dataclasses.pyi +313 -0
- mypy/typeshed/stdlib/datetime.pyi +295 -0
- mypy/typeshed/stdlib/dbm/__init__.pyi +95 -0
- mypy/typeshed/stdlib/dbm/dumb.pyi +31 -0
- mypy/typeshed/stdlib/dbm/gnu.pyi +40 -0
- mypy/typeshed/stdlib/dbm/ndbm.pyi +36 -0
- mypy/typeshed/stdlib/decimal.pyi +2 -0
- mypy/typeshed/stdlib/difflib.pyi +140 -0
- mypy/typeshed/stdlib/dis.pyi +144 -0
- mypy/typeshed/stdlib/distutils/__init__.pyi +5 -0
- mypy/typeshed/stdlib/distutils/archive_util.pyi +20 -0
- mypy/typeshed/stdlib/distutils/bcppcompiler.pyi +3 -0
- mypy/typeshed/stdlib/distutils/ccompiler.pyi +152 -0
- mypy/typeshed/stdlib/distutils/cmd.pyi +66 -0
- mypy/typeshed/stdlib/distutils/command/__init__.pyi +0 -0
- mypy/typeshed/stdlib/distutils/command/bdist.pyi +25 -0
- mypy/typeshed/stdlib/distutils/command/bdist_dumb.pyi +21 -0
- mypy/typeshed/stdlib/distutils/command/bdist_msi.pyi +45 -0
- mypy/typeshed/stdlib/distutils/command/bdist_packager.pyi +0 -0
- mypy/typeshed/stdlib/distutils/command/bdist_rpm.pyi +52 -0
- mypy/typeshed/stdlib/distutils/command/bdist_wininst.pyi +16 -0
- mypy/typeshed/stdlib/distutils/command/build.pyi +31 -0
- mypy/typeshed/stdlib/distutils/command/build_clib.pyi +27 -0
- mypy/typeshed/stdlib/distutils/command/build_ext.pyi +50 -0
- mypy/typeshed/stdlib/distutils/command/build_py.pyi +44 -0
- mypy/typeshed/stdlib/distutils/command/build_scripts.pyi +24 -0
- mypy/typeshed/stdlib/distutils/command/check.pyi +39 -0
- mypy/typeshed/stdlib/distutils/command/clean.pyi +17 -0
- mypy/typeshed/stdlib/distutils/command/config.pyi +83 -0
- mypy/typeshed/stdlib/distutils/command/install.pyi +63 -0
- mypy/typeshed/stdlib/distutils/command/install_data.pyi +19 -0
- mypy/typeshed/stdlib/distutils/command/install_egg_info.pyi +18 -0
- mypy/typeshed/stdlib/distutils/command/install_headers.pyi +16 -0
- mypy/typeshed/stdlib/distutils/command/install_lib.pyi +25 -0
- mypy/typeshed/stdlib/distutils/command/install_scripts.pyi +18 -0
- mypy/typeshed/stdlib/distutils/command/register.pyi +18 -0
- mypy/typeshed/stdlib/distutils/command/sdist.pyi +42 -0
- mypy/typeshed/stdlib/distutils/command/upload.pyi +17 -0
- mypy/typeshed/stdlib/distutils/config.pyi +17 -0
- mypy/typeshed/stdlib/distutils/core.pyi +57 -0
- mypy/typeshed/stdlib/distutils/cygwinccompiler.pyi +20 -0
- mypy/typeshed/stdlib/distutils/debug.pyi +1 -0
- mypy/typeshed/stdlib/distutils/dep_util.pyi +3 -0
- mypy/typeshed/stdlib/distutils/dir_util.pyi +13 -0
- mypy/typeshed/stdlib/distutils/dist.pyi +146 -0
- mypy/typeshed/stdlib/distutils/errors.pyi +19 -0
- mypy/typeshed/stdlib/distutils/extension.pyi +36 -0
- mypy/typeshed/stdlib/distutils/fancy_getopt.pyi +34 -0
- mypy/typeshed/stdlib/distutils/file_util.pyi +14 -0
- mypy/typeshed/stdlib/distutils/filelist.pyi +50 -0
- mypy/typeshed/stdlib/distutils/log.pyi +25 -0
- mypy/typeshed/stdlib/distutils/msvccompiler.pyi +3 -0
- mypy/typeshed/stdlib/distutils/spawn.pyi +2 -0
- mypy/typeshed/stdlib/distutils/sysconfig.pyi +22 -0
- mypy/typeshed/stdlib/distutils/text_file.pyi +21 -0
- mypy/typeshed/stdlib/distutils/unixccompiler.pyi +3 -0
- mypy/typeshed/stdlib/distutils/util.pyi +46 -0
- mypy/typeshed/stdlib/distutils/version.pyi +36 -0
- mypy/typeshed/stdlib/doctest.pyi +248 -0
- mypy/typeshed/stdlib/dummy_threading.pyi +2 -0
- mypy/typeshed/stdlib/email/__init__.pyi +29 -0
- mypy/typeshed/stdlib/email/_header_value_parser.pyi +392 -0
- mypy/typeshed/stdlib/email/_policybase.pyi +51 -0
- mypy/typeshed/stdlib/email/base64mime.pyi +13 -0
- mypy/typeshed/stdlib/email/charset.pyi +34 -0
- mypy/typeshed/stdlib/email/contentmanager.pyi +11 -0
- mypy/typeshed/stdlib/email/encoders.pyi +8 -0
- mypy/typeshed/stdlib/email/errors.pyi +39 -0
- mypy/typeshed/stdlib/email/feedparser.pyi +23 -0
- mypy/typeshed/stdlib/email/generator.pyi +40 -0
- mypy/typeshed/stdlib/email/header.pyi +31 -0
- mypy/typeshed/stdlib/email/headerregistry.pyi +178 -0
- mypy/typeshed/stdlib/email/iterators.pyi +12 -0
- mypy/typeshed/stdlib/email/message.pyi +161 -0
- mypy/typeshed/stdlib/email/mime/__init__.pyi +0 -0
- mypy/typeshed/stdlib/email/mime/application.pyi +17 -0
- mypy/typeshed/stdlib/email/mime/audio.pyi +17 -0
- mypy/typeshed/stdlib/email/mime/base.pyi +8 -0
- mypy/typeshed/stdlib/email/mime/image.pyi +17 -0
- mypy/typeshed/stdlib/email/mime/message.pyi +8 -0
- mypy/typeshed/stdlib/email/mime/multipart.pyi +18 -0
- mypy/typeshed/stdlib/email/mime/nonmultipart.pyi +5 -0
- mypy/typeshed/stdlib/email/mime/text.pyi +9 -0
- mypy/typeshed/stdlib/email/parser.pyi +26 -0
- mypy/typeshed/stdlib/email/policy.pyi +38 -0
- mypy/typeshed/stdlib/email/quoprimime.pyi +28 -0
- mypy/typeshed/stdlib/email/utils.pyi +66 -0
- mypy/typeshed/stdlib/encodings/__init__.pyi +10 -0
- mypy/typeshed/stdlib/encodings/utf_8.pyi +21 -0
- mypy/typeshed/stdlib/encodings/utf_8_sig.pyi +22 -0
- mypy/typeshed/stdlib/ensurepip/__init__.pyi +12 -0
- mypy/typeshed/stdlib/enum.pyi +317 -0
- mypy/typeshed/stdlib/errno.pyi +222 -0
- mypy/typeshed/stdlib/faulthandler.pyi +13 -0
- mypy/typeshed/stdlib/fcntl.pyi +127 -0
- mypy/typeshed/stdlib/filecmp.pyi +57 -0
- mypy/typeshed/stdlib/fileinput.pyi +213 -0
- mypy/typeshed/stdlib/fnmatch.pyi +9 -0
- mypy/typeshed/stdlib/formatter.pyi +88 -0
- mypy/typeshed/stdlib/fractions.pyi +150 -0
- mypy/typeshed/stdlib/ftplib.pyi +178 -0
- mypy/typeshed/stdlib/functools.pyi +200 -0
- mypy/typeshed/stdlib/gc.pyi +37 -0
- mypy/typeshed/stdlib/genericpath.pyi +52 -0
- mypy/typeshed/stdlib/getopt.pyi +11 -0
- mypy/typeshed/stdlib/getpass.pyi +8 -0
- mypy/typeshed/stdlib/gettext.pyi +169 -0
- mypy/typeshed/stdlib/glob.pyi +42 -0
- mypy/typeshed/stdlib/graphlib.pyi +28 -0
- mypy/typeshed/stdlib/grp.pyi +21 -0
- mypy/typeshed/stdlib/gzip.pyi +160 -0
- mypy/typeshed/stdlib/hashlib.pyi +165 -0
- mypy/typeshed/stdlib/heapq.pyi +17 -0
- mypy/typeshed/stdlib/hmac.pyi +38 -0
- mypy/typeshed/stdlib/html/__init__.pyi +6 -0
- mypy/typeshed/stdlib/html/entities.pyi +6 -0
- mypy/typeshed/stdlib/html/parser.pyi +34 -0
- mypy/typeshed/stdlib/http/__init__.pyi +105 -0
- mypy/typeshed/stdlib/http/client.pyi +259 -0
- mypy/typeshed/stdlib/http/cookiejar.pyi +159 -0
- mypy/typeshed/stdlib/http/cookies.pyi +60 -0
- mypy/typeshed/stdlib/http/server.pyi +83 -0
- mypy/typeshed/stdlib/imaplib.pyi +168 -0
- mypy/typeshed/stdlib/imghdr.pyi +17 -0
- mypy/typeshed/stdlib/imp.pyi +62 -0
- mypy/typeshed/stdlib/importlib/__init__.pyi +24 -0
- mypy/typeshed/stdlib/importlib/_abc.pyi +15 -0
- mypy/typeshed/stdlib/importlib/abc.pyi +172 -0
- mypy/typeshed/stdlib/importlib/machinery.pyi +179 -0
- mypy/typeshed/stdlib/importlib/metadata/__init__.pyi +276 -0
- mypy/typeshed/stdlib/importlib/metadata/_meta.pyi +40 -0
- mypy/typeshed/stdlib/importlib/readers.pyi +68 -0
- mypy/typeshed/stdlib/importlib/resources/__init__.pyi +46 -0
- mypy/typeshed/stdlib/importlib/resources/abc.pyi +12 -0
- mypy/typeshed/stdlib/importlib/resources/readers.pyi +14 -0
- mypy/typeshed/stdlib/importlib/resources/simple.pyi +49 -0
- mypy/typeshed/stdlib/importlib/simple.pyi +11 -0
- mypy/typeshed/stdlib/importlib/util.pyi +43 -0
- mypy/typeshed/stdlib/inspect.pyi +631 -0
- mypy/typeshed/stdlib/io.pyi +204 -0
- mypy/typeshed/stdlib/ipaddress.pyi +208 -0
- mypy/typeshed/stdlib/itertools.pyi +293 -0
- mypy/typeshed/stdlib/json/__init__.pyi +61 -0
- mypy/typeshed/stdlib/json/decoder.pyi +32 -0
- mypy/typeshed/stdlib/json/encoder.pyi +38 -0
- mypy/typeshed/stdlib/json/tool.pyi +1 -0
- mypy/typeshed/stdlib/keyword.pyi +21 -0
- mypy/typeshed/stdlib/lib2to3/__init__.pyi +0 -0
- mypy/typeshed/stdlib/lib2to3/btm_matcher.pyi +28 -0
- mypy/typeshed/stdlib/lib2to3/fixer_base.pyi +42 -0
- mypy/typeshed/stdlib/lib2to3/fixes/__init__.pyi +0 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_apply.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_asserts.pyi +10 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_basestring.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_buffer.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_dict.pyi +16 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_except.pyi +14 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_exec.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_execfile.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi +13 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_filter.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_funcattrs.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_future.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_getcwdu.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_has_key.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_idioms.pyi +15 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_import.pyi +16 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_imports.pyi +21 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_imports2.pyi +6 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_input.pyi +11 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_intern.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_isinstance.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools_imports.pyi +7 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_long.pyi +7 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_map.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_metaclass.pyi +17 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_methodattrs.pyi +10 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_ne.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_next.pyi +19 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_nonzero.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_numliterals.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_operator.pyi +12 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_paren.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_print.pyi +12 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_raise.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_raw_input.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_reduce.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_reload.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_renames.pyi +17 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_repr.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_set_literal.pyi +7 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_standarderror.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_sys_exc.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_throw.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_tuple_params.pyi +17 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_types.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_unicode.pyi +12 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_urllib.pyi +15 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_ws_comma.pyi +12 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_xrange.pyi +20 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_xreadlines.pyi +8 -0
- mypy/typeshed/stdlib/lib2to3/fixes/fix_zip.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/main.pyi +42 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/__init__.pyi +9 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/driver.pyi +27 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/grammar.pyi +24 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/literals.pyi +7 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/parse.pyi +30 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/pgen.pyi +50 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/token.pyi +67 -0
- mypy/typeshed/stdlib/lib2to3/pgen2/tokenize.pyi +96 -0
- mypy/typeshed/stdlib/lib2to3/pygram.pyi +114 -0
- mypy/typeshed/stdlib/lib2to3/pytree.pyi +117 -0
- mypy/typeshed/stdlib/lib2to3/refactor.pyi +82 -0
- mypy/typeshed/stdlib/linecache.pyi +23 -0
- mypy/typeshed/stdlib/locale.pyi +152 -0
- mypy/typeshed/stdlib/logging/__init__.pyi +655 -0
- mypy/typeshed/stdlib/logging/config.pyi +134 -0
- mypy/typeshed/stdlib/logging/handlers.pyi +275 -0
- mypy/typeshed/stdlib/lzma.pyi +197 -0
- mypy/typeshed/stdlib/mailbox.pyi +256 -0
- mypy/typeshed/stdlib/mailcap.pyi +11 -0
- mypy/typeshed/stdlib/marshal.pyi +33 -0
- mypy/typeshed/stdlib/math.pyi +125 -0
- mypy/typeshed/stdlib/mimetypes.pyi +46 -0
- mypy/typeshed/stdlib/mmap.pyi +113 -0
- mypy/typeshed/stdlib/modulefinder.pyi +66 -0
- mypy/typeshed/stdlib/msilib/__init__.pyi +176 -0
- mypy/typeshed/stdlib/msilib/schema.pyi +94 -0
- mypy/typeshed/stdlib/msilib/sequence.pyi +13 -0
- mypy/typeshed/stdlib/msilib/text.pyi +7 -0
- mypy/typeshed/stdlib/msvcrt.pyi +32 -0
- mypy/typeshed/stdlib/multiprocessing/__init__.pyi +90 -0
- mypy/typeshed/stdlib/multiprocessing/connection.pyi +75 -0
- mypy/typeshed/stdlib/multiprocessing/context.pyi +187 -0
- mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi +77 -0
- mypy/typeshed/stdlib/multiprocessing/dummy/connection.pyi +39 -0
- mypy/typeshed/stdlib/multiprocessing/forkserver.pyi +31 -0
- mypy/typeshed/stdlib/multiprocessing/heap.pyi +36 -0
- mypy/typeshed/stdlib/multiprocessing/managers.pyi +212 -0
- mypy/typeshed/stdlib/multiprocessing/pool.pyi +103 -0
- mypy/typeshed/stdlib/multiprocessing/popen_fork.pyi +23 -0
- mypy/typeshed/stdlib/multiprocessing/popen_forkserver.pyi +16 -0
- mypy/typeshed/stdlib/multiprocessing/popen_spawn_posix.pyi +20 -0
- mypy/typeshed/stdlib/multiprocessing/popen_spawn_win32.pyi +30 -0
- mypy/typeshed/stdlib/multiprocessing/process.pyi +39 -0
- mypy/typeshed/stdlib/multiprocessing/queues.pyi +41 -0
- mypy/typeshed/stdlib/multiprocessing/reduction.pyi +89 -0
- mypy/typeshed/stdlib/multiprocessing/resource_sharer.pyi +20 -0
- mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi +18 -0
- mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi +40 -0
- mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi +101 -0
- mypy/typeshed/stdlib/multiprocessing/spawn.pyi +32 -0
- mypy/typeshed/stdlib/multiprocessing/synchronize.pyi +54 -0
- mypy/typeshed/stdlib/multiprocessing/util.pyi +79 -0
- mypy/typeshed/stdlib/netrc.pyi +23 -0
- mypy/typeshed/stdlib/nis.pyi +9 -0
- mypy/typeshed/stdlib/nntplib.pyi +125 -0
- mypy/typeshed/stdlib/nt.pyi +111 -0
- mypy/typeshed/stdlib/ntpath.pyi +119 -0
- mypy/typeshed/stdlib/nturl2path.pyi +2 -0
- mypy/typeshed/stdlib/numbers.pyi +154 -0
- mypy/typeshed/stdlib/opcode.pyi +59 -0
- mypy/typeshed/stdlib/operator.pyi +110 -0
- mypy/typeshed/stdlib/optparse.pyi +252 -0
- mypy/typeshed/stdlib/os/__init__.pyi +1139 -0
- mypy/typeshed/stdlib/os/path.pyi +8 -0
- mypy/typeshed/stdlib/ossaudiodev.pyi +131 -0
- mypy/typeshed/stdlib/parser.pyi +24 -0
- mypy/typeshed/stdlib/pathlib.pyi +232 -0
- mypy/typeshed/stdlib/pdb.pyi +181 -0
- mypy/typeshed/stdlib/pickle.pyi +270 -0
- mypy/typeshed/stdlib/pickletools.pyi +167 -0
- mypy/typeshed/stdlib/pipes.pyi +16 -0
- mypy/typeshed/stdlib/pkgutil.pyi +53 -0
- mypy/typeshed/stdlib/platform.pyi +42 -0
- mypy/typeshed/stdlib/plistlib.pyi +113 -0
- mypy/typeshed/stdlib/poplib.pyi +71 -0
- mypy/typeshed/stdlib/posix.pyi +359 -0
- mypy/typeshed/stdlib/posixpath.pyi +161 -0
- mypy/typeshed/stdlib/pprint.pyi +112 -0
- mypy/typeshed/stdlib/profile.pyi +31 -0
- mypy/typeshed/stdlib/pstats.pyi +78 -0
- mypy/typeshed/stdlib/pty.pyi +19 -0
- mypy/typeshed/stdlib/pwd.pyi +27 -0
- mypy/typeshed/stdlib/py_compile.pyi +34 -0
- mypy/typeshed/stdlib/pyclbr.pyi +74 -0
- mypy/typeshed/stdlib/pydoc.pyi +261 -0
- mypy/typeshed/stdlib/pydoc_data/__init__.pyi +0 -0
- mypy/typeshed/stdlib/pydoc_data/topics.pyi +1 -0
- mypy/typeshed/stdlib/pyexpat/__init__.pyi +80 -0
- mypy/typeshed/stdlib/pyexpat/errors.pyi +49 -0
- mypy/typeshed/stdlib/pyexpat/model.pyi +11 -0
- mypy/typeshed/stdlib/queue.pyi +58 -0
- mypy/typeshed/stdlib/quopri.pyi +11 -0
- mypy/typeshed/stdlib/random.pyi +138 -0
- mypy/typeshed/stdlib/re.pyi +290 -0
- mypy/typeshed/stdlib/readline.pyi +36 -0
- mypy/typeshed/stdlib/reprlib.pyi +65 -0
- mypy/typeshed/stdlib/resource.pyi +92 -0
- mypy/typeshed/stdlib/rlcompleter.pyi +9 -0
- mypy/typeshed/stdlib/runpy.pyi +24 -0
- mypy/typeshed/stdlib/sched.pyi +42 -0
- mypy/typeshed/stdlib/secrets.pyi +15 -0
- mypy/typeshed/stdlib/select.pyi +151 -0
- mypy/typeshed/stdlib/selectors.pyi +67 -0
- mypy/typeshed/stdlib/shelve.pyi +46 -0
- mypy/typeshed/stdlib/shlex.pyi +43 -0
- mypy/typeshed/stdlib/shutil.pyi +189 -0
- mypy/typeshed/stdlib/signal.pyi +189 -0
- mypy/typeshed/stdlib/site.pyi +27 -0
- mypy/typeshed/stdlib/smtpd.pyi +91 -0
- mypy/typeshed/stdlib/smtplib.pyi +204 -0
- mypy/typeshed/stdlib/sndhdr.pyi +14 -0
- mypy/typeshed/stdlib/socket.pyi +825 -0
- mypy/typeshed/stdlib/socketserver.pyi +168 -0
- mypy/typeshed/stdlib/spwd.pyi +40 -0
- mypy/typeshed/stdlib/sqlite3/__init__.pyi +1 -0
- mypy/typeshed/stdlib/sqlite3/dbapi2.pyi +469 -0
- mypy/typeshed/stdlib/sre_compile.pyi +11 -0
- mypy/typeshed/stdlib/sre_constants.pyi +130 -0
- mypy/typeshed/stdlib/sre_parse.pyi +104 -0
- mypy/typeshed/stdlib/ssl.pyi +529 -0
- mypy/typeshed/stdlib/stat.pyi +1 -0
- mypy/typeshed/stdlib/statistics.pyi +132 -0
- mypy/typeshed/stdlib/string.pyi +83 -0
- mypy/typeshed/stdlib/stringprep.pyi +27 -0
- mypy/typeshed/stdlib/struct.pyi +26 -0
- mypy/typeshed/stdlib/subprocess.pyi +2614 -0
- mypy/typeshed/stdlib/sunau.pyi +86 -0
- mypy/typeshed/stdlib/symbol.pyi +93 -0
- mypy/typeshed/stdlib/symtable.pyi +58 -0
- mypy/typeshed/stdlib/sys/__init__.pyi +373 -0
- mypy/typeshed/stdlib/sys/_monitoring.pyi +52 -0
- mypy/typeshed/stdlib/sysconfig.pyi +43 -0
- mypy/typeshed/stdlib/syslog.pyi +46 -0
- mypy/typeshed/stdlib/tabnanny.pyi +16 -0
- mypy/typeshed/stdlib/tarfile.pyi +438 -0
- mypy/typeshed/stdlib/telnetlib.pyi +122 -0
- mypy/typeshed/stdlib/tempfile.pyi +477 -0
- mypy/typeshed/stdlib/termios.pyi +267 -0
- mypy/typeshed/stdlib/textwrap.pyi +103 -0
- mypy/typeshed/stdlib/this.pyi +2 -0
- mypy/typeshed/stdlib/threading.pyi +187 -0
- mypy/typeshed/stdlib/time.pyi +107 -0
- mypy/typeshed/stdlib/timeit.pyi +32 -0
- mypy/typeshed/stdlib/tkinter/__init__.pyi +3641 -0
- mypy/typeshed/stdlib/tkinter/colorchooser.pyi +20 -0
- mypy/typeshed/stdlib/tkinter/commondialog.pyi +14 -0
- mypy/typeshed/stdlib/tkinter/constants.pyi +80 -0
- mypy/typeshed/stdlib/tkinter/dialog.pyi +16 -0
- mypy/typeshed/stdlib/tkinter/dnd.pyi +20 -0
- mypy/typeshed/stdlib/tkinter/filedialog.pyi +151 -0
- mypy/typeshed/stdlib/tkinter/font.pyi +116 -0
- mypy/typeshed/stdlib/tkinter/messagebox.pyi +44 -0
- mypy/typeshed/stdlib/tkinter/scrolledtext.pyi +10 -0
- mypy/typeshed/stdlib/tkinter/simpledialog.pyi +54 -0
- mypy/typeshed/stdlib/tkinter/tix.pyi +299 -0
- mypy/typeshed/stdlib/tkinter/ttk.pyi +1191 -0
- mypy/typeshed/stdlib/token.pyi +159 -0
- mypy/typeshed/stdlib/tokenize.pyi +177 -0
- mypy/typeshed/stdlib/tomllib.pyi +10 -0
- mypy/typeshed/stdlib/trace.pyi +79 -0
- mypy/typeshed/stdlib/traceback.pyi +260 -0
- mypy/typeshed/stdlib/tracemalloc.pyi +124 -0
- mypy/typeshed/stdlib/tty.pyi +30 -0
- mypy/typeshed/stdlib/turtle.pyi +713 -0
- mypy/typeshed/stdlib/types.pyi +605 -0
- mypy/typeshed/stdlib/typing.pyi +968 -0
- mypy/typeshed/stdlib/typing_extensions.pyi +503 -0
- mypy/typeshed/stdlib/unicodedata.pyi +71 -0
- mypy/typeshed/stdlib/unittest/__init__.pyi +67 -0
- mypy/typeshed/stdlib/unittest/_log.pyi +27 -0
- mypy/typeshed/stdlib/unittest/async_case.pyi +21 -0
- mypy/typeshed/stdlib/unittest/case.pyi +342 -0
- mypy/typeshed/stdlib/unittest/loader.pyi +51 -0
- mypy/typeshed/stdlib/unittest/main.pyi +69 -0
- mypy/typeshed/stdlib/unittest/mock.pyi +430 -0
- mypy/typeshed/stdlib/unittest/result.pyi +46 -0
- mypy/typeshed/stdlib/unittest/runner.pyi +72 -0
- mypy/typeshed/stdlib/unittest/signals.pyi +15 -0
- mypy/typeshed/stdlib/unittest/suite.pyi +22 -0
- mypy/typeshed/stdlib/unittest/util.pyi +23 -0
- mypy/typeshed/stdlib/urllib/__init__.pyi +0 -0
- mypy/typeshed/stdlib/urllib/error.pyi +23 -0
- mypy/typeshed/stdlib/urllib/parse.pyi +210 -0
- mypy/typeshed/stdlib/urllib/request.pyi +399 -0
- mypy/typeshed/stdlib/urllib/response.pyi +43 -0
- mypy/typeshed/stdlib/urllib/robotparser.pyi +20 -0
- mypy/typeshed/stdlib/uu.pyi +13 -0
- mypy/typeshed/stdlib/uuid.pyi +100 -0
- mypy/typeshed/stdlib/venv/__init__.pyi +79 -0
- mypy/typeshed/stdlib/warnings.pyi +112 -0
- mypy/typeshed/stdlib/wave.pyi +85 -0
- mypy/typeshed/stdlib/weakref.pyi +150 -0
- mypy/typeshed/stdlib/webbrowser.pyi +74 -0
- mypy/typeshed/stdlib/winreg.pyi +103 -0
- mypy/typeshed/stdlib/winsound.pyi +28 -0
- mypy/typeshed/stdlib/wsgiref/__init__.pyi +0 -0
- mypy/typeshed/stdlib/wsgiref/handlers.pyi +91 -0
- mypy/typeshed/stdlib/wsgiref/headers.pyi +26 -0
- mypy/typeshed/stdlib/wsgiref/simple_server.pyi +37 -0
- mypy/typeshed/stdlib/wsgiref/types.pyi +32 -0
- mypy/typeshed/stdlib/wsgiref/util.pyi +24 -0
- mypy/typeshed/stdlib/wsgiref/validate.pyi +50 -0
- mypy/typeshed/stdlib/xdrlib.pyi +57 -0
- mypy/typeshed/stdlib/xml/__init__.pyi +1 -0
- mypy/typeshed/stdlib/xml/dom/NodeFilter.pyi +19 -0
- mypy/typeshed/stdlib/xml/dom/__init__.pyi +69 -0
- mypy/typeshed/stdlib/xml/dom/domreg.pyi +8 -0
- mypy/typeshed/stdlib/xml/dom/expatbuilder.pyi +100 -0
- mypy/typeshed/stdlib/xml/dom/minicompat.pyi +22 -0
- mypy/typeshed/stdlib/xml/dom/minidom.pyi +404 -0
- mypy/typeshed/stdlib/xml/dom/pulldom.pyi +94 -0
- mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi +108 -0
- mypy/typeshed/stdlib/xml/etree/ElementInclude.pyi +28 -0
- mypy/typeshed/stdlib/xml/etree/ElementPath.pyi +34 -0
- mypy/typeshed/stdlib/xml/etree/ElementTree.pyi +321 -0
- mypy/typeshed/stdlib/xml/etree/__init__.pyi +0 -0
- mypy/typeshed/stdlib/xml/etree/cElementTree.pyi +1 -0
- mypy/typeshed/stdlib/xml/parsers/__init__.pyi +1 -0
- mypy/typeshed/stdlib/xml/parsers/expat/__init__.pyi +1 -0
- mypy/typeshed/stdlib/xml/parsers/expat/errors.pyi +1 -0
- mypy/typeshed/stdlib/xml/parsers/expat/model.pyi +1 -0
- mypy/typeshed/stdlib/xml/sax/__init__.pyi +25 -0
- mypy/typeshed/stdlib/xml/sax/_exceptions.pyi +19 -0
- mypy/typeshed/stdlib/xml/sax/handler.pyi +55 -0
- mypy/typeshed/stdlib/xml/sax/saxutils.pyi +60 -0
- mypy/typeshed/stdlib/xml/sax/xmlreader.pyi +87 -0
- mypy/typeshed/stdlib/xmlrpc/__init__.pyi +0 -0
- mypy/typeshed/stdlib/xmlrpc/client.pyi +296 -0
- mypy/typeshed/stdlib/xmlrpc/server.pyi +143 -0
- mypy/typeshed/stdlib/xxlimited.pyi +22 -0
- mypy/typeshed/stdlib/zipapp.pyi +20 -0
- mypy/typeshed/stdlib/zipfile/__init__.pyi +306 -0
- mypy/typeshed/stdlib/zipfile/_path.pyi +95 -0
- mypy/typeshed/stdlib/zipimport.pyi +32 -0
- mypy/typeshed/stdlib/zlib.pyi +56 -0
- mypy/typeshed/stdlib/zoneinfo/__init__.pyi +38 -0
- mypy/typeshed/stubs/mypy-extensions/mypy_extensions.pyi +218 -0
- mypy/typestate.py +323 -0
- mypy/typetraverser.py +142 -0
- mypy/typevars.py +93 -0
- mypy/typevartuples.py +32 -0
- mypy/util.py +869 -0
- mypy/version.py +1 -0
- mypy/visitor.py +621 -0
- mypy/xml/mypy-html.css +104 -0
- mypy/xml/mypy-html.xslt +81 -0
- mypy/xml/mypy-txt.xslt +100 -0
- mypy/xml/mypy.xsd +50 -0
- mypy_dev-1.9.0.dev0.dist-info/LICENSE +229 -0
- mypy_dev-1.9.0.dev0.dist-info/METADATA +39 -0
- mypy_dev-1.9.0.dev0.dist-info/RECORD +1018 -0
- mypy_dev-1.9.0.dev0.dist-info/WHEEL +5 -0
- mypy_dev-1.9.0.dev0.dist-info/entry_points.txt +6 -0
- mypy_dev-1.9.0.dev0.dist-info/top_level.txt +2 -0
- mypyc/README.md +133 -0
- mypyc/__init__.py +0 -0
- mypyc/__main__.py +57 -0
- mypyc/analysis/__init__.py +0 -0
- mypyc/analysis/attrdefined.py +436 -0
- mypyc/analysis/blockfreq.py +32 -0
- mypyc/analysis/dataflow.py +624 -0
- mypyc/analysis/ircheck.py +429 -0
- mypyc/analysis/selfleaks.py +207 -0
- mypyc/build.py +616 -0
- mypyc/codegen/__init__.py +0 -0
- mypyc/codegen/cstring.py +54 -0
- mypyc/codegen/emit.py +1193 -0
- mypyc/codegen/emitclass.py +1060 -0
- mypyc/codegen/emitfunc.py +846 -0
- mypyc/codegen/emitmodule.py +1131 -0
- mypyc/codegen/emitwrapper.py +979 -0
- mypyc/codegen/literals.py +302 -0
- mypyc/common.py +136 -0
- mypyc/crash.py +31 -0
- mypyc/doc/Makefile +20 -0
- mypyc/doc/bool_operations.rst +27 -0
- mypyc/doc/compilation_units.rst +20 -0
- mypyc/doc/conf.py +59 -0
- mypyc/doc/cpython-timings.md +25 -0
- mypyc/doc/dev-intro.md +548 -0
- mypyc/doc/dict_operations.rst +59 -0
- mypyc/doc/differences_from_python.rst +332 -0
- mypyc/doc/float_operations.rst +50 -0
- mypyc/doc/future.md +42 -0
- mypyc/doc/getting_started.rst +240 -0
- mypyc/doc/index.rst +61 -0
- mypyc/doc/int_operations.rst +162 -0
- mypyc/doc/introduction.rst +150 -0
- mypyc/doc/list_operations.rst +65 -0
- mypyc/doc/make.bat +35 -0
- mypyc/doc/native_classes.rst +206 -0
- mypyc/doc/native_operations.rst +55 -0
- mypyc/doc/performance_tips_and_tricks.rst +244 -0
- mypyc/doc/set_operations.rst +47 -0
- mypyc/doc/str_operations.rst +35 -0
- mypyc/doc/tuple_operations.rst +33 -0
- mypyc/doc/using_type_annotations.rst +398 -0
- mypyc/errors.py +29 -0
- mypyc/external/googletest/LICENSE +28 -0
- mypyc/external/googletest/README.md +280 -0
- mypyc/external/googletest/include/gtest/gtest-death-test.h +294 -0
- mypyc/external/googletest/include/gtest/gtest-message.h +250 -0
- mypyc/external/googletest/include/gtest/gtest-param-test.h +1444 -0
- mypyc/external/googletest/include/gtest/gtest-param-test.h.pump +510 -0
- mypyc/external/googletest/include/gtest/gtest-printers.h +993 -0
- mypyc/external/googletest/include/gtest/gtest-spi.h +232 -0
- mypyc/external/googletest/include/gtest/gtest-test-part.h +179 -0
- mypyc/external/googletest/include/gtest/gtest-typed-test.h +263 -0
- mypyc/external/googletest/include/gtest/gtest.h +2236 -0
- mypyc/external/googletest/include/gtest/gtest_pred_impl.h +358 -0
- mypyc/external/googletest/include/gtest/gtest_prod.h +58 -0
- mypyc/external/googletest/include/gtest/internal/custom/gtest-port.h +69 -0
- mypyc/external/googletest/include/gtest/internal/custom/gtest-printers.h +42 -0
- mypyc/external/googletest/include/gtest/internal/custom/gtest.h +41 -0
- mypyc/external/googletest/include/gtest/internal/gtest-death-test-internal.h +319 -0
- mypyc/external/googletest/include/gtest/internal/gtest-filepath.h +206 -0
- mypyc/external/googletest/include/gtest/internal/gtest-internal.h +1238 -0
- mypyc/external/googletest/include/gtest/internal/gtest-linked_ptr.h +243 -0
- mypyc/external/googletest/include/gtest/internal/gtest-param-util-generated.h +5146 -0
- mypyc/external/googletest/include/gtest/internal/gtest-param-util-generated.h.pump +286 -0
- mypyc/external/googletest/include/gtest/internal/gtest-param-util.h +731 -0
- mypyc/external/googletest/include/gtest/internal/gtest-port-arch.h +93 -0
- mypyc/external/googletest/include/gtest/internal/gtest-port.h +2560 -0
- mypyc/external/googletest/include/gtest/internal/gtest-string.h +167 -0
- mypyc/external/googletest/include/gtest/internal/gtest-tuple.h +1020 -0
- mypyc/external/googletest/include/gtest/internal/gtest-tuple.h.pump +347 -0
- mypyc/external/googletest/include/gtest/internal/gtest-type-util.h +3331 -0
- mypyc/external/googletest/include/gtest/internal/gtest-type-util.h.pump +297 -0
- mypyc/external/googletest/make/Makefile +61 -0
- mypyc/external/googletest/src/gtest-all.cc +48 -0
- mypyc/external/googletest/src/gtest-death-test.cc +1342 -0
- mypyc/external/googletest/src/gtest-filepath.cc +387 -0
- mypyc/external/googletest/src/gtest-internal-inl.h +1183 -0
- mypyc/external/googletest/src/gtest-port.cc +1259 -0
- mypyc/external/googletest/src/gtest-printers.cc +373 -0
- mypyc/external/googletest/src/gtest-test-part.cc +110 -0
- mypyc/external/googletest/src/gtest-typed-test.cc +118 -0
- mypyc/external/googletest/src/gtest.cc +5388 -0
- mypyc/external/googletest/src/gtest_main.cc +38 -0
- mypyc/ir/__init__.py +0 -0
- mypyc/ir/class_ir.py +499 -0
- mypyc/ir/func_ir.py +370 -0
- mypyc/ir/module_ir.py +88 -0
- mypyc/ir/ops.py +1642 -0
- mypyc/ir/pprint.py +496 -0
- mypyc/ir/rtypes.py +1038 -0
- mypyc/irbuild/__init__.py +0 -0
- mypyc/irbuild/ast_helpers.py +120 -0
- mypyc/irbuild/builder.py +1398 -0
- mypyc/irbuild/callable_class.py +173 -0
- mypyc/irbuild/classdef.py +850 -0
- mypyc/irbuild/constant_fold.py +95 -0
- mypyc/irbuild/context.py +186 -0
- mypyc/irbuild/env_class.py +223 -0
- mypyc/irbuild/expression.py +1067 -0
- mypyc/irbuild/for_helpers.py +1046 -0
- mypyc/irbuild/format_str_tokenizer.py +250 -0
- mypyc/irbuild/function.py +1089 -0
- mypyc/irbuild/generator.py +346 -0
- mypyc/irbuild/ll_builder.py +2407 -0
- mypyc/irbuild/main.py +153 -0
- mypyc/irbuild/mapper.py +221 -0
- mypyc/irbuild/match.py +355 -0
- mypyc/irbuild/nonlocalcontrol.py +197 -0
- mypyc/irbuild/prebuildvisitor.py +203 -0
- mypyc/irbuild/prepare.py +609 -0
- mypyc/irbuild/specialize.py +822 -0
- mypyc/irbuild/statement.py +1017 -0
- mypyc/irbuild/targets.py +57 -0
- mypyc/irbuild/util.py +189 -0
- mypyc/irbuild/visitor.py +401 -0
- mypyc/irbuild/vtable.py +82 -0
- mypyc/lib-rt/CPy.h +643 -0
- mypyc/lib-rt/bytes_ops.c +143 -0
- mypyc/lib-rt/dict_ops.c +446 -0
- mypyc/lib-rt/exc_ops.c +259 -0
- mypyc/lib-rt/float_ops.c +192 -0
- mypyc/lib-rt/generic_ops.c +64 -0
- mypyc/lib-rt/getargs.c +450 -0
- mypyc/lib-rt/getargsfast.c +569 -0
- mypyc/lib-rt/init.c +13 -0
- mypyc/lib-rt/int_ops.c +803 -0
- mypyc/lib-rt/list_ops.c +335 -0
- mypyc/lib-rt/misc_ops.c +942 -0
- mypyc/lib-rt/module_shim.tmpl +18 -0
- mypyc/lib-rt/mypyc_util.h +118 -0
- mypyc/lib-rt/pythoncapi_compat.h +497 -0
- mypyc/lib-rt/pythonsupport.h +548 -0
- mypyc/lib-rt/set_ops.c +17 -0
- mypyc/lib-rt/setup.py +70 -0
- mypyc/lib-rt/str_ops.c +241 -0
- mypyc/lib-rt/test_capi.cc +585 -0
- mypyc/lib-rt/tuple_ops.c +61 -0
- mypyc/namegen.py +115 -0
- mypyc/options.py +32 -0
- mypyc/primitives/__init__.py +0 -0
- mypyc/primitives/bytes_ops.py +101 -0
- mypyc/primitives/dict_ops.py +325 -0
- mypyc/primitives/exc_ops.py +101 -0
- mypyc/primitives/float_ops.py +168 -0
- mypyc/primitives/generic_ops.py +384 -0
- mypyc/primitives/int_ops.py +304 -0
- mypyc/primitives/list_ops.py +300 -0
- mypyc/primitives/misc_ops.py +241 -0
- mypyc/primitives/registry.py +323 -0
- mypyc/primitives/set_ops.py +121 -0
- mypyc/primitives/str_ops.py +229 -0
- mypyc/primitives/tuple_ops.py +83 -0
- mypyc/rt_subtype.py +77 -0
- mypyc/sametype.py +83 -0
- mypyc/subtype.py +88 -0
- mypyc/test/__init__.py +0 -0
- mypyc/test/config.py +13 -0
- mypyc/test/test_alwaysdefined.py +46 -0
- mypyc/test/test_analysis.py +77 -0
- mypyc/test/test_cheader.py +45 -0
- mypyc/test/test_commandline.py +82 -0
- mypyc/test/test_emit.py +69 -0
- mypyc/test/test_emitclass.py +35 -0
- mypyc/test/test_emitfunc.py +926 -0
- mypyc/test/test_emitwrapper.py +60 -0
- mypyc/test/test_exceptions.py +56 -0
- mypyc/test/test_external.py +49 -0
- mypyc/test/test_irbuild.py +87 -0
- mypyc/test/test_ircheck.py +199 -0
- mypyc/test/test_literals.py +90 -0
- mypyc/test/test_namegen.py +48 -0
- mypyc/test/test_pprint.py +42 -0
- mypyc/test/test_rarray.py +48 -0
- mypyc/test/test_refcount.py +59 -0
- mypyc/test/test_run.py +426 -0
- mypyc/test/test_serialization.py +108 -0
- mypyc/test/test_struct.py +112 -0
- mypyc/test/test_tuplename.py +33 -0
- mypyc/test/test_typeops.py +97 -0
- mypyc/test/testutil.py +283 -0
- mypyc/test-data/alwaysdefined.test +732 -0
- mypyc/test-data/analysis.test +603 -0
- mypyc/test-data/commandline.test +245 -0
- mypyc/test-data/driver/driver.py +48 -0
- mypyc/test-data/exceptions-freq.test +125 -0
- mypyc/test-data/exceptions.test +713 -0
- mypyc/test-data/fixtures/ir.py +373 -0
- mypyc/test-data/fixtures/testutil.py +103 -0
- mypyc/test-data/fixtures/typing-full.pyi +169 -0
- mypyc/test-data/irbuild-any.test +238 -0
- mypyc/test-data/irbuild-basic.test +3690 -0
- mypyc/test-data/irbuild-bool.test +463 -0
- mypyc/test-data/irbuild-bytes.test +184 -0
- mypyc/test-data/irbuild-classes.test +1303 -0
- mypyc/test-data/irbuild-constant-fold.test +480 -0
- mypyc/test-data/irbuild-dict.test +585 -0
- mypyc/test-data/irbuild-dunders.test +223 -0
- mypyc/test-data/irbuild-float.test +497 -0
- mypyc/test-data/irbuild-generics.test +151 -0
- mypyc/test-data/irbuild-glue-methods.test +437 -0
- mypyc/test-data/irbuild-i16.test +526 -0
- mypyc/test-data/irbuild-i32.test +598 -0
- mypyc/test-data/irbuild-i64.test +2164 -0
- mypyc/test-data/irbuild-int.test +235 -0
- mypyc/test-data/irbuild-isinstance.test +109 -0
- mypyc/test-data/irbuild-lists.test +547 -0
- mypyc/test-data/irbuild-match.test +1708 -0
- mypyc/test-data/irbuild-math.test +64 -0
- mypyc/test-data/irbuild-nested.test +807 -0
- mypyc/test-data/irbuild-optional.test +536 -0
- mypyc/test-data/irbuild-set.test +838 -0
- mypyc/test-data/irbuild-singledispatch.test +257 -0
- mypyc/test-data/irbuild-statements.test +1149 -0
- mypyc/test-data/irbuild-str.test +314 -0
- mypyc/test-data/irbuild-strip-asserts.test +12 -0
- mypyc/test-data/irbuild-try.test +523 -0
- mypyc/test-data/irbuild-tuple.test +462 -0
- mypyc/test-data/irbuild-u8.test +543 -0
- mypyc/test-data/irbuild-unreachable.test +241 -0
- mypyc/test-data/irbuild-vectorcall.test +153 -0
- mypyc/test-data/refcount.test +1588 -0
- mypyc/test-data/run-async.test +145 -0
- mypyc/test-data/run-attrs.test +318 -0
- mypyc/test-data/run-bench.test +196 -0
- mypyc/test-data/run-bools.test +229 -0
- mypyc/test-data/run-bytes.test +302 -0
- mypyc/test-data/run-classes.test +2505 -0
- mypyc/test-data/run-dicts.test +334 -0
- mypyc/test-data/run-dunders.test +945 -0
- mypyc/test-data/run-exceptions.test +448 -0
- mypyc/test-data/run-floats.test +516 -0
- mypyc/test-data/run-functions.test +1310 -0
- mypyc/test-data/run-generators.test +681 -0
- mypyc/test-data/run-i16.test +338 -0
- mypyc/test-data/run-i32.test +336 -0
- mypyc/test-data/run-i64.test +1519 -0
- mypyc/test-data/run-imports.test +265 -0
- mypyc/test-data/run-integers.test +540 -0
- mypyc/test-data/run-lists.test +411 -0
- mypyc/test-data/run-loops.test +485 -0
- mypyc/test-data/run-match.test +283 -0
- mypyc/test-data/run-math.test +106 -0
- mypyc/test-data/run-misc.test +1168 -0
- mypyc/test-data/run-multimodule.test +887 -0
- mypyc/test-data/run-mypy-sim.test +138 -0
- mypyc/test-data/run-primitives.test +375 -0
- mypyc/test-data/run-python37.test +159 -0
- mypyc/test-data/run-python38.test +88 -0
- mypyc/test-data/run-sets.test +150 -0
- mypyc/test-data/run-singledispatch.test +698 -0
- mypyc/test-data/run-strings.test +641 -0
- mypyc/test-data/run-traits.test +411 -0
- mypyc/test-data/run-tuples.test +258 -0
- mypyc/test-data/run-u8.test +303 -0
- mypyc/transform/__init__.py +0 -0
- mypyc/transform/exceptions.py +182 -0
- mypyc/transform/refcount.py +294 -0
- mypyc/transform/uninit.py +190 -0
|
@@ -0,0 +1,2492 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import inspect
|
|
5
|
+
import io
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
import tempfile
|
|
10
|
+
import textwrap
|
|
11
|
+
import unittest
|
|
12
|
+
from typing import Any, Callable, Iterator
|
|
13
|
+
|
|
14
|
+
import mypy.stubtest
|
|
15
|
+
from mypy.stubtest import parse_options, test_stubs
|
|
16
|
+
from mypy.test.data import root_dir
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@contextlib.contextmanager
|
|
20
|
+
def use_tmp_dir(mod_name: str) -> Iterator[str]:
|
|
21
|
+
current = os.getcwd()
|
|
22
|
+
current_syspath = sys.path.copy()
|
|
23
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
24
|
+
try:
|
|
25
|
+
os.chdir(tmp)
|
|
26
|
+
if sys.path[0] != tmp:
|
|
27
|
+
sys.path.insert(0, tmp)
|
|
28
|
+
yield tmp
|
|
29
|
+
finally:
|
|
30
|
+
sys.path = current_syspath.copy()
|
|
31
|
+
if mod_name in sys.modules:
|
|
32
|
+
del sys.modules[mod_name]
|
|
33
|
+
|
|
34
|
+
os.chdir(current)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
TEST_MODULE_NAME = "test_module"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
stubtest_typing_stub = """
|
|
41
|
+
Any = object()
|
|
42
|
+
|
|
43
|
+
class _SpecialForm:
|
|
44
|
+
def __getitem__(self, typeargs: Any) -> object: ...
|
|
45
|
+
|
|
46
|
+
Callable: _SpecialForm = ...
|
|
47
|
+
Generic: _SpecialForm = ...
|
|
48
|
+
Protocol: _SpecialForm = ...
|
|
49
|
+
Union: _SpecialForm = ...
|
|
50
|
+
|
|
51
|
+
class TypeVar:
|
|
52
|
+
def __init__(self, name, covariant: bool = ..., contravariant: bool = ...) -> None: ...
|
|
53
|
+
|
|
54
|
+
class ParamSpec:
|
|
55
|
+
def __init__(self, name: str) -> None: ...
|
|
56
|
+
|
|
57
|
+
AnyStr = TypeVar("AnyStr", str, bytes)
|
|
58
|
+
_T = TypeVar("_T")
|
|
59
|
+
_T_co = TypeVar("_T_co", covariant=True)
|
|
60
|
+
_K = TypeVar("_K")
|
|
61
|
+
_V = TypeVar("_V")
|
|
62
|
+
_S = TypeVar("_S", contravariant=True)
|
|
63
|
+
_R = TypeVar("_R", covariant=True)
|
|
64
|
+
|
|
65
|
+
class Coroutine(Generic[_T_co, _S, _R]): ...
|
|
66
|
+
class Iterable(Generic[_T_co]): ...
|
|
67
|
+
class Iterator(Iterable[_T_co]): ...
|
|
68
|
+
class Mapping(Generic[_K, _V]): ...
|
|
69
|
+
class Match(Generic[AnyStr]): ...
|
|
70
|
+
class Sequence(Iterable[_T_co]): ...
|
|
71
|
+
class Tuple(Sequence[_T_co]): ...
|
|
72
|
+
class NamedTuple(tuple[Any, ...]): ...
|
|
73
|
+
def overload(func: _T) -> _T: ...
|
|
74
|
+
def type_check_only(func: _T) -> _T: ...
|
|
75
|
+
def final(func: _T) -> _T: ...
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
stubtest_builtins_stub = """
|
|
79
|
+
from typing import Generic, Mapping, Sequence, TypeVar, overload
|
|
80
|
+
|
|
81
|
+
T = TypeVar('T')
|
|
82
|
+
T_co = TypeVar('T_co', covariant=True)
|
|
83
|
+
KT = TypeVar('KT')
|
|
84
|
+
VT = TypeVar('VT')
|
|
85
|
+
|
|
86
|
+
class object:
|
|
87
|
+
__module__: str
|
|
88
|
+
def __init__(self) -> None: pass
|
|
89
|
+
def __repr__(self) -> str: pass
|
|
90
|
+
class type: ...
|
|
91
|
+
|
|
92
|
+
class tuple(Sequence[T_co], Generic[T_co]):
|
|
93
|
+
def __ge__(self, __other: tuple[T_co, ...]) -> bool: pass
|
|
94
|
+
|
|
95
|
+
class dict(Mapping[KT, VT]): ...
|
|
96
|
+
|
|
97
|
+
class function: pass
|
|
98
|
+
class ellipsis: pass
|
|
99
|
+
|
|
100
|
+
class int: ...
|
|
101
|
+
class float: ...
|
|
102
|
+
class bool(int): ...
|
|
103
|
+
class str: ...
|
|
104
|
+
class bytes: ...
|
|
105
|
+
|
|
106
|
+
class list(Sequence[T]): ...
|
|
107
|
+
|
|
108
|
+
def property(f: T) -> T: ...
|
|
109
|
+
def classmethod(f: T) -> T: ...
|
|
110
|
+
def staticmethod(f: T) -> T: ...
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
stubtest_enum_stub = """
|
|
114
|
+
import sys
|
|
115
|
+
from typing import Any, TypeVar, Iterator
|
|
116
|
+
|
|
117
|
+
_T = TypeVar('_T')
|
|
118
|
+
|
|
119
|
+
class EnumMeta(type):
|
|
120
|
+
def __len__(self) -> int: pass
|
|
121
|
+
def __iter__(self: type[_T]) -> Iterator[_T]: pass
|
|
122
|
+
def __reversed__(self: type[_T]) -> Iterator[_T]: pass
|
|
123
|
+
def __getitem__(self: type[_T], name: str) -> _T: pass
|
|
124
|
+
|
|
125
|
+
class Enum(metaclass=EnumMeta):
|
|
126
|
+
def __new__(cls: type[_T], value: object) -> _T: pass
|
|
127
|
+
def __repr__(self) -> str: pass
|
|
128
|
+
def __str__(self) -> str: pass
|
|
129
|
+
def __format__(self, format_spec: str) -> str: pass
|
|
130
|
+
def __hash__(self) -> Any: pass
|
|
131
|
+
def __reduce_ex__(self, proto: Any) -> Any: pass
|
|
132
|
+
name: str
|
|
133
|
+
value: Any
|
|
134
|
+
|
|
135
|
+
class Flag(Enum):
|
|
136
|
+
def __or__(self: _T, other: _T) -> _T: pass
|
|
137
|
+
def __and__(self: _T, other: _T) -> _T: pass
|
|
138
|
+
def __xor__(self: _T, other: _T) -> _T: pass
|
|
139
|
+
def __invert__(self: _T) -> _T: pass
|
|
140
|
+
if sys.version_info >= (3, 11):
|
|
141
|
+
__ror__ = __or__
|
|
142
|
+
__rand__ = __and__
|
|
143
|
+
__rxor__ = __xor__
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def run_stubtest(
|
|
148
|
+
stub: str, runtime: str, options: list[str], config_file: str | None = None
|
|
149
|
+
) -> str:
|
|
150
|
+
with use_tmp_dir(TEST_MODULE_NAME) as tmp_dir:
|
|
151
|
+
with open("builtins.pyi", "w") as f:
|
|
152
|
+
f.write(stubtest_builtins_stub)
|
|
153
|
+
with open("typing.pyi", "w") as f:
|
|
154
|
+
f.write(stubtest_typing_stub)
|
|
155
|
+
with open("enum.pyi", "w") as f:
|
|
156
|
+
f.write(stubtest_enum_stub)
|
|
157
|
+
with open(f"{TEST_MODULE_NAME}.pyi", "w") as f:
|
|
158
|
+
f.write(stub)
|
|
159
|
+
with open(f"{TEST_MODULE_NAME}.py", "w") as f:
|
|
160
|
+
f.write(runtime)
|
|
161
|
+
if config_file:
|
|
162
|
+
with open(f"{TEST_MODULE_NAME}_config.ini", "w") as f:
|
|
163
|
+
f.write(config_file)
|
|
164
|
+
options = options + ["--mypy-config-file", f"{TEST_MODULE_NAME}_config.ini"]
|
|
165
|
+
output = io.StringIO()
|
|
166
|
+
with contextlib.redirect_stdout(output):
|
|
167
|
+
test_stubs(parse_options([TEST_MODULE_NAME] + options), use_builtins_fixtures=True)
|
|
168
|
+
return remove_color_code(
|
|
169
|
+
output.getvalue()
|
|
170
|
+
# remove cwd as it's not available from outside
|
|
171
|
+
.replace(os.path.realpath(tmp_dir) + os.sep, "").replace(tmp_dir + os.sep, "")
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class Case:
|
|
176
|
+
def __init__(self, stub: str, runtime: str, error: str | None) -> None:
|
|
177
|
+
self.stub = stub
|
|
178
|
+
self.runtime = runtime
|
|
179
|
+
self.error = error
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def collect_cases(fn: Callable[..., Iterator[Case]]) -> Callable[..., None]:
|
|
183
|
+
"""run_stubtest used to be slow, so we used this decorator to combine cases.
|
|
184
|
+
|
|
185
|
+
If you're reading this and bored, feel free to refactor this and make it more like
|
|
186
|
+
other mypy tests.
|
|
187
|
+
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
def test(*args: Any, **kwargs: Any) -> None:
|
|
191
|
+
cases = list(fn(*args, **kwargs))
|
|
192
|
+
expected_errors = set()
|
|
193
|
+
for c in cases:
|
|
194
|
+
if c.error is None:
|
|
195
|
+
continue
|
|
196
|
+
expected_error = c.error
|
|
197
|
+
if expected_error == "":
|
|
198
|
+
expected_error = TEST_MODULE_NAME
|
|
199
|
+
elif not expected_error.startswith(f"{TEST_MODULE_NAME}."):
|
|
200
|
+
expected_error = f"{TEST_MODULE_NAME}.{expected_error}"
|
|
201
|
+
assert expected_error not in expected_errors, (
|
|
202
|
+
"collect_cases merges cases into a single stubtest invocation; we already "
|
|
203
|
+
"expect an error for {}".format(expected_error)
|
|
204
|
+
)
|
|
205
|
+
expected_errors.add(expected_error)
|
|
206
|
+
output = run_stubtest(
|
|
207
|
+
stub="\n\n".join(textwrap.dedent(c.stub.lstrip("\n")) for c in cases),
|
|
208
|
+
runtime="\n\n".join(textwrap.dedent(c.runtime.lstrip("\n")) for c in cases),
|
|
209
|
+
options=["--generate-allowlist"],
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
actual_errors = set(output.splitlines())
|
|
213
|
+
if actual_errors != expected_errors:
|
|
214
|
+
output = run_stubtest(
|
|
215
|
+
stub="\n\n".join(textwrap.dedent(c.stub.lstrip("\n")) for c in cases),
|
|
216
|
+
runtime="\n\n".join(textwrap.dedent(c.runtime.lstrip("\n")) for c in cases),
|
|
217
|
+
options=[],
|
|
218
|
+
)
|
|
219
|
+
assert actual_errors == expected_errors, output
|
|
220
|
+
|
|
221
|
+
return test
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class StubtestUnit(unittest.TestCase):
|
|
225
|
+
@collect_cases
|
|
226
|
+
def test_basic_good(self) -> Iterator[Case]:
|
|
227
|
+
yield Case(
|
|
228
|
+
stub="def f(number: int, text: str) -> None: ...",
|
|
229
|
+
runtime="def f(number, text): pass",
|
|
230
|
+
error=None,
|
|
231
|
+
)
|
|
232
|
+
yield Case(
|
|
233
|
+
stub="""
|
|
234
|
+
class X:
|
|
235
|
+
def f(self, number: int, text: str) -> None: ...
|
|
236
|
+
""",
|
|
237
|
+
runtime="""
|
|
238
|
+
class X:
|
|
239
|
+
def f(self, number, text): pass
|
|
240
|
+
""",
|
|
241
|
+
error=None,
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
@collect_cases
|
|
245
|
+
def test_types(self) -> Iterator[Case]:
|
|
246
|
+
yield Case(
|
|
247
|
+
stub="def mistyped_class() -> None: ...",
|
|
248
|
+
runtime="class mistyped_class: pass",
|
|
249
|
+
error="mistyped_class",
|
|
250
|
+
)
|
|
251
|
+
yield Case(
|
|
252
|
+
stub="class mistyped_fn: ...", runtime="def mistyped_fn(): pass", error="mistyped_fn"
|
|
253
|
+
)
|
|
254
|
+
yield Case(
|
|
255
|
+
stub="""
|
|
256
|
+
class X:
|
|
257
|
+
def mistyped_var(self) -> int: ...
|
|
258
|
+
""",
|
|
259
|
+
runtime="""
|
|
260
|
+
class X:
|
|
261
|
+
mistyped_var = 1
|
|
262
|
+
""",
|
|
263
|
+
error="X.mistyped_var",
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
@collect_cases
|
|
267
|
+
def test_coroutines(self) -> Iterator[Case]:
|
|
268
|
+
yield Case(stub="def bar() -> int: ...", runtime="async def bar(): return 5", error="bar")
|
|
269
|
+
# Don't error for this one -- we get false positives otherwise
|
|
270
|
+
yield Case(stub="async def foo() -> int: ...", runtime="def foo(): return 5", error=None)
|
|
271
|
+
yield Case(stub="def baz() -> int: ...", runtime="def baz(): return 5", error=None)
|
|
272
|
+
yield Case(
|
|
273
|
+
stub="async def bingo() -> int: ...", runtime="async def bingo(): return 5", error=None
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
@collect_cases
|
|
277
|
+
def test_arg_name(self) -> Iterator[Case]:
|
|
278
|
+
yield Case(
|
|
279
|
+
stub="def bad(number: int, text: str) -> None: ...",
|
|
280
|
+
runtime="def bad(num, text) -> None: pass",
|
|
281
|
+
error="bad",
|
|
282
|
+
)
|
|
283
|
+
yield Case(
|
|
284
|
+
stub="def good_posonly(__number: int, text: str) -> None: ...",
|
|
285
|
+
runtime="def good_posonly(num, /, text): pass",
|
|
286
|
+
error=None,
|
|
287
|
+
)
|
|
288
|
+
yield Case(
|
|
289
|
+
stub="def bad_posonly(__number: int, text: str) -> None: ...",
|
|
290
|
+
runtime="def bad_posonly(flag, /, text): pass",
|
|
291
|
+
error="bad_posonly",
|
|
292
|
+
)
|
|
293
|
+
yield Case(
|
|
294
|
+
stub="""
|
|
295
|
+
class BadMethod:
|
|
296
|
+
def f(self, number: int, text: str) -> None: ...
|
|
297
|
+
""",
|
|
298
|
+
runtime="""
|
|
299
|
+
class BadMethod:
|
|
300
|
+
def f(self, n, text): pass
|
|
301
|
+
""",
|
|
302
|
+
error="BadMethod.f",
|
|
303
|
+
)
|
|
304
|
+
yield Case(
|
|
305
|
+
stub="""
|
|
306
|
+
class GoodDunder:
|
|
307
|
+
def __exit__(self, t, v, tb) -> None: ...
|
|
308
|
+
""",
|
|
309
|
+
runtime="""
|
|
310
|
+
class GoodDunder:
|
|
311
|
+
def __exit__(self, exc_type, exc_val, exc_tb): pass
|
|
312
|
+
""",
|
|
313
|
+
error=None,
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
@collect_cases
|
|
317
|
+
def test_arg_kind(self) -> Iterator[Case]:
|
|
318
|
+
yield Case(
|
|
319
|
+
stub="def runtime_kwonly(number: int, text: str) -> None: ...",
|
|
320
|
+
runtime="def runtime_kwonly(number, *, text): pass",
|
|
321
|
+
error="runtime_kwonly",
|
|
322
|
+
)
|
|
323
|
+
yield Case(
|
|
324
|
+
stub="def stub_kwonly(number: int, *, text: str) -> None: ...",
|
|
325
|
+
runtime="def stub_kwonly(number, text): pass",
|
|
326
|
+
error="stub_kwonly",
|
|
327
|
+
)
|
|
328
|
+
yield Case(
|
|
329
|
+
stub="def stub_posonly(__number: int, text: str) -> None: ...",
|
|
330
|
+
runtime="def stub_posonly(number, text): pass",
|
|
331
|
+
error="stub_posonly",
|
|
332
|
+
)
|
|
333
|
+
yield Case(
|
|
334
|
+
stub="def good_posonly(__number: int, text: str) -> None: ...",
|
|
335
|
+
runtime="def good_posonly(number, /, text): pass",
|
|
336
|
+
error=None,
|
|
337
|
+
)
|
|
338
|
+
yield Case(
|
|
339
|
+
stub="def runtime_posonly(number: int, text: str) -> None: ...",
|
|
340
|
+
runtime="def runtime_posonly(number, /, text): pass",
|
|
341
|
+
error="runtime_posonly",
|
|
342
|
+
)
|
|
343
|
+
yield Case(
|
|
344
|
+
stub="def stub_posonly_570(number: int, /, text: str) -> None: ...",
|
|
345
|
+
runtime="def stub_posonly_570(number, text): pass",
|
|
346
|
+
error="stub_posonly_570",
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
@collect_cases
|
|
350
|
+
def test_private_parameters(self) -> Iterator[Case]:
|
|
351
|
+
# Private parameters can optionally be omitted.
|
|
352
|
+
yield Case(
|
|
353
|
+
stub="def priv_pos_arg_missing() -> None: ...",
|
|
354
|
+
runtime="def priv_pos_arg_missing(_p1=None): pass",
|
|
355
|
+
error=None,
|
|
356
|
+
)
|
|
357
|
+
yield Case(
|
|
358
|
+
stub="def multi_priv_args() -> None: ...",
|
|
359
|
+
runtime="def multi_priv_args(_p='', _q=''): pass",
|
|
360
|
+
error=None,
|
|
361
|
+
)
|
|
362
|
+
yield Case(
|
|
363
|
+
stub="def priv_kwarg_missing() -> None: ...",
|
|
364
|
+
runtime="def priv_kwarg_missing(*, _p2=''): pass",
|
|
365
|
+
error=None,
|
|
366
|
+
)
|
|
367
|
+
# But if they are included, they must be correct.
|
|
368
|
+
yield Case(
|
|
369
|
+
stub="def priv_pos_arg_wrong(_p: int = ...) -> None: ...",
|
|
370
|
+
runtime="def priv_pos_arg_wrong(_p=None): pass",
|
|
371
|
+
error="priv_pos_arg_wrong",
|
|
372
|
+
)
|
|
373
|
+
yield Case(
|
|
374
|
+
stub="def priv_kwarg_wrong(*, _p: int = ...) -> None: ...",
|
|
375
|
+
runtime="def priv_kwarg_wrong(*, _p=None): pass",
|
|
376
|
+
error="priv_kwarg_wrong",
|
|
377
|
+
)
|
|
378
|
+
# Private parameters must have a default and start with exactly one
|
|
379
|
+
# underscore.
|
|
380
|
+
yield Case(
|
|
381
|
+
stub="def pos_arg_no_default() -> None: ...",
|
|
382
|
+
runtime="def pos_arg_no_default(_np): pass",
|
|
383
|
+
error="pos_arg_no_default",
|
|
384
|
+
)
|
|
385
|
+
yield Case(
|
|
386
|
+
stub="def kwarg_no_default() -> None: ...",
|
|
387
|
+
runtime="def kwarg_no_default(*, _np): pass",
|
|
388
|
+
error="kwarg_no_default",
|
|
389
|
+
)
|
|
390
|
+
yield Case(
|
|
391
|
+
stub="def double_underscore_pos_arg() -> None: ...",
|
|
392
|
+
runtime="def double_underscore_pos_arg(__np = None): pass",
|
|
393
|
+
error="double_underscore_pos_arg",
|
|
394
|
+
)
|
|
395
|
+
yield Case(
|
|
396
|
+
stub="def double_underscore_kwarg() -> None: ...",
|
|
397
|
+
runtime="def double_underscore_kwarg(*, __np = None): pass",
|
|
398
|
+
error="double_underscore_kwarg",
|
|
399
|
+
)
|
|
400
|
+
# But spot parameters that are accidentally not marked kw-only and
|
|
401
|
+
# vice-versa.
|
|
402
|
+
yield Case(
|
|
403
|
+
stub="def priv_arg_is_kwonly(_p=...) -> None: ...",
|
|
404
|
+
runtime="def priv_arg_is_kwonly(*, _p=''): pass",
|
|
405
|
+
error="priv_arg_is_kwonly",
|
|
406
|
+
)
|
|
407
|
+
yield Case(
|
|
408
|
+
stub="def priv_arg_is_positional(*, _p=...) -> None: ...",
|
|
409
|
+
runtime="def priv_arg_is_positional(_p=''): pass",
|
|
410
|
+
error="priv_arg_is_positional",
|
|
411
|
+
)
|
|
412
|
+
# Private parameters not at the end of the parameter list must be
|
|
413
|
+
# included so that users can pass the following arguments using
|
|
414
|
+
# positional syntax.
|
|
415
|
+
yield Case(
|
|
416
|
+
stub="def priv_args_not_at_end(*, q='') -> None: ...",
|
|
417
|
+
runtime="def priv_args_not_at_end(_p='', q=''): pass",
|
|
418
|
+
error="priv_args_not_at_end",
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
@collect_cases
|
|
422
|
+
def test_default_presence(self) -> Iterator[Case]:
|
|
423
|
+
yield Case(
|
|
424
|
+
stub="def f1(text: str = ...) -> None: ...",
|
|
425
|
+
runtime="def f1(text = 'asdf'): pass",
|
|
426
|
+
error=None,
|
|
427
|
+
)
|
|
428
|
+
yield Case(
|
|
429
|
+
stub="def f2(text: str = ...) -> None: ...", runtime="def f2(text): pass", error="f2"
|
|
430
|
+
)
|
|
431
|
+
yield Case(
|
|
432
|
+
stub="def f3(text: str) -> None: ...",
|
|
433
|
+
runtime="def f3(text = 'asdf'): pass",
|
|
434
|
+
error="f3",
|
|
435
|
+
)
|
|
436
|
+
yield Case(
|
|
437
|
+
stub="def f4(text: str = ...) -> None: ...",
|
|
438
|
+
runtime="def f4(text = None): pass",
|
|
439
|
+
error="f4",
|
|
440
|
+
)
|
|
441
|
+
yield Case(
|
|
442
|
+
stub="def f5(data: bytes = ...) -> None: ...",
|
|
443
|
+
runtime="def f5(data = 'asdf'): pass",
|
|
444
|
+
error="f5",
|
|
445
|
+
)
|
|
446
|
+
yield Case(
|
|
447
|
+
stub="""
|
|
448
|
+
from typing import TypeVar
|
|
449
|
+
_T = TypeVar("_T", bound=str)
|
|
450
|
+
def f6(text: _T = ...) -> None: ...
|
|
451
|
+
""",
|
|
452
|
+
runtime="def f6(text = None): pass",
|
|
453
|
+
error="f6",
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
@collect_cases
|
|
457
|
+
def test_default_value(self) -> Iterator[Case]:
|
|
458
|
+
yield Case(
|
|
459
|
+
stub="def f1(text: str = 'x') -> None: ...",
|
|
460
|
+
runtime="def f1(text = 'y'): pass",
|
|
461
|
+
error="f1",
|
|
462
|
+
)
|
|
463
|
+
yield Case(
|
|
464
|
+
stub='def f2(text: bytes = b"x\'") -> None: ...',
|
|
465
|
+
runtime='def f2(text = b"x\'"): pass',
|
|
466
|
+
error=None,
|
|
467
|
+
)
|
|
468
|
+
yield Case(
|
|
469
|
+
stub='def f3(text: bytes = b"y\'") -> None: ...',
|
|
470
|
+
runtime='def f3(text = b"x\'"): pass',
|
|
471
|
+
error="f3",
|
|
472
|
+
)
|
|
473
|
+
yield Case(
|
|
474
|
+
stub="def f4(text: object = 1) -> None: ...",
|
|
475
|
+
runtime="def f4(text = 1.0): pass",
|
|
476
|
+
error="f4",
|
|
477
|
+
)
|
|
478
|
+
yield Case(
|
|
479
|
+
stub="def f5(text: object = True) -> None: ...",
|
|
480
|
+
runtime="def f5(text = 1): pass",
|
|
481
|
+
error="f5",
|
|
482
|
+
)
|
|
483
|
+
yield Case(
|
|
484
|
+
stub="def f6(text: object = True) -> None: ...",
|
|
485
|
+
runtime="def f6(text = True): pass",
|
|
486
|
+
error=None,
|
|
487
|
+
)
|
|
488
|
+
yield Case(
|
|
489
|
+
stub="def f7(text: object = not True) -> None: ...",
|
|
490
|
+
runtime="def f7(text = False): pass",
|
|
491
|
+
error=None,
|
|
492
|
+
)
|
|
493
|
+
yield Case(
|
|
494
|
+
stub="def f8(text: object = not True) -> None: ...",
|
|
495
|
+
runtime="def f8(text = True): pass",
|
|
496
|
+
error="f8",
|
|
497
|
+
)
|
|
498
|
+
yield Case(
|
|
499
|
+
stub="def f9(text: object = {1: 2}) -> None: ...",
|
|
500
|
+
runtime="def f9(text = {1: 3}): pass",
|
|
501
|
+
error="f9",
|
|
502
|
+
)
|
|
503
|
+
yield Case(
|
|
504
|
+
stub="def f10(text: object = [1, 2]) -> None: ...",
|
|
505
|
+
runtime="def f10(text = [1, 2]): pass",
|
|
506
|
+
error=None,
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
# Simulate "<unrepresentable>"
|
|
510
|
+
yield Case(
|
|
511
|
+
stub="def f11() -> None: ...",
|
|
512
|
+
runtime="""
|
|
513
|
+
def f11(text=None) -> None: pass
|
|
514
|
+
f11.__text_signature__ = "(text=<unrepresentable>)"
|
|
515
|
+
""",
|
|
516
|
+
error="f11",
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
@collect_cases
|
|
520
|
+
def test_static_class_method(self) -> Iterator[Case]:
|
|
521
|
+
yield Case(
|
|
522
|
+
stub="""
|
|
523
|
+
class Good:
|
|
524
|
+
@classmethod
|
|
525
|
+
def f(cls, number: int, text: str) -> None: ...
|
|
526
|
+
""",
|
|
527
|
+
runtime="""
|
|
528
|
+
class Good:
|
|
529
|
+
@classmethod
|
|
530
|
+
def f(cls, number, text): pass
|
|
531
|
+
""",
|
|
532
|
+
error=None,
|
|
533
|
+
)
|
|
534
|
+
yield Case(
|
|
535
|
+
stub="""
|
|
536
|
+
class Bad1:
|
|
537
|
+
def f(cls, number: int, text: str) -> None: ...
|
|
538
|
+
""",
|
|
539
|
+
runtime="""
|
|
540
|
+
class Bad1:
|
|
541
|
+
@classmethod
|
|
542
|
+
def f(cls, number, text): pass
|
|
543
|
+
""",
|
|
544
|
+
error="Bad1.f",
|
|
545
|
+
)
|
|
546
|
+
yield Case(
|
|
547
|
+
stub="""
|
|
548
|
+
class Bad2:
|
|
549
|
+
@classmethod
|
|
550
|
+
def f(cls, number: int, text: str) -> None: ...
|
|
551
|
+
""",
|
|
552
|
+
runtime="""
|
|
553
|
+
class Bad2:
|
|
554
|
+
@staticmethod
|
|
555
|
+
def f(self, number, text): pass
|
|
556
|
+
""",
|
|
557
|
+
error="Bad2.f",
|
|
558
|
+
)
|
|
559
|
+
yield Case(
|
|
560
|
+
stub="""
|
|
561
|
+
class Bad3:
|
|
562
|
+
@staticmethod
|
|
563
|
+
def f(cls, number: int, text: str) -> None: ...
|
|
564
|
+
""",
|
|
565
|
+
runtime="""
|
|
566
|
+
class Bad3:
|
|
567
|
+
@classmethod
|
|
568
|
+
def f(self, number, text): pass
|
|
569
|
+
""",
|
|
570
|
+
error="Bad3.f",
|
|
571
|
+
)
|
|
572
|
+
yield Case(
|
|
573
|
+
stub="""
|
|
574
|
+
class GoodNew:
|
|
575
|
+
def __new__(cls, *args, **kwargs): ...
|
|
576
|
+
""",
|
|
577
|
+
runtime="""
|
|
578
|
+
class GoodNew:
|
|
579
|
+
def __new__(cls, *args, **kwargs): pass
|
|
580
|
+
""",
|
|
581
|
+
error=None,
|
|
582
|
+
)
|
|
583
|
+
|
|
584
|
+
@collect_cases
|
|
585
|
+
def test_arg_mismatch(self) -> Iterator[Case]:
|
|
586
|
+
yield Case(
|
|
587
|
+
stub="def f1(a, *, b, c) -> None: ...", runtime="def f1(a, *, b, c): pass", error=None
|
|
588
|
+
)
|
|
589
|
+
yield Case(
|
|
590
|
+
stub="def f2(a, *, b) -> None: ...", runtime="def f2(a, *, b, c): pass", error="f2"
|
|
591
|
+
)
|
|
592
|
+
yield Case(
|
|
593
|
+
stub="def f3(a, *, b, c) -> None: ...", runtime="def f3(a, *, b): pass", error="f3"
|
|
594
|
+
)
|
|
595
|
+
yield Case(
|
|
596
|
+
stub="def f4(a, *, b, c) -> None: ...", runtime="def f4(a, b, *, c): pass", error="f4"
|
|
597
|
+
)
|
|
598
|
+
yield Case(
|
|
599
|
+
stub="def f5(a, b, *, c) -> None: ...", runtime="def f5(a, *, b, c): pass", error="f5"
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
@collect_cases
|
|
603
|
+
def test_varargs_varkwargs(self) -> Iterator[Case]:
|
|
604
|
+
yield Case(
|
|
605
|
+
stub="def f1(*args, **kwargs) -> None: ...",
|
|
606
|
+
runtime="def f1(*args, **kwargs): pass",
|
|
607
|
+
error=None,
|
|
608
|
+
)
|
|
609
|
+
yield Case(
|
|
610
|
+
stub="def f2(*args, **kwargs) -> None: ...",
|
|
611
|
+
runtime="def f2(**kwargs): pass",
|
|
612
|
+
error="f2",
|
|
613
|
+
)
|
|
614
|
+
yield Case(
|
|
615
|
+
stub="def g1(a, b, c, d) -> None: ...", runtime="def g1(a, *args): pass", error=None
|
|
616
|
+
)
|
|
617
|
+
yield Case(
|
|
618
|
+
stub="def g2(a, b, c, d, *args) -> None: ...", runtime="def g2(a): pass", error="g2"
|
|
619
|
+
)
|
|
620
|
+
yield Case(
|
|
621
|
+
stub="def g3(a, b, c, d, *args) -> None: ...",
|
|
622
|
+
runtime="def g3(a, *args): pass",
|
|
623
|
+
error=None,
|
|
624
|
+
)
|
|
625
|
+
yield Case(
|
|
626
|
+
stub="def h1(a) -> None: ...", runtime="def h1(a, b, c, d, *args): pass", error="h1"
|
|
627
|
+
)
|
|
628
|
+
yield Case(
|
|
629
|
+
stub="def h2(a, *args) -> None: ...", runtime="def h2(a, b, c, d): pass", error="h2"
|
|
630
|
+
)
|
|
631
|
+
yield Case(
|
|
632
|
+
stub="def h3(a, *args) -> None: ...",
|
|
633
|
+
runtime="def h3(a, b, c, d, *args): pass",
|
|
634
|
+
error="h3",
|
|
635
|
+
)
|
|
636
|
+
yield Case(
|
|
637
|
+
stub="def j1(a: int, *args) -> None: ...", runtime="def j1(a): pass", error="j1"
|
|
638
|
+
)
|
|
639
|
+
yield Case(
|
|
640
|
+
stub="def j2(a: int) -> None: ...", runtime="def j2(a, *args): pass", error="j2"
|
|
641
|
+
)
|
|
642
|
+
yield Case(
|
|
643
|
+
stub="def j3(a, b, c) -> None: ...", runtime="def j3(a, *args, c): pass", error="j3"
|
|
644
|
+
)
|
|
645
|
+
yield Case(stub="def k1(a, **kwargs) -> None: ...", runtime="def k1(a): pass", error="k1")
|
|
646
|
+
yield Case(
|
|
647
|
+
# In theory an error, but led to worse results in practice
|
|
648
|
+
stub="def k2(a) -> None: ...",
|
|
649
|
+
runtime="def k2(a, **kwargs): pass",
|
|
650
|
+
error=None,
|
|
651
|
+
)
|
|
652
|
+
yield Case(
|
|
653
|
+
stub="def k3(a, b) -> None: ...", runtime="def k3(a, **kwargs): pass", error="k3"
|
|
654
|
+
)
|
|
655
|
+
yield Case(
|
|
656
|
+
stub="def k4(a, *, b) -> None: ...", runtime="def k4(a, **kwargs): pass", error=None
|
|
657
|
+
)
|
|
658
|
+
yield Case(
|
|
659
|
+
stub="def k5(a, *, b) -> None: ...",
|
|
660
|
+
runtime="def k5(a, *, b, c, **kwargs): pass",
|
|
661
|
+
error="k5",
|
|
662
|
+
)
|
|
663
|
+
yield Case(
|
|
664
|
+
stub="def k6(a, *, b, **kwargs) -> None: ...",
|
|
665
|
+
runtime="def k6(a, *, b, c, **kwargs): pass",
|
|
666
|
+
error="k6",
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
@collect_cases
|
|
670
|
+
def test_overload(self) -> Iterator[Case]:
|
|
671
|
+
yield Case(
|
|
672
|
+
stub="""
|
|
673
|
+
from typing import overload
|
|
674
|
+
|
|
675
|
+
@overload
|
|
676
|
+
def f1(a: int, *, c: int = ...) -> int: ...
|
|
677
|
+
@overload
|
|
678
|
+
def f1(a: int, b: int, c: int = ...) -> str: ...
|
|
679
|
+
""",
|
|
680
|
+
runtime="def f1(a, b = 0, c = 0): pass",
|
|
681
|
+
error=None,
|
|
682
|
+
)
|
|
683
|
+
yield Case(
|
|
684
|
+
stub="""
|
|
685
|
+
@overload
|
|
686
|
+
def f2(a: int, *, c: int = ...) -> int: ...
|
|
687
|
+
@overload
|
|
688
|
+
def f2(a: int, b: int, c: int = ...) -> str: ...
|
|
689
|
+
""",
|
|
690
|
+
runtime="def f2(a, b, c = 0): pass",
|
|
691
|
+
error="f2",
|
|
692
|
+
)
|
|
693
|
+
yield Case(
|
|
694
|
+
stub="""
|
|
695
|
+
@overload
|
|
696
|
+
def f3(a: int) -> int: ...
|
|
697
|
+
@overload
|
|
698
|
+
def f3(a: int, b: str) -> str: ...
|
|
699
|
+
""",
|
|
700
|
+
runtime="def f3(a, b = None): pass",
|
|
701
|
+
error="f3",
|
|
702
|
+
)
|
|
703
|
+
yield Case(
|
|
704
|
+
stub="""
|
|
705
|
+
@overload
|
|
706
|
+
def f4(a: int, *args, b: int, **kwargs) -> int: ...
|
|
707
|
+
@overload
|
|
708
|
+
def f4(a: str, *args, b: int, **kwargs) -> str: ...
|
|
709
|
+
""",
|
|
710
|
+
runtime="def f4(a, *args, b, **kwargs): pass",
|
|
711
|
+
error=None,
|
|
712
|
+
)
|
|
713
|
+
yield Case(
|
|
714
|
+
stub="""
|
|
715
|
+
@overload
|
|
716
|
+
def f5(__a: int) -> int: ...
|
|
717
|
+
@overload
|
|
718
|
+
def f5(__b: str) -> str: ...
|
|
719
|
+
""",
|
|
720
|
+
runtime="def f5(x, /): pass",
|
|
721
|
+
error=None,
|
|
722
|
+
)
|
|
723
|
+
yield Case(
|
|
724
|
+
stub="""
|
|
725
|
+
from typing import final
|
|
726
|
+
from typing_extensions import deprecated
|
|
727
|
+
class Foo:
|
|
728
|
+
@overload
|
|
729
|
+
@final
|
|
730
|
+
def f6(self, __a: int) -> int: ...
|
|
731
|
+
@overload
|
|
732
|
+
@deprecated("evil")
|
|
733
|
+
def f6(self, __b: str) -> str: ...
|
|
734
|
+
""",
|
|
735
|
+
runtime="""
|
|
736
|
+
class Foo:
|
|
737
|
+
def f6(self, x, /): pass
|
|
738
|
+
""",
|
|
739
|
+
error=None,
|
|
740
|
+
)
|
|
741
|
+
yield Case(
|
|
742
|
+
stub="""
|
|
743
|
+
@overload
|
|
744
|
+
def f7(a: int, /) -> int: ...
|
|
745
|
+
@overload
|
|
746
|
+
def f7(b: str, /) -> str: ...
|
|
747
|
+
""",
|
|
748
|
+
runtime="def f7(x, /): pass",
|
|
749
|
+
error=None,
|
|
750
|
+
)
|
|
751
|
+
yield Case(
|
|
752
|
+
stub="""
|
|
753
|
+
@overload
|
|
754
|
+
def f8(a: int, c: int = 0, /) -> int: ...
|
|
755
|
+
@overload
|
|
756
|
+
def f8(b: str, d: int, /) -> str: ...
|
|
757
|
+
""",
|
|
758
|
+
runtime="def f8(x, y, /): pass",
|
|
759
|
+
error="f8",
|
|
760
|
+
)
|
|
761
|
+
yield Case(
|
|
762
|
+
stub="""
|
|
763
|
+
@overload
|
|
764
|
+
def f9(a: int, c: int = 0, /) -> int: ...
|
|
765
|
+
@overload
|
|
766
|
+
def f9(b: str, d: int, /) -> str: ...
|
|
767
|
+
""",
|
|
768
|
+
runtime="def f9(x, y=0, /): pass",
|
|
769
|
+
error=None,
|
|
770
|
+
)
|
|
771
|
+
yield Case(
|
|
772
|
+
stub="""
|
|
773
|
+
class Bar:
|
|
774
|
+
@overload
|
|
775
|
+
def f1(self) -> int: ...
|
|
776
|
+
@overload
|
|
777
|
+
def f1(self, a: int, /) -> int: ...
|
|
778
|
+
|
|
779
|
+
@overload
|
|
780
|
+
def f2(self, a: int, /) -> int: ...
|
|
781
|
+
@overload
|
|
782
|
+
def f2(self, a: str, /) -> int: ...
|
|
783
|
+
""",
|
|
784
|
+
runtime="""
|
|
785
|
+
class Bar:
|
|
786
|
+
def f1(self, *a) -> int: ...
|
|
787
|
+
def f2(self, *a) -> int: ...
|
|
788
|
+
""",
|
|
789
|
+
error=None,
|
|
790
|
+
)
|
|
791
|
+
|
|
792
|
+
@collect_cases
|
|
793
|
+
def test_property(self) -> Iterator[Case]:
|
|
794
|
+
yield Case(
|
|
795
|
+
stub="""
|
|
796
|
+
class Good:
|
|
797
|
+
@property
|
|
798
|
+
def read_only_attr(self) -> int: ...
|
|
799
|
+
""",
|
|
800
|
+
runtime="""
|
|
801
|
+
class Good:
|
|
802
|
+
@property
|
|
803
|
+
def read_only_attr(self): return 1
|
|
804
|
+
""",
|
|
805
|
+
error=None,
|
|
806
|
+
)
|
|
807
|
+
yield Case(
|
|
808
|
+
stub="""
|
|
809
|
+
class Bad:
|
|
810
|
+
@property
|
|
811
|
+
def f(self) -> int: ...
|
|
812
|
+
""",
|
|
813
|
+
runtime="""
|
|
814
|
+
class Bad:
|
|
815
|
+
def f(self) -> int: return 1
|
|
816
|
+
""",
|
|
817
|
+
error="Bad.f",
|
|
818
|
+
)
|
|
819
|
+
yield Case(
|
|
820
|
+
stub="""
|
|
821
|
+
class GoodReadOnly:
|
|
822
|
+
@property
|
|
823
|
+
def f(self) -> int: ...
|
|
824
|
+
""",
|
|
825
|
+
runtime="""
|
|
826
|
+
class GoodReadOnly:
|
|
827
|
+
f = 1
|
|
828
|
+
""",
|
|
829
|
+
error=None,
|
|
830
|
+
)
|
|
831
|
+
yield Case(
|
|
832
|
+
stub="""
|
|
833
|
+
class BadReadOnly:
|
|
834
|
+
@property
|
|
835
|
+
def f(self) -> str: ...
|
|
836
|
+
""",
|
|
837
|
+
runtime="""
|
|
838
|
+
class BadReadOnly:
|
|
839
|
+
f = 1
|
|
840
|
+
""",
|
|
841
|
+
error="BadReadOnly.f",
|
|
842
|
+
)
|
|
843
|
+
yield Case(
|
|
844
|
+
stub="""
|
|
845
|
+
class Y:
|
|
846
|
+
@property
|
|
847
|
+
def read_only_attr(self) -> int: ...
|
|
848
|
+
@read_only_attr.setter
|
|
849
|
+
def read_only_attr(self, val: int) -> None: ...
|
|
850
|
+
""",
|
|
851
|
+
runtime="""
|
|
852
|
+
class Y:
|
|
853
|
+
@property
|
|
854
|
+
def read_only_attr(self): return 5
|
|
855
|
+
""",
|
|
856
|
+
error="Y.read_only_attr",
|
|
857
|
+
)
|
|
858
|
+
yield Case(
|
|
859
|
+
stub="""
|
|
860
|
+
class Z:
|
|
861
|
+
@property
|
|
862
|
+
def read_write_attr(self) -> int: ...
|
|
863
|
+
@read_write_attr.setter
|
|
864
|
+
def read_write_attr(self, val: int) -> None: ...
|
|
865
|
+
""",
|
|
866
|
+
runtime="""
|
|
867
|
+
class Z:
|
|
868
|
+
@property
|
|
869
|
+
def read_write_attr(self): return self._val
|
|
870
|
+
@read_write_attr.setter
|
|
871
|
+
def read_write_attr(self, val): self._val = val
|
|
872
|
+
""",
|
|
873
|
+
error=None,
|
|
874
|
+
)
|
|
875
|
+
yield Case(
|
|
876
|
+
stub="""
|
|
877
|
+
class FineAndDandy:
|
|
878
|
+
@property
|
|
879
|
+
def attr(self) -> int: ...
|
|
880
|
+
""",
|
|
881
|
+
runtime="""
|
|
882
|
+
class _EvilDescriptor:
|
|
883
|
+
def __get__(self, instance, ownerclass=None):
|
|
884
|
+
if instance is None:
|
|
885
|
+
raise AttributeError('no')
|
|
886
|
+
return 42
|
|
887
|
+
def __set__(self, instance, value):
|
|
888
|
+
raise AttributeError('no')
|
|
889
|
+
|
|
890
|
+
class FineAndDandy:
|
|
891
|
+
attr = _EvilDescriptor()
|
|
892
|
+
""",
|
|
893
|
+
error=None,
|
|
894
|
+
)
|
|
895
|
+
|
|
896
|
+
@collect_cases
|
|
897
|
+
def test_var(self) -> Iterator[Case]:
|
|
898
|
+
yield Case(stub="x1: int", runtime="x1 = 5", error=None)
|
|
899
|
+
yield Case(stub="x2: str", runtime="x2 = 5", error="x2")
|
|
900
|
+
yield Case("from typing import Tuple", "", None) # dummy case
|
|
901
|
+
yield Case(
|
|
902
|
+
stub="""
|
|
903
|
+
x3: Tuple[int, int]
|
|
904
|
+
""",
|
|
905
|
+
runtime="x3 = (1, 3)",
|
|
906
|
+
error=None,
|
|
907
|
+
)
|
|
908
|
+
yield Case(
|
|
909
|
+
stub="""
|
|
910
|
+
x4: Tuple[int, int]
|
|
911
|
+
""",
|
|
912
|
+
runtime="x4 = (1, 3, 5)",
|
|
913
|
+
error="x4",
|
|
914
|
+
)
|
|
915
|
+
yield Case(stub="x5: int", runtime="def x5(a, b): pass", error="x5")
|
|
916
|
+
yield Case(
|
|
917
|
+
stub="def foo(a: int, b: int) -> None: ...\nx6 = foo",
|
|
918
|
+
runtime="def foo(a, b): pass\ndef x6(c, d): pass",
|
|
919
|
+
error="x6",
|
|
920
|
+
)
|
|
921
|
+
yield Case(
|
|
922
|
+
stub="""
|
|
923
|
+
class X:
|
|
924
|
+
f: int
|
|
925
|
+
""",
|
|
926
|
+
runtime="""
|
|
927
|
+
class X:
|
|
928
|
+
def __init__(self):
|
|
929
|
+
self.f = "asdf"
|
|
930
|
+
""",
|
|
931
|
+
error=None,
|
|
932
|
+
)
|
|
933
|
+
yield Case(
|
|
934
|
+
stub="""
|
|
935
|
+
class Y:
|
|
936
|
+
read_only_attr: int
|
|
937
|
+
""",
|
|
938
|
+
runtime="""
|
|
939
|
+
class Y:
|
|
940
|
+
@property
|
|
941
|
+
def read_only_attr(self): return 5
|
|
942
|
+
""",
|
|
943
|
+
error="Y.read_only_attr",
|
|
944
|
+
)
|
|
945
|
+
yield Case(
|
|
946
|
+
stub="""
|
|
947
|
+
class Z:
|
|
948
|
+
read_write_attr: int
|
|
949
|
+
""",
|
|
950
|
+
runtime="""
|
|
951
|
+
class Z:
|
|
952
|
+
@property
|
|
953
|
+
def read_write_attr(self): return self._val
|
|
954
|
+
@read_write_attr.setter
|
|
955
|
+
def read_write_attr(self, val): self._val = val
|
|
956
|
+
""",
|
|
957
|
+
error=None,
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
@collect_cases
|
|
961
|
+
def test_type_alias(self) -> Iterator[Case]:
|
|
962
|
+
yield Case(
|
|
963
|
+
stub="""
|
|
964
|
+
import collections.abc
|
|
965
|
+
import re
|
|
966
|
+
import typing
|
|
967
|
+
from typing import Callable, Dict, Generic, Iterable, List, Match, Tuple, TypeVar, Union
|
|
968
|
+
""",
|
|
969
|
+
runtime="""
|
|
970
|
+
import collections.abc
|
|
971
|
+
import re
|
|
972
|
+
from typing import Callable, Dict, Generic, Iterable, List, Match, Tuple, TypeVar, Union
|
|
973
|
+
""",
|
|
974
|
+
error=None,
|
|
975
|
+
)
|
|
976
|
+
yield Case(
|
|
977
|
+
stub="""
|
|
978
|
+
class X:
|
|
979
|
+
def f(self) -> None: ...
|
|
980
|
+
Y = X
|
|
981
|
+
""",
|
|
982
|
+
runtime="""
|
|
983
|
+
class X:
|
|
984
|
+
def f(self) -> None: ...
|
|
985
|
+
class Y: ...
|
|
986
|
+
""",
|
|
987
|
+
error="Y.f",
|
|
988
|
+
)
|
|
989
|
+
yield Case(stub="A = Tuple[int, str]", runtime="A = (int, str)", error="A")
|
|
990
|
+
# Error if an alias isn't present at runtime...
|
|
991
|
+
yield Case(stub="B = str", runtime="", error="B")
|
|
992
|
+
# ... but only if the alias isn't private
|
|
993
|
+
yield Case(stub="_C = int", runtime="", error=None)
|
|
994
|
+
yield Case(
|
|
995
|
+
stub="""
|
|
996
|
+
D = tuple[str, str]
|
|
997
|
+
E = Tuple[int, int, int]
|
|
998
|
+
F = Tuple[str, int]
|
|
999
|
+
""",
|
|
1000
|
+
runtime="""
|
|
1001
|
+
D = Tuple[str, str]
|
|
1002
|
+
E = Tuple[int, int, int]
|
|
1003
|
+
F = List[str]
|
|
1004
|
+
""",
|
|
1005
|
+
error="F",
|
|
1006
|
+
)
|
|
1007
|
+
yield Case(
|
|
1008
|
+
stub="""
|
|
1009
|
+
G = str | int
|
|
1010
|
+
H = Union[str, bool]
|
|
1011
|
+
I = str | int
|
|
1012
|
+
""",
|
|
1013
|
+
runtime="""
|
|
1014
|
+
G = Union[str, int]
|
|
1015
|
+
H = Union[str, bool]
|
|
1016
|
+
I = str
|
|
1017
|
+
""",
|
|
1018
|
+
error="I",
|
|
1019
|
+
)
|
|
1020
|
+
yield Case(
|
|
1021
|
+
stub="""
|
|
1022
|
+
K = dict[str, str]
|
|
1023
|
+
L = Dict[int, int]
|
|
1024
|
+
KK = collections.abc.Iterable[str]
|
|
1025
|
+
LL = typing.Iterable[str]
|
|
1026
|
+
""",
|
|
1027
|
+
runtime="""
|
|
1028
|
+
K = Dict[str, str]
|
|
1029
|
+
L = Dict[int, int]
|
|
1030
|
+
KK = Iterable[str]
|
|
1031
|
+
LL = Iterable[str]
|
|
1032
|
+
""",
|
|
1033
|
+
error=None,
|
|
1034
|
+
)
|
|
1035
|
+
yield Case(
|
|
1036
|
+
stub="""
|
|
1037
|
+
_T = TypeVar("_T")
|
|
1038
|
+
class _Spam(Generic[_T]):
|
|
1039
|
+
def foo(self) -> None: ...
|
|
1040
|
+
IntFood = _Spam[int]
|
|
1041
|
+
""",
|
|
1042
|
+
runtime="""
|
|
1043
|
+
_T = TypeVar("_T")
|
|
1044
|
+
class _Bacon(Generic[_T]):
|
|
1045
|
+
def foo(self, arg): pass
|
|
1046
|
+
IntFood = _Bacon[int]
|
|
1047
|
+
""",
|
|
1048
|
+
error="IntFood.foo",
|
|
1049
|
+
)
|
|
1050
|
+
yield Case(stub="StrList = list[str]", runtime="StrList = ['foo', 'bar']", error="StrList")
|
|
1051
|
+
yield Case(
|
|
1052
|
+
stub="""
|
|
1053
|
+
N = typing.Callable[[str], bool]
|
|
1054
|
+
O = collections.abc.Callable[[int], str]
|
|
1055
|
+
P = typing.Callable[[str], bool]
|
|
1056
|
+
""",
|
|
1057
|
+
runtime="""
|
|
1058
|
+
N = Callable[[str], bool]
|
|
1059
|
+
O = Callable[[int], str]
|
|
1060
|
+
P = int
|
|
1061
|
+
""",
|
|
1062
|
+
error="P",
|
|
1063
|
+
)
|
|
1064
|
+
yield Case(
|
|
1065
|
+
stub="""
|
|
1066
|
+
class Foo:
|
|
1067
|
+
class Bar: ...
|
|
1068
|
+
BarAlias = Foo.Bar
|
|
1069
|
+
""",
|
|
1070
|
+
runtime="""
|
|
1071
|
+
class Foo:
|
|
1072
|
+
class Bar: pass
|
|
1073
|
+
BarAlias = Foo.Bar
|
|
1074
|
+
""",
|
|
1075
|
+
error=None,
|
|
1076
|
+
)
|
|
1077
|
+
yield Case(
|
|
1078
|
+
stub="""
|
|
1079
|
+
from io import StringIO
|
|
1080
|
+
StringIOAlias = StringIO
|
|
1081
|
+
""",
|
|
1082
|
+
runtime="""
|
|
1083
|
+
from _io import StringIO
|
|
1084
|
+
StringIOAlias = StringIO
|
|
1085
|
+
""",
|
|
1086
|
+
error=None,
|
|
1087
|
+
)
|
|
1088
|
+
yield Case(stub="M = Match[str]", runtime="M = Match[str]", error=None)
|
|
1089
|
+
yield Case(
|
|
1090
|
+
stub="""
|
|
1091
|
+
class Baz:
|
|
1092
|
+
def fizz(self) -> None: ...
|
|
1093
|
+
BazAlias = Baz
|
|
1094
|
+
""",
|
|
1095
|
+
runtime="""
|
|
1096
|
+
class Baz:
|
|
1097
|
+
def fizz(self): pass
|
|
1098
|
+
BazAlias = Baz
|
|
1099
|
+
Baz.__name__ = Baz.__qualname__ = Baz.__module__ = "New"
|
|
1100
|
+
""",
|
|
1101
|
+
error=None,
|
|
1102
|
+
)
|
|
1103
|
+
yield Case(
|
|
1104
|
+
stub="""
|
|
1105
|
+
class FooBar:
|
|
1106
|
+
__module__: None # type: ignore
|
|
1107
|
+
def fizz(self) -> None: ...
|
|
1108
|
+
FooBarAlias = FooBar
|
|
1109
|
+
""",
|
|
1110
|
+
runtime="""
|
|
1111
|
+
class FooBar:
|
|
1112
|
+
def fizz(self): pass
|
|
1113
|
+
FooBarAlias = FooBar
|
|
1114
|
+
FooBar.__module__ = None
|
|
1115
|
+
""",
|
|
1116
|
+
error=None,
|
|
1117
|
+
)
|
|
1118
|
+
if sys.version_info >= (3, 10):
|
|
1119
|
+
yield Case(
|
|
1120
|
+
stub="""
|
|
1121
|
+
Q = Dict[str, str]
|
|
1122
|
+
R = dict[int, int]
|
|
1123
|
+
S = Tuple[int, int]
|
|
1124
|
+
T = tuple[str, str]
|
|
1125
|
+
U = int | str
|
|
1126
|
+
V = Union[int, str]
|
|
1127
|
+
W = typing.Callable[[str], bool]
|
|
1128
|
+
Z = collections.abc.Callable[[str], bool]
|
|
1129
|
+
QQ = typing.Iterable[str]
|
|
1130
|
+
RR = collections.abc.Iterable[str]
|
|
1131
|
+
MM = typing.Match[str]
|
|
1132
|
+
MMM = re.Match[str]
|
|
1133
|
+
""",
|
|
1134
|
+
runtime="""
|
|
1135
|
+
Q = dict[str, str]
|
|
1136
|
+
R = dict[int, int]
|
|
1137
|
+
S = tuple[int, int]
|
|
1138
|
+
T = tuple[str, str]
|
|
1139
|
+
U = int | str
|
|
1140
|
+
V = int | str
|
|
1141
|
+
W = collections.abc.Callable[[str], bool]
|
|
1142
|
+
Z = collections.abc.Callable[[str], bool]
|
|
1143
|
+
QQ = collections.abc.Iterable[str]
|
|
1144
|
+
RR = collections.abc.Iterable[str]
|
|
1145
|
+
MM = re.Match[str]
|
|
1146
|
+
MMM = re.Match[str]
|
|
1147
|
+
""",
|
|
1148
|
+
error=None,
|
|
1149
|
+
)
|
|
1150
|
+
|
|
1151
|
+
@collect_cases
|
|
1152
|
+
def test_enum(self) -> Iterator[Case]:
|
|
1153
|
+
yield Case(stub="import enum", runtime="import enum", error=None)
|
|
1154
|
+
yield Case(
|
|
1155
|
+
stub="""
|
|
1156
|
+
class X(enum.Enum):
|
|
1157
|
+
a: int
|
|
1158
|
+
b: str
|
|
1159
|
+
c: str
|
|
1160
|
+
""",
|
|
1161
|
+
runtime="""
|
|
1162
|
+
class X(enum.Enum):
|
|
1163
|
+
a = 1
|
|
1164
|
+
b = "asdf"
|
|
1165
|
+
c = 2
|
|
1166
|
+
""",
|
|
1167
|
+
error="X.c",
|
|
1168
|
+
)
|
|
1169
|
+
yield Case(
|
|
1170
|
+
stub="""
|
|
1171
|
+
class Flags1(enum.Flag):
|
|
1172
|
+
a: int
|
|
1173
|
+
b: int
|
|
1174
|
+
def foo(x: Flags1 = ...) -> None: ...
|
|
1175
|
+
""",
|
|
1176
|
+
runtime="""
|
|
1177
|
+
class Flags1(enum.Flag):
|
|
1178
|
+
a = 1
|
|
1179
|
+
b = 2
|
|
1180
|
+
def foo(x=Flags1.a|Flags1.b): pass
|
|
1181
|
+
""",
|
|
1182
|
+
error=None,
|
|
1183
|
+
)
|
|
1184
|
+
yield Case(
|
|
1185
|
+
stub="""
|
|
1186
|
+
class Flags2(enum.Flag):
|
|
1187
|
+
a: int
|
|
1188
|
+
b: int
|
|
1189
|
+
def bar(x: Flags2 | None = None) -> None: ...
|
|
1190
|
+
""",
|
|
1191
|
+
runtime="""
|
|
1192
|
+
class Flags2(enum.Flag):
|
|
1193
|
+
a = 1
|
|
1194
|
+
b = 2
|
|
1195
|
+
def bar(x=Flags2.a|Flags2.b): pass
|
|
1196
|
+
""",
|
|
1197
|
+
error="bar",
|
|
1198
|
+
)
|
|
1199
|
+
yield Case(
|
|
1200
|
+
stub="""
|
|
1201
|
+
class Flags3(enum.Flag):
|
|
1202
|
+
a: int
|
|
1203
|
+
b: int
|
|
1204
|
+
def baz(x: Flags3 | None = ...) -> None: ...
|
|
1205
|
+
""",
|
|
1206
|
+
runtime="""
|
|
1207
|
+
class Flags3(enum.Flag):
|
|
1208
|
+
a = 1
|
|
1209
|
+
b = 2
|
|
1210
|
+
def baz(x=Flags3(0)): pass
|
|
1211
|
+
""",
|
|
1212
|
+
error=None,
|
|
1213
|
+
)
|
|
1214
|
+
yield Case(
|
|
1215
|
+
runtime="""
|
|
1216
|
+
import enum
|
|
1217
|
+
class SomeObject: ...
|
|
1218
|
+
|
|
1219
|
+
class WeirdEnum(enum.Enum):
|
|
1220
|
+
a = SomeObject()
|
|
1221
|
+
b = SomeObject()
|
|
1222
|
+
""",
|
|
1223
|
+
stub="""
|
|
1224
|
+
import enum
|
|
1225
|
+
class SomeObject: ...
|
|
1226
|
+
class WeirdEnum(enum.Enum):
|
|
1227
|
+
_value_: SomeObject
|
|
1228
|
+
a = ...
|
|
1229
|
+
b = ...
|
|
1230
|
+
""",
|
|
1231
|
+
error=None,
|
|
1232
|
+
)
|
|
1233
|
+
yield Case(
|
|
1234
|
+
stub="""
|
|
1235
|
+
class Flags4(enum.Flag):
|
|
1236
|
+
a: int
|
|
1237
|
+
b: int
|
|
1238
|
+
def spam(x: Flags4 | None = None) -> None: ...
|
|
1239
|
+
""",
|
|
1240
|
+
runtime="""
|
|
1241
|
+
class Flags4(enum.Flag):
|
|
1242
|
+
a = 1
|
|
1243
|
+
b = 2
|
|
1244
|
+
def spam(x=Flags4(0)): pass
|
|
1245
|
+
""",
|
|
1246
|
+
error="spam",
|
|
1247
|
+
)
|
|
1248
|
+
yield Case(
|
|
1249
|
+
stub="""
|
|
1250
|
+
from typing_extensions import Final, Literal
|
|
1251
|
+
class BytesEnum(bytes, enum.Enum):
|
|
1252
|
+
a: bytes
|
|
1253
|
+
FOO: Literal[BytesEnum.a]
|
|
1254
|
+
BAR: Final = BytesEnum.a
|
|
1255
|
+
BAZ: BytesEnum
|
|
1256
|
+
EGGS: bytes
|
|
1257
|
+
""",
|
|
1258
|
+
runtime="""
|
|
1259
|
+
class BytesEnum(bytes, enum.Enum):
|
|
1260
|
+
a = b'foo'
|
|
1261
|
+
FOO = BytesEnum.a
|
|
1262
|
+
BAR = BytesEnum.a
|
|
1263
|
+
BAZ = BytesEnum.a
|
|
1264
|
+
EGGS = BytesEnum.a
|
|
1265
|
+
""",
|
|
1266
|
+
error=None,
|
|
1267
|
+
)
|
|
1268
|
+
|
|
1269
|
+
@collect_cases
|
|
1270
|
+
def test_decorator(self) -> Iterator[Case]:
|
|
1271
|
+
yield Case(
|
|
1272
|
+
stub="""
|
|
1273
|
+
from typing import Any, Callable
|
|
1274
|
+
def decorator(f: Callable[[], int]) -> Callable[..., Any]: ...
|
|
1275
|
+
@decorator
|
|
1276
|
+
def f() -> Any: ...
|
|
1277
|
+
""",
|
|
1278
|
+
runtime="""
|
|
1279
|
+
def decorator(f): return f
|
|
1280
|
+
@decorator
|
|
1281
|
+
def f(): return 3
|
|
1282
|
+
""",
|
|
1283
|
+
error=None,
|
|
1284
|
+
)
|
|
1285
|
+
|
|
1286
|
+
@collect_cases
|
|
1287
|
+
def test_all_at_runtime_not_stub(self) -> Iterator[Case]:
|
|
1288
|
+
yield Case(
|
|
1289
|
+
stub="Z: int",
|
|
1290
|
+
runtime="""
|
|
1291
|
+
__all__ = []
|
|
1292
|
+
Z = 5""",
|
|
1293
|
+
error=None,
|
|
1294
|
+
)
|
|
1295
|
+
|
|
1296
|
+
@collect_cases
|
|
1297
|
+
def test_all_in_stub_not_at_runtime(self) -> Iterator[Case]:
|
|
1298
|
+
yield Case(stub="__all__ = ()", runtime="", error="__all__")
|
|
1299
|
+
|
|
1300
|
+
@collect_cases
|
|
1301
|
+
def test_all_in_stub_different_to_all_at_runtime(self) -> Iterator[Case]:
|
|
1302
|
+
# We *should* emit an error with the module name itself + __all__,
|
|
1303
|
+
# if the stub *does* define __all__,
|
|
1304
|
+
# but the stub's __all__ is inconsistent with the runtime's __all__
|
|
1305
|
+
yield Case(
|
|
1306
|
+
stub="""
|
|
1307
|
+
__all__ = ['foo']
|
|
1308
|
+
foo: str
|
|
1309
|
+
""",
|
|
1310
|
+
runtime="""
|
|
1311
|
+
__all__ = []
|
|
1312
|
+
foo = 'foo'
|
|
1313
|
+
""",
|
|
1314
|
+
error="__all__",
|
|
1315
|
+
)
|
|
1316
|
+
|
|
1317
|
+
@collect_cases
|
|
1318
|
+
def test_missing(self) -> Iterator[Case]:
|
|
1319
|
+
yield Case(stub="x = 5", runtime="", error="x")
|
|
1320
|
+
yield Case(stub="def f(): ...", runtime="", error="f")
|
|
1321
|
+
yield Case(stub="class X: ...", runtime="", error="X")
|
|
1322
|
+
yield Case(
|
|
1323
|
+
stub="""
|
|
1324
|
+
from typing import overload
|
|
1325
|
+
@overload
|
|
1326
|
+
def h(x: int): ...
|
|
1327
|
+
@overload
|
|
1328
|
+
def h(x: str): ...
|
|
1329
|
+
""",
|
|
1330
|
+
runtime="",
|
|
1331
|
+
error="h",
|
|
1332
|
+
)
|
|
1333
|
+
yield Case(stub="", runtime="__all__ = []", error=None) # dummy case
|
|
1334
|
+
yield Case(stub="", runtime="__all__ += ['y']\ny = 5", error="y")
|
|
1335
|
+
yield Case(stub="", runtime="__all__ += ['g']\ndef g(): pass", error="g")
|
|
1336
|
+
# Here we should only check that runtime has B, since the stub explicitly re-exports it
|
|
1337
|
+
yield Case(
|
|
1338
|
+
stub="from mystery import A, B as B, C as D # type: ignore", runtime="", error="B"
|
|
1339
|
+
)
|
|
1340
|
+
yield Case(
|
|
1341
|
+
stub="class Y: ...",
|
|
1342
|
+
runtime="__all__ += ['Y']\nclass Y:\n def __or__(self, other): return self|other",
|
|
1343
|
+
error="Y.__or__",
|
|
1344
|
+
)
|
|
1345
|
+
yield Case(
|
|
1346
|
+
stub="class Z: ...",
|
|
1347
|
+
runtime="__all__ += ['Z']\nclass Z:\n def __reduce__(self): return (Z,)",
|
|
1348
|
+
error=None,
|
|
1349
|
+
)
|
|
1350
|
+
|
|
1351
|
+
@collect_cases
|
|
1352
|
+
def test_missing_no_runtime_all(self) -> Iterator[Case]:
|
|
1353
|
+
yield Case(stub="", runtime="import sys", error=None)
|
|
1354
|
+
yield Case(stub="", runtime="def g(): ...", error="g")
|
|
1355
|
+
yield Case(stub="", runtime="CONSTANT = 0", error="CONSTANT")
|
|
1356
|
+
yield Case(stub="", runtime="import re; constant = re.compile('foo')", error="constant")
|
|
1357
|
+
yield Case(stub="", runtime="from json.scanner import NUMBER_RE", error=None)
|
|
1358
|
+
yield Case(stub="", runtime="from string import ascii_letters", error=None)
|
|
1359
|
+
|
|
1360
|
+
@collect_cases
|
|
1361
|
+
def test_missing_no_runtime_all_terrible(self) -> Iterator[Case]:
|
|
1362
|
+
yield Case(
|
|
1363
|
+
stub="",
|
|
1364
|
+
runtime="""
|
|
1365
|
+
import sys
|
|
1366
|
+
import types
|
|
1367
|
+
import __future__
|
|
1368
|
+
_m = types.SimpleNamespace()
|
|
1369
|
+
_m.annotations = __future__.annotations
|
|
1370
|
+
sys.modules["_terrible_stubtest_test_module"] = _m
|
|
1371
|
+
|
|
1372
|
+
from _terrible_stubtest_test_module import *
|
|
1373
|
+
assert annotations
|
|
1374
|
+
""",
|
|
1375
|
+
error=None,
|
|
1376
|
+
)
|
|
1377
|
+
|
|
1378
|
+
@collect_cases
|
|
1379
|
+
def test_non_public_1(self) -> Iterator[Case]:
|
|
1380
|
+
yield Case(
|
|
1381
|
+
stub="__all__: list[str]", runtime="", error=f"{TEST_MODULE_NAME}.__all__"
|
|
1382
|
+
) # dummy case
|
|
1383
|
+
yield Case(stub="_f: int", runtime="def _f(): ...", error="_f")
|
|
1384
|
+
|
|
1385
|
+
@collect_cases
|
|
1386
|
+
def test_non_public_2(self) -> Iterator[Case]:
|
|
1387
|
+
yield Case(stub="__all__: list[str] = ['f']", runtime="__all__ = ['f']", error=None)
|
|
1388
|
+
yield Case(stub="f: int", runtime="def f(): ...", error="f")
|
|
1389
|
+
yield Case(stub="g: int", runtime="def g(): ...", error="g")
|
|
1390
|
+
|
|
1391
|
+
@collect_cases
|
|
1392
|
+
def test_dunders(self) -> Iterator[Case]:
|
|
1393
|
+
yield Case(
|
|
1394
|
+
stub="class A:\n def __init__(self, a: int, b: int) -> None: ...",
|
|
1395
|
+
runtime="class A:\n def __init__(self, a, bx): pass",
|
|
1396
|
+
error="A.__init__",
|
|
1397
|
+
)
|
|
1398
|
+
yield Case(
|
|
1399
|
+
stub="class B:\n def __call__(self, c: int, d: int) -> None: ...",
|
|
1400
|
+
runtime="class B:\n def __call__(self, c, dx): pass",
|
|
1401
|
+
error="B.__call__",
|
|
1402
|
+
)
|
|
1403
|
+
yield Case(
|
|
1404
|
+
stub=(
|
|
1405
|
+
"class C:\n"
|
|
1406
|
+
" def __init_subclass__(\n"
|
|
1407
|
+
" cls, e: int = ..., **kwargs: int\n"
|
|
1408
|
+
" ) -> None: ...\n"
|
|
1409
|
+
),
|
|
1410
|
+
runtime="class C:\n def __init_subclass__(cls, e=1, **kwargs): pass",
|
|
1411
|
+
error=None,
|
|
1412
|
+
)
|
|
1413
|
+
if sys.version_info >= (3, 9):
|
|
1414
|
+
yield Case(
|
|
1415
|
+
stub="class D:\n def __class_getitem__(cls, type: type) -> type: ...",
|
|
1416
|
+
runtime="class D:\n def __class_getitem__(cls, type): ...",
|
|
1417
|
+
error=None,
|
|
1418
|
+
)
|
|
1419
|
+
|
|
1420
|
+
@collect_cases
|
|
1421
|
+
def test_not_subclassable(self) -> Iterator[Case]:
|
|
1422
|
+
yield Case(
|
|
1423
|
+
stub="class CanBeSubclassed: ...", runtime="class CanBeSubclassed: ...", error=None
|
|
1424
|
+
)
|
|
1425
|
+
yield Case(
|
|
1426
|
+
stub="class CannotBeSubclassed:\n def __init_subclass__(cls) -> None: ...",
|
|
1427
|
+
runtime="class CannotBeSubclassed:\n def __init_subclass__(cls): raise TypeError",
|
|
1428
|
+
error="CannotBeSubclassed",
|
|
1429
|
+
)
|
|
1430
|
+
|
|
1431
|
+
@collect_cases
|
|
1432
|
+
def test_has_runtime_final_decorator(self) -> Iterator[Case]:
|
|
1433
|
+
yield Case(
|
|
1434
|
+
stub="from typing_extensions import final",
|
|
1435
|
+
runtime="""
|
|
1436
|
+
import functools
|
|
1437
|
+
from typing_extensions import final
|
|
1438
|
+
""",
|
|
1439
|
+
error=None,
|
|
1440
|
+
)
|
|
1441
|
+
yield Case(
|
|
1442
|
+
stub="""
|
|
1443
|
+
@final
|
|
1444
|
+
class A: ...
|
|
1445
|
+
""",
|
|
1446
|
+
runtime="""
|
|
1447
|
+
@final
|
|
1448
|
+
class A: ...
|
|
1449
|
+
""",
|
|
1450
|
+
error=None,
|
|
1451
|
+
)
|
|
1452
|
+
yield Case( # Runtime can miss `@final` decorator
|
|
1453
|
+
stub="""
|
|
1454
|
+
@final
|
|
1455
|
+
class B: ...
|
|
1456
|
+
""",
|
|
1457
|
+
runtime="""
|
|
1458
|
+
class B: ...
|
|
1459
|
+
""",
|
|
1460
|
+
error=None,
|
|
1461
|
+
)
|
|
1462
|
+
yield Case( # Stub cannot miss `@final` decorator
|
|
1463
|
+
stub="""
|
|
1464
|
+
class C: ...
|
|
1465
|
+
""",
|
|
1466
|
+
runtime="""
|
|
1467
|
+
@final
|
|
1468
|
+
class C: ...
|
|
1469
|
+
""",
|
|
1470
|
+
error="C",
|
|
1471
|
+
)
|
|
1472
|
+
yield Case(
|
|
1473
|
+
stub="""
|
|
1474
|
+
class D:
|
|
1475
|
+
@final
|
|
1476
|
+
def foo(self) -> None: ...
|
|
1477
|
+
@final
|
|
1478
|
+
@staticmethod
|
|
1479
|
+
def bar() -> None: ...
|
|
1480
|
+
@staticmethod
|
|
1481
|
+
@final
|
|
1482
|
+
def bar2() -> None: ...
|
|
1483
|
+
@final
|
|
1484
|
+
@classmethod
|
|
1485
|
+
def baz(cls) -> None: ...
|
|
1486
|
+
@classmethod
|
|
1487
|
+
@final
|
|
1488
|
+
def baz2(cls) -> None: ...
|
|
1489
|
+
@property
|
|
1490
|
+
@final
|
|
1491
|
+
def eggs(self) -> int: ...
|
|
1492
|
+
@final
|
|
1493
|
+
@property
|
|
1494
|
+
def eggs2(self) -> int: ...
|
|
1495
|
+
@final
|
|
1496
|
+
def ham(self, obj: int) -> int: ...
|
|
1497
|
+
""",
|
|
1498
|
+
runtime="""
|
|
1499
|
+
class D:
|
|
1500
|
+
@final
|
|
1501
|
+
def foo(self): pass
|
|
1502
|
+
@final
|
|
1503
|
+
@staticmethod
|
|
1504
|
+
def bar(): pass
|
|
1505
|
+
@staticmethod
|
|
1506
|
+
@final
|
|
1507
|
+
def bar2(): pass
|
|
1508
|
+
@final
|
|
1509
|
+
@classmethod
|
|
1510
|
+
def baz(cls): pass
|
|
1511
|
+
@classmethod
|
|
1512
|
+
@final
|
|
1513
|
+
def baz2(cls): pass
|
|
1514
|
+
@property
|
|
1515
|
+
@final
|
|
1516
|
+
def eggs(self): return 42
|
|
1517
|
+
@final
|
|
1518
|
+
@property
|
|
1519
|
+
def eggs2(self): pass
|
|
1520
|
+
@final
|
|
1521
|
+
@functools.lru_cache()
|
|
1522
|
+
def ham(self, obj): return obj * 2
|
|
1523
|
+
""",
|
|
1524
|
+
error=None,
|
|
1525
|
+
)
|
|
1526
|
+
# Stub methods are allowed to have @final even if the runtime doesn't...
|
|
1527
|
+
yield Case(
|
|
1528
|
+
stub="""
|
|
1529
|
+
class E:
|
|
1530
|
+
@final
|
|
1531
|
+
def foo(self) -> None: ...
|
|
1532
|
+
@final
|
|
1533
|
+
@staticmethod
|
|
1534
|
+
def bar() -> None: ...
|
|
1535
|
+
@staticmethod
|
|
1536
|
+
@final
|
|
1537
|
+
def bar2() -> None: ...
|
|
1538
|
+
@final
|
|
1539
|
+
@classmethod
|
|
1540
|
+
def baz(cls) -> None: ...
|
|
1541
|
+
@classmethod
|
|
1542
|
+
@final
|
|
1543
|
+
def baz2(cls) -> None: ...
|
|
1544
|
+
@property
|
|
1545
|
+
@final
|
|
1546
|
+
def eggs(self) -> int: ...
|
|
1547
|
+
@final
|
|
1548
|
+
@property
|
|
1549
|
+
def eggs2(self) -> int: ...
|
|
1550
|
+
@final
|
|
1551
|
+
def ham(self, obj: int) -> int: ...
|
|
1552
|
+
""",
|
|
1553
|
+
runtime="""
|
|
1554
|
+
class E:
|
|
1555
|
+
def foo(self): pass
|
|
1556
|
+
@staticmethod
|
|
1557
|
+
def bar(): pass
|
|
1558
|
+
@staticmethod
|
|
1559
|
+
def bar2(): pass
|
|
1560
|
+
@classmethod
|
|
1561
|
+
def baz(cls): pass
|
|
1562
|
+
@classmethod
|
|
1563
|
+
def baz2(cls): pass
|
|
1564
|
+
@property
|
|
1565
|
+
def eggs(self): return 42
|
|
1566
|
+
@property
|
|
1567
|
+
def eggs2(self): return 42
|
|
1568
|
+
@functools.lru_cache()
|
|
1569
|
+
def ham(self, obj): return obj * 2
|
|
1570
|
+
""",
|
|
1571
|
+
error=None,
|
|
1572
|
+
)
|
|
1573
|
+
# ...But if the runtime has @final, the stub must have it as well
|
|
1574
|
+
yield Case(
|
|
1575
|
+
stub="""
|
|
1576
|
+
class F:
|
|
1577
|
+
def foo(self) -> None: ...
|
|
1578
|
+
""",
|
|
1579
|
+
runtime="""
|
|
1580
|
+
class F:
|
|
1581
|
+
@final
|
|
1582
|
+
def foo(self): pass
|
|
1583
|
+
""",
|
|
1584
|
+
error="F.foo",
|
|
1585
|
+
)
|
|
1586
|
+
yield Case(
|
|
1587
|
+
stub="""
|
|
1588
|
+
class G:
|
|
1589
|
+
@staticmethod
|
|
1590
|
+
def foo() -> None: ...
|
|
1591
|
+
""",
|
|
1592
|
+
runtime="""
|
|
1593
|
+
class G:
|
|
1594
|
+
@final
|
|
1595
|
+
@staticmethod
|
|
1596
|
+
def foo(): pass
|
|
1597
|
+
""",
|
|
1598
|
+
error="G.foo",
|
|
1599
|
+
)
|
|
1600
|
+
yield Case(
|
|
1601
|
+
stub="""
|
|
1602
|
+
class H:
|
|
1603
|
+
@staticmethod
|
|
1604
|
+
def foo() -> None: ...
|
|
1605
|
+
""",
|
|
1606
|
+
runtime="""
|
|
1607
|
+
class H:
|
|
1608
|
+
@staticmethod
|
|
1609
|
+
@final
|
|
1610
|
+
def foo(): pass
|
|
1611
|
+
""",
|
|
1612
|
+
error="H.foo",
|
|
1613
|
+
)
|
|
1614
|
+
yield Case(
|
|
1615
|
+
stub="""
|
|
1616
|
+
class I:
|
|
1617
|
+
@classmethod
|
|
1618
|
+
def foo(cls) -> None: ...
|
|
1619
|
+
""",
|
|
1620
|
+
runtime="""
|
|
1621
|
+
class I:
|
|
1622
|
+
@final
|
|
1623
|
+
@classmethod
|
|
1624
|
+
def foo(cls): pass
|
|
1625
|
+
""",
|
|
1626
|
+
error="I.foo",
|
|
1627
|
+
)
|
|
1628
|
+
yield Case(
|
|
1629
|
+
stub="""
|
|
1630
|
+
class J:
|
|
1631
|
+
@classmethod
|
|
1632
|
+
def foo(cls) -> None: ...
|
|
1633
|
+
""",
|
|
1634
|
+
runtime="""
|
|
1635
|
+
class J:
|
|
1636
|
+
@classmethod
|
|
1637
|
+
@final
|
|
1638
|
+
def foo(cls): pass
|
|
1639
|
+
""",
|
|
1640
|
+
error="J.foo",
|
|
1641
|
+
)
|
|
1642
|
+
yield Case(
|
|
1643
|
+
stub="""
|
|
1644
|
+
class K:
|
|
1645
|
+
@property
|
|
1646
|
+
def foo(self) -> int: ...
|
|
1647
|
+
""",
|
|
1648
|
+
runtime="""
|
|
1649
|
+
class K:
|
|
1650
|
+
@property
|
|
1651
|
+
@final
|
|
1652
|
+
def foo(self): return 42
|
|
1653
|
+
""",
|
|
1654
|
+
error="K.foo",
|
|
1655
|
+
)
|
|
1656
|
+
# This test wouldn't pass,
|
|
1657
|
+
# because the runtime can't set __final__ on instances of builtins.property,
|
|
1658
|
+
# so stubtest has non way of knowing that the runtime was decorated with @final:
|
|
1659
|
+
#
|
|
1660
|
+
# yield Case(
|
|
1661
|
+
# stub="""
|
|
1662
|
+
# class K2:
|
|
1663
|
+
# @property
|
|
1664
|
+
# def foo(self) -> int: ...
|
|
1665
|
+
# """,
|
|
1666
|
+
# runtime="""
|
|
1667
|
+
# class K2:
|
|
1668
|
+
# @final
|
|
1669
|
+
# @property
|
|
1670
|
+
# def foo(self): return 42
|
|
1671
|
+
# """,
|
|
1672
|
+
# error="K2.foo",
|
|
1673
|
+
# )
|
|
1674
|
+
yield Case(
|
|
1675
|
+
stub="""
|
|
1676
|
+
class L:
|
|
1677
|
+
def foo(self, obj: int) -> int: ...
|
|
1678
|
+
""",
|
|
1679
|
+
runtime="""
|
|
1680
|
+
class L:
|
|
1681
|
+
@final
|
|
1682
|
+
@functools.lru_cache()
|
|
1683
|
+
def foo(self, obj): return obj * 2
|
|
1684
|
+
""",
|
|
1685
|
+
error="L.foo",
|
|
1686
|
+
)
|
|
1687
|
+
|
|
1688
|
+
@collect_cases
|
|
1689
|
+
def test_name_mangling(self) -> Iterator[Case]:
|
|
1690
|
+
yield Case(
|
|
1691
|
+
stub="""
|
|
1692
|
+
class X:
|
|
1693
|
+
def __mangle_good(self, text: str) -> None: ...
|
|
1694
|
+
def __mangle_bad(self, number: int) -> None: ...
|
|
1695
|
+
""",
|
|
1696
|
+
runtime="""
|
|
1697
|
+
class X:
|
|
1698
|
+
def __mangle_good(self, text): pass
|
|
1699
|
+
def __mangle_bad(self, text): pass
|
|
1700
|
+
""",
|
|
1701
|
+
error="X.__mangle_bad",
|
|
1702
|
+
)
|
|
1703
|
+
yield Case(
|
|
1704
|
+
stub="""
|
|
1705
|
+
class Klass:
|
|
1706
|
+
class __Mangled1:
|
|
1707
|
+
class __Mangled2:
|
|
1708
|
+
def __mangle_good(self, text: str) -> None: ...
|
|
1709
|
+
def __mangle_bad(self, number: int) -> None: ...
|
|
1710
|
+
""",
|
|
1711
|
+
runtime="""
|
|
1712
|
+
class Klass:
|
|
1713
|
+
class __Mangled1:
|
|
1714
|
+
class __Mangled2:
|
|
1715
|
+
def __mangle_good(self, text): pass
|
|
1716
|
+
def __mangle_bad(self, text): pass
|
|
1717
|
+
""",
|
|
1718
|
+
error="Klass.__Mangled1.__Mangled2.__mangle_bad",
|
|
1719
|
+
)
|
|
1720
|
+
yield Case(
|
|
1721
|
+
stub="""
|
|
1722
|
+
class __Dunder__:
|
|
1723
|
+
def __mangle_good(self, text: str) -> None: ...
|
|
1724
|
+
def __mangle_bad(self, number: int) -> None: ...
|
|
1725
|
+
""",
|
|
1726
|
+
runtime="""
|
|
1727
|
+
class __Dunder__:
|
|
1728
|
+
def __mangle_good(self, text): pass
|
|
1729
|
+
def __mangle_bad(self, text): pass
|
|
1730
|
+
""",
|
|
1731
|
+
error="__Dunder__.__mangle_bad",
|
|
1732
|
+
)
|
|
1733
|
+
yield Case(
|
|
1734
|
+
stub="""
|
|
1735
|
+
class _Private:
|
|
1736
|
+
def __mangle_good(self, text: str) -> None: ...
|
|
1737
|
+
def __mangle_bad(self, number: int) -> None: ...
|
|
1738
|
+
""",
|
|
1739
|
+
runtime="""
|
|
1740
|
+
class _Private:
|
|
1741
|
+
def __mangle_good(self, text): pass
|
|
1742
|
+
def __mangle_bad(self, text): pass
|
|
1743
|
+
""",
|
|
1744
|
+
error="_Private.__mangle_bad",
|
|
1745
|
+
)
|
|
1746
|
+
|
|
1747
|
+
@collect_cases
|
|
1748
|
+
def test_mro(self) -> Iterator[Case]:
|
|
1749
|
+
yield Case(
|
|
1750
|
+
stub="""
|
|
1751
|
+
class A:
|
|
1752
|
+
def foo(self, x: int) -> None: ...
|
|
1753
|
+
class B(A):
|
|
1754
|
+
pass
|
|
1755
|
+
class C(A):
|
|
1756
|
+
pass
|
|
1757
|
+
""",
|
|
1758
|
+
runtime="""
|
|
1759
|
+
class A:
|
|
1760
|
+
def foo(self, x: int) -> None: ...
|
|
1761
|
+
class B(A):
|
|
1762
|
+
def foo(self, x: int) -> None: ...
|
|
1763
|
+
class C(A):
|
|
1764
|
+
def foo(self, y: int) -> None: ...
|
|
1765
|
+
""",
|
|
1766
|
+
error="C.foo",
|
|
1767
|
+
)
|
|
1768
|
+
yield Case(
|
|
1769
|
+
stub="""
|
|
1770
|
+
class X: ...
|
|
1771
|
+
""",
|
|
1772
|
+
runtime="""
|
|
1773
|
+
class X:
|
|
1774
|
+
def __init__(self, x): pass
|
|
1775
|
+
""",
|
|
1776
|
+
error="X.__init__",
|
|
1777
|
+
)
|
|
1778
|
+
|
|
1779
|
+
@collect_cases
|
|
1780
|
+
def test_good_literal(self) -> Iterator[Case]:
|
|
1781
|
+
yield Case(
|
|
1782
|
+
stub=r"""
|
|
1783
|
+
from typing_extensions import Literal
|
|
1784
|
+
|
|
1785
|
+
import enum
|
|
1786
|
+
class Color(enum.Enum):
|
|
1787
|
+
RED: int
|
|
1788
|
+
|
|
1789
|
+
NUM: Literal[1]
|
|
1790
|
+
CHAR: Literal['a']
|
|
1791
|
+
FLAG: Literal[True]
|
|
1792
|
+
NON: Literal[None]
|
|
1793
|
+
BYT1: Literal[b'abc']
|
|
1794
|
+
BYT2: Literal[b'\x90']
|
|
1795
|
+
ENUM: Literal[Color.RED]
|
|
1796
|
+
""",
|
|
1797
|
+
runtime=r"""
|
|
1798
|
+
import enum
|
|
1799
|
+
class Color(enum.Enum):
|
|
1800
|
+
RED = 3
|
|
1801
|
+
|
|
1802
|
+
NUM = 1
|
|
1803
|
+
CHAR = 'a'
|
|
1804
|
+
NON = None
|
|
1805
|
+
FLAG = True
|
|
1806
|
+
BYT1 = b"abc"
|
|
1807
|
+
BYT2 = b'\x90'
|
|
1808
|
+
ENUM = Color.RED
|
|
1809
|
+
""",
|
|
1810
|
+
error=None,
|
|
1811
|
+
)
|
|
1812
|
+
|
|
1813
|
+
@collect_cases
|
|
1814
|
+
def test_bad_literal(self) -> Iterator[Case]:
|
|
1815
|
+
yield Case("from typing_extensions import Literal", "", None) # dummy case
|
|
1816
|
+
yield Case(
|
|
1817
|
+
stub="INT_FLOAT_MISMATCH: Literal[1]",
|
|
1818
|
+
runtime="INT_FLOAT_MISMATCH = 1.0",
|
|
1819
|
+
error="INT_FLOAT_MISMATCH",
|
|
1820
|
+
)
|
|
1821
|
+
yield Case(stub="WRONG_INT: Literal[1]", runtime="WRONG_INT = 2", error="WRONG_INT")
|
|
1822
|
+
yield Case(stub="WRONG_STR: Literal['a']", runtime="WRONG_STR = 'b'", error="WRONG_STR")
|
|
1823
|
+
yield Case(
|
|
1824
|
+
stub="BYTES_STR_MISMATCH: Literal[b'value']",
|
|
1825
|
+
runtime="BYTES_STR_MISMATCH = 'value'",
|
|
1826
|
+
error="BYTES_STR_MISMATCH",
|
|
1827
|
+
)
|
|
1828
|
+
yield Case(
|
|
1829
|
+
stub="STR_BYTES_MISMATCH: Literal['value']",
|
|
1830
|
+
runtime="STR_BYTES_MISMATCH = b'value'",
|
|
1831
|
+
error="STR_BYTES_MISMATCH",
|
|
1832
|
+
)
|
|
1833
|
+
yield Case(
|
|
1834
|
+
stub="WRONG_BYTES: Literal[b'abc']",
|
|
1835
|
+
runtime="WRONG_BYTES = b'xyz'",
|
|
1836
|
+
error="WRONG_BYTES",
|
|
1837
|
+
)
|
|
1838
|
+
yield Case(
|
|
1839
|
+
stub="WRONG_BOOL_1: Literal[True]",
|
|
1840
|
+
runtime="WRONG_BOOL_1 = False",
|
|
1841
|
+
error="WRONG_BOOL_1",
|
|
1842
|
+
)
|
|
1843
|
+
yield Case(
|
|
1844
|
+
stub="WRONG_BOOL_2: Literal[False]",
|
|
1845
|
+
runtime="WRONG_BOOL_2 = True",
|
|
1846
|
+
error="WRONG_BOOL_2",
|
|
1847
|
+
)
|
|
1848
|
+
|
|
1849
|
+
@collect_cases
|
|
1850
|
+
def test_special_subtype(self) -> Iterator[Case]:
|
|
1851
|
+
yield Case(
|
|
1852
|
+
stub="""
|
|
1853
|
+
b1: bool
|
|
1854
|
+
b2: bool
|
|
1855
|
+
b3: bool
|
|
1856
|
+
""",
|
|
1857
|
+
runtime="""
|
|
1858
|
+
b1 = 0
|
|
1859
|
+
b2 = 1
|
|
1860
|
+
b3 = 2
|
|
1861
|
+
""",
|
|
1862
|
+
error="b3",
|
|
1863
|
+
)
|
|
1864
|
+
yield Case(
|
|
1865
|
+
stub="""
|
|
1866
|
+
from typing_extensions import TypedDict
|
|
1867
|
+
|
|
1868
|
+
class _Options(TypedDict):
|
|
1869
|
+
a: str
|
|
1870
|
+
b: int
|
|
1871
|
+
|
|
1872
|
+
opt1: _Options
|
|
1873
|
+
opt2: _Options
|
|
1874
|
+
opt3: _Options
|
|
1875
|
+
""",
|
|
1876
|
+
runtime="""
|
|
1877
|
+
opt1 = {"a": "3.", "b": 14}
|
|
1878
|
+
opt2 = {"some": "stuff"} # false negative
|
|
1879
|
+
opt3 = 0
|
|
1880
|
+
""",
|
|
1881
|
+
error="opt3",
|
|
1882
|
+
)
|
|
1883
|
+
|
|
1884
|
+
@collect_cases
|
|
1885
|
+
def test_runtime_typing_objects(self) -> Iterator[Case]:
|
|
1886
|
+
yield Case(
|
|
1887
|
+
stub="from typing_extensions import Protocol, TypedDict",
|
|
1888
|
+
runtime="from typing_extensions import Protocol, TypedDict",
|
|
1889
|
+
error=None,
|
|
1890
|
+
)
|
|
1891
|
+
yield Case(
|
|
1892
|
+
stub="""
|
|
1893
|
+
class X(Protocol):
|
|
1894
|
+
bar: int
|
|
1895
|
+
def foo(self, x: int, y: bytes = ...) -> str: ...
|
|
1896
|
+
""",
|
|
1897
|
+
runtime="""
|
|
1898
|
+
class X(Protocol):
|
|
1899
|
+
bar: int
|
|
1900
|
+
def foo(self, x: int, y: bytes = ...) -> str: ...
|
|
1901
|
+
""",
|
|
1902
|
+
error=None,
|
|
1903
|
+
)
|
|
1904
|
+
yield Case(
|
|
1905
|
+
stub="""
|
|
1906
|
+
class Y(TypedDict):
|
|
1907
|
+
a: int
|
|
1908
|
+
""",
|
|
1909
|
+
runtime="""
|
|
1910
|
+
class Y(TypedDict):
|
|
1911
|
+
a: int
|
|
1912
|
+
""",
|
|
1913
|
+
error=None,
|
|
1914
|
+
)
|
|
1915
|
+
|
|
1916
|
+
@collect_cases
|
|
1917
|
+
def test_named_tuple(self) -> Iterator[Case]:
|
|
1918
|
+
yield Case(
|
|
1919
|
+
stub="from typing import NamedTuple",
|
|
1920
|
+
runtime="from typing import NamedTuple",
|
|
1921
|
+
error=None,
|
|
1922
|
+
)
|
|
1923
|
+
yield Case(
|
|
1924
|
+
stub="""
|
|
1925
|
+
class X1(NamedTuple):
|
|
1926
|
+
bar: int
|
|
1927
|
+
foo: str = ...
|
|
1928
|
+
""",
|
|
1929
|
+
runtime="""
|
|
1930
|
+
class X1(NamedTuple):
|
|
1931
|
+
bar: int
|
|
1932
|
+
foo: str = 'a'
|
|
1933
|
+
""",
|
|
1934
|
+
error=None,
|
|
1935
|
+
)
|
|
1936
|
+
yield Case(
|
|
1937
|
+
stub="""
|
|
1938
|
+
class X2(NamedTuple):
|
|
1939
|
+
bar: int
|
|
1940
|
+
foo: str
|
|
1941
|
+
""",
|
|
1942
|
+
runtime="""
|
|
1943
|
+
class X2(NamedTuple):
|
|
1944
|
+
bar: int
|
|
1945
|
+
foo: str = 'a'
|
|
1946
|
+
""",
|
|
1947
|
+
# `__new__` will miss a default value for a `foo` parameter,
|
|
1948
|
+
# but we don't generate special errors for `foo` missing `...` part.
|
|
1949
|
+
error="X2.__new__",
|
|
1950
|
+
)
|
|
1951
|
+
|
|
1952
|
+
@collect_cases
|
|
1953
|
+
def test_named_tuple_typing_and_collections(self) -> Iterator[Case]:
|
|
1954
|
+
yield Case(
|
|
1955
|
+
stub="from typing import NamedTuple",
|
|
1956
|
+
runtime="from collections import namedtuple",
|
|
1957
|
+
error=None,
|
|
1958
|
+
)
|
|
1959
|
+
yield Case(
|
|
1960
|
+
stub="""
|
|
1961
|
+
class X1(NamedTuple):
|
|
1962
|
+
bar: int
|
|
1963
|
+
foo: str = ...
|
|
1964
|
+
""",
|
|
1965
|
+
runtime="""
|
|
1966
|
+
X1 = namedtuple('X1', ['bar', 'foo'], defaults=['a'])
|
|
1967
|
+
""",
|
|
1968
|
+
error=None,
|
|
1969
|
+
)
|
|
1970
|
+
yield Case(
|
|
1971
|
+
stub="""
|
|
1972
|
+
class X2(NamedTuple):
|
|
1973
|
+
bar: int
|
|
1974
|
+
foo: str
|
|
1975
|
+
""",
|
|
1976
|
+
runtime="""
|
|
1977
|
+
X2 = namedtuple('X1', ['bar', 'foo'], defaults=['a'])
|
|
1978
|
+
""",
|
|
1979
|
+
error="X2.__new__",
|
|
1980
|
+
)
|
|
1981
|
+
|
|
1982
|
+
@collect_cases
|
|
1983
|
+
def test_type_var(self) -> Iterator[Case]:
|
|
1984
|
+
yield Case(
|
|
1985
|
+
stub="from typing import TypeVar", runtime="from typing import TypeVar", error=None
|
|
1986
|
+
)
|
|
1987
|
+
yield Case(stub="A = TypeVar('A')", runtime="A = TypeVar('A')", error=None)
|
|
1988
|
+
yield Case(stub="B = TypeVar('B')", runtime="B = 5", error="B")
|
|
1989
|
+
if sys.version_info >= (3, 10):
|
|
1990
|
+
yield Case(
|
|
1991
|
+
stub="from typing import ParamSpec",
|
|
1992
|
+
runtime="from typing import ParamSpec",
|
|
1993
|
+
error=None,
|
|
1994
|
+
)
|
|
1995
|
+
yield Case(stub="C = ParamSpec('C')", runtime="C = ParamSpec('C')", error=None)
|
|
1996
|
+
|
|
1997
|
+
@collect_cases
|
|
1998
|
+
def test_metaclass_match(self) -> Iterator[Case]:
|
|
1999
|
+
yield Case(stub="class Meta(type): ...", runtime="class Meta(type): ...", error=None)
|
|
2000
|
+
yield Case(stub="class A0: ...", runtime="class A0: ...", error=None)
|
|
2001
|
+
yield Case(
|
|
2002
|
+
stub="class A1(metaclass=Meta): ...",
|
|
2003
|
+
runtime="class A1(metaclass=Meta): ...",
|
|
2004
|
+
error=None,
|
|
2005
|
+
)
|
|
2006
|
+
yield Case(stub="class A2: ...", runtime="class A2(metaclass=Meta): ...", error="A2")
|
|
2007
|
+
yield Case(stub="class A3(metaclass=Meta): ...", runtime="class A3: ...", error="A3")
|
|
2008
|
+
|
|
2009
|
+
# Explicit `type` metaclass can always be added in any part:
|
|
2010
|
+
yield Case(
|
|
2011
|
+
stub="class T1(metaclass=type): ...",
|
|
2012
|
+
runtime="class T1(metaclass=type): ...",
|
|
2013
|
+
error=None,
|
|
2014
|
+
)
|
|
2015
|
+
yield Case(stub="class T2: ...", runtime="class T2(metaclass=type): ...", error=None)
|
|
2016
|
+
yield Case(stub="class T3(metaclass=type): ...", runtime="class T3: ...", error=None)
|
|
2017
|
+
|
|
2018
|
+
# Explicit check that `_protected` names are also supported:
|
|
2019
|
+
yield Case(stub="class _P1(type): ...", runtime="class _P1(type): ...", error=None)
|
|
2020
|
+
yield Case(stub="class P2: ...", runtime="class P2(metaclass=_P1): ...", error="P2")
|
|
2021
|
+
|
|
2022
|
+
# With inheritance:
|
|
2023
|
+
yield Case(
|
|
2024
|
+
stub="""
|
|
2025
|
+
class I1(metaclass=Meta): ...
|
|
2026
|
+
class S1(I1): ...
|
|
2027
|
+
""",
|
|
2028
|
+
runtime="""
|
|
2029
|
+
class I1(metaclass=Meta): ...
|
|
2030
|
+
class S1(I1): ...
|
|
2031
|
+
""",
|
|
2032
|
+
error=None,
|
|
2033
|
+
)
|
|
2034
|
+
yield Case(
|
|
2035
|
+
stub="""
|
|
2036
|
+
class I2(metaclass=Meta): ...
|
|
2037
|
+
class S2: ... # missing inheritance
|
|
2038
|
+
""",
|
|
2039
|
+
runtime="""
|
|
2040
|
+
class I2(metaclass=Meta): ...
|
|
2041
|
+
class S2(I2): ...
|
|
2042
|
+
""",
|
|
2043
|
+
error="S2",
|
|
2044
|
+
)
|
|
2045
|
+
|
|
2046
|
+
@collect_cases
|
|
2047
|
+
def test_metaclass_abcmeta(self) -> Iterator[Case]:
|
|
2048
|
+
# Handling abstract metaclasses is special:
|
|
2049
|
+
yield Case(stub="from abc import ABCMeta", runtime="from abc import ABCMeta", error=None)
|
|
2050
|
+
yield Case(
|
|
2051
|
+
stub="class A1(metaclass=ABCMeta): ...",
|
|
2052
|
+
runtime="class A1(metaclass=ABCMeta): ...",
|
|
2053
|
+
error=None,
|
|
2054
|
+
)
|
|
2055
|
+
# Stubs cannot miss abstract metaclass:
|
|
2056
|
+
yield Case(stub="class A2: ...", runtime="class A2(metaclass=ABCMeta): ...", error="A2")
|
|
2057
|
+
# But, stubs can add extra abstract metaclass, this might be a typing hack:
|
|
2058
|
+
yield Case(stub="class A3(metaclass=ABCMeta): ...", runtime="class A3: ...", error=None)
|
|
2059
|
+
|
|
2060
|
+
@collect_cases
|
|
2061
|
+
def test_abstract_methods(self) -> Iterator[Case]:
|
|
2062
|
+
yield Case(
|
|
2063
|
+
stub="""
|
|
2064
|
+
from abc import abstractmethod
|
|
2065
|
+
from typing import overload
|
|
2066
|
+
""",
|
|
2067
|
+
runtime="from abc import abstractmethod",
|
|
2068
|
+
error=None,
|
|
2069
|
+
)
|
|
2070
|
+
yield Case(
|
|
2071
|
+
stub="""
|
|
2072
|
+
class A1:
|
|
2073
|
+
def some(self) -> None: ...
|
|
2074
|
+
""",
|
|
2075
|
+
runtime="""
|
|
2076
|
+
class A1:
|
|
2077
|
+
@abstractmethod
|
|
2078
|
+
def some(self) -> None: ...
|
|
2079
|
+
""",
|
|
2080
|
+
error="A1.some",
|
|
2081
|
+
)
|
|
2082
|
+
yield Case(
|
|
2083
|
+
stub="""
|
|
2084
|
+
class A2:
|
|
2085
|
+
@abstractmethod
|
|
2086
|
+
def some(self) -> None: ...
|
|
2087
|
+
""",
|
|
2088
|
+
runtime="""
|
|
2089
|
+
class A2:
|
|
2090
|
+
@abstractmethod
|
|
2091
|
+
def some(self) -> None: ...
|
|
2092
|
+
""",
|
|
2093
|
+
error=None,
|
|
2094
|
+
)
|
|
2095
|
+
yield Case(
|
|
2096
|
+
stub="""
|
|
2097
|
+
class A3:
|
|
2098
|
+
@overload
|
|
2099
|
+
def some(self, other: int) -> str: ...
|
|
2100
|
+
@overload
|
|
2101
|
+
def some(self, other: str) -> int: ...
|
|
2102
|
+
""",
|
|
2103
|
+
runtime="""
|
|
2104
|
+
class A3:
|
|
2105
|
+
@abstractmethod
|
|
2106
|
+
def some(self, other) -> None: ...
|
|
2107
|
+
""",
|
|
2108
|
+
error="A3.some",
|
|
2109
|
+
)
|
|
2110
|
+
yield Case(
|
|
2111
|
+
stub="""
|
|
2112
|
+
class A4:
|
|
2113
|
+
@overload
|
|
2114
|
+
@abstractmethod
|
|
2115
|
+
def some(self, other: int) -> str: ...
|
|
2116
|
+
@overload
|
|
2117
|
+
@abstractmethod
|
|
2118
|
+
def some(self, other: str) -> int: ...
|
|
2119
|
+
""",
|
|
2120
|
+
runtime="""
|
|
2121
|
+
class A4:
|
|
2122
|
+
@abstractmethod
|
|
2123
|
+
def some(self, other) -> None: ...
|
|
2124
|
+
""",
|
|
2125
|
+
error=None,
|
|
2126
|
+
)
|
|
2127
|
+
yield Case(
|
|
2128
|
+
stub="""
|
|
2129
|
+
class A5:
|
|
2130
|
+
@abstractmethod
|
|
2131
|
+
@overload
|
|
2132
|
+
def some(self, other: int) -> str: ...
|
|
2133
|
+
@abstractmethod
|
|
2134
|
+
@overload
|
|
2135
|
+
def some(self, other: str) -> int: ...
|
|
2136
|
+
""",
|
|
2137
|
+
runtime="""
|
|
2138
|
+
class A5:
|
|
2139
|
+
@abstractmethod
|
|
2140
|
+
def some(self, other) -> None: ...
|
|
2141
|
+
""",
|
|
2142
|
+
error=None,
|
|
2143
|
+
)
|
|
2144
|
+
# Runtime can miss `@abstractmethod`:
|
|
2145
|
+
yield Case(
|
|
2146
|
+
stub="""
|
|
2147
|
+
class A6:
|
|
2148
|
+
@abstractmethod
|
|
2149
|
+
def some(self) -> None: ...
|
|
2150
|
+
""",
|
|
2151
|
+
runtime="""
|
|
2152
|
+
class A6:
|
|
2153
|
+
def some(self) -> None: ...
|
|
2154
|
+
""",
|
|
2155
|
+
error=None,
|
|
2156
|
+
)
|
|
2157
|
+
|
|
2158
|
+
@collect_cases
|
|
2159
|
+
def test_abstract_properties(self) -> Iterator[Case]:
|
|
2160
|
+
# TODO: test abstract properties with setters
|
|
2161
|
+
yield Case(
|
|
2162
|
+
stub="from abc import abstractmethod",
|
|
2163
|
+
runtime="from abc import abstractmethod",
|
|
2164
|
+
error=None,
|
|
2165
|
+
)
|
|
2166
|
+
# Ensure that `@property` also can be abstract:
|
|
2167
|
+
yield Case(
|
|
2168
|
+
stub="""
|
|
2169
|
+
class AP1:
|
|
2170
|
+
@property
|
|
2171
|
+
def some(self) -> int: ...
|
|
2172
|
+
""",
|
|
2173
|
+
runtime="""
|
|
2174
|
+
class AP1:
|
|
2175
|
+
@property
|
|
2176
|
+
@abstractmethod
|
|
2177
|
+
def some(self) -> int: ...
|
|
2178
|
+
""",
|
|
2179
|
+
error="AP1.some",
|
|
2180
|
+
)
|
|
2181
|
+
yield Case(
|
|
2182
|
+
stub="""
|
|
2183
|
+
class AP1_2:
|
|
2184
|
+
def some(self) -> int: ... # missing `@property` decorator
|
|
2185
|
+
""",
|
|
2186
|
+
runtime="""
|
|
2187
|
+
class AP1_2:
|
|
2188
|
+
@property
|
|
2189
|
+
@abstractmethod
|
|
2190
|
+
def some(self) -> int: ...
|
|
2191
|
+
""",
|
|
2192
|
+
error="AP1_2.some",
|
|
2193
|
+
)
|
|
2194
|
+
yield Case(
|
|
2195
|
+
stub="""
|
|
2196
|
+
class AP2:
|
|
2197
|
+
@property
|
|
2198
|
+
@abstractmethod
|
|
2199
|
+
def some(self) -> int: ...
|
|
2200
|
+
""",
|
|
2201
|
+
runtime="""
|
|
2202
|
+
class AP2:
|
|
2203
|
+
@property
|
|
2204
|
+
@abstractmethod
|
|
2205
|
+
def some(self) -> int: ...
|
|
2206
|
+
""",
|
|
2207
|
+
error=None,
|
|
2208
|
+
)
|
|
2209
|
+
# Runtime can miss `@abstractmethod`:
|
|
2210
|
+
yield Case(
|
|
2211
|
+
stub="""
|
|
2212
|
+
class AP3:
|
|
2213
|
+
@property
|
|
2214
|
+
@abstractmethod
|
|
2215
|
+
def some(self) -> int: ...
|
|
2216
|
+
""",
|
|
2217
|
+
runtime="""
|
|
2218
|
+
class AP3:
|
|
2219
|
+
@property
|
|
2220
|
+
def some(self) -> int: ...
|
|
2221
|
+
""",
|
|
2222
|
+
error=None,
|
|
2223
|
+
)
|
|
2224
|
+
|
|
2225
|
+
@collect_cases
|
|
2226
|
+
def test_type_check_only(self) -> Iterator[Case]:
|
|
2227
|
+
yield Case(
|
|
2228
|
+
stub="from typing import type_check_only, overload",
|
|
2229
|
+
runtime="from typing import overload",
|
|
2230
|
+
error=None,
|
|
2231
|
+
)
|
|
2232
|
+
# You can have public types that are only defined in stubs
|
|
2233
|
+
# with `@type_check_only`:
|
|
2234
|
+
yield Case(
|
|
2235
|
+
stub="""
|
|
2236
|
+
@type_check_only
|
|
2237
|
+
class A1: ...
|
|
2238
|
+
""",
|
|
2239
|
+
runtime="",
|
|
2240
|
+
error=None,
|
|
2241
|
+
)
|
|
2242
|
+
# Having `@type_check_only` on a type that exists at runtime is an error
|
|
2243
|
+
yield Case(
|
|
2244
|
+
stub="""
|
|
2245
|
+
@type_check_only
|
|
2246
|
+
class A2: ...
|
|
2247
|
+
""",
|
|
2248
|
+
runtime="class A2: ...",
|
|
2249
|
+
error="A2",
|
|
2250
|
+
)
|
|
2251
|
+
# The same is true for NamedTuples and TypedDicts:
|
|
2252
|
+
yield Case(
|
|
2253
|
+
stub="from typing_extensions import NamedTuple, TypedDict",
|
|
2254
|
+
runtime="from typing_extensions import NamedTuple, TypedDict",
|
|
2255
|
+
error=None,
|
|
2256
|
+
)
|
|
2257
|
+
yield Case(
|
|
2258
|
+
stub="""
|
|
2259
|
+
@type_check_only
|
|
2260
|
+
class NT1(NamedTuple): ...
|
|
2261
|
+
""",
|
|
2262
|
+
runtime="class NT1(NamedTuple): ...",
|
|
2263
|
+
error="NT1",
|
|
2264
|
+
)
|
|
2265
|
+
yield Case(
|
|
2266
|
+
stub="""
|
|
2267
|
+
@type_check_only
|
|
2268
|
+
class TD1(TypedDict): ...
|
|
2269
|
+
""",
|
|
2270
|
+
runtime="class TD1(TypedDict): ...",
|
|
2271
|
+
error="TD1",
|
|
2272
|
+
)
|
|
2273
|
+
# The same is true for functions:
|
|
2274
|
+
yield Case(
|
|
2275
|
+
stub="""
|
|
2276
|
+
@type_check_only
|
|
2277
|
+
def func1() -> None: ...
|
|
2278
|
+
""",
|
|
2279
|
+
runtime="",
|
|
2280
|
+
error=None,
|
|
2281
|
+
)
|
|
2282
|
+
yield Case(
|
|
2283
|
+
stub="""
|
|
2284
|
+
@type_check_only
|
|
2285
|
+
def func2() -> None: ...
|
|
2286
|
+
""",
|
|
2287
|
+
runtime="def func2() -> None: ...",
|
|
2288
|
+
error="func2",
|
|
2289
|
+
)
|
|
2290
|
+
|
|
2291
|
+
|
|
2292
|
+
def remove_color_code(s: str) -> str:
|
|
2293
|
+
return re.sub("\\x1b.*?m", "", s) # this works!
|
|
2294
|
+
|
|
2295
|
+
|
|
2296
|
+
class StubtestMiscUnit(unittest.TestCase):
|
|
2297
|
+
def test_output(self) -> None:
|
|
2298
|
+
output = run_stubtest(
|
|
2299
|
+
stub="def bad(number: int, text: str) -> None: ...",
|
|
2300
|
+
runtime="def bad(num, text): pass",
|
|
2301
|
+
options=[],
|
|
2302
|
+
)
|
|
2303
|
+
expected = (
|
|
2304
|
+
f'error: {TEST_MODULE_NAME}.bad is inconsistent, stub argument "number" differs '
|
|
2305
|
+
'from runtime argument "num"\n'
|
|
2306
|
+
f"Stub: in file {TEST_MODULE_NAME}.pyi:1\n"
|
|
2307
|
+
"def (number: builtins.int, text: builtins.str)\n"
|
|
2308
|
+
f"Runtime: in file {TEST_MODULE_NAME}.py:1\ndef (num, text)\n\n"
|
|
2309
|
+
"Found 1 error (checked 1 module)\n"
|
|
2310
|
+
)
|
|
2311
|
+
assert output == expected
|
|
2312
|
+
|
|
2313
|
+
output = run_stubtest(
|
|
2314
|
+
stub="def bad(number: int, text: str) -> None: ...",
|
|
2315
|
+
runtime="def bad(num, text): pass",
|
|
2316
|
+
options=["--concise"],
|
|
2317
|
+
)
|
|
2318
|
+
expected = (
|
|
2319
|
+
"{}.bad is inconsistent, "
|
|
2320
|
+
'stub argument "number" differs from runtime argument "num"\n'.format(TEST_MODULE_NAME)
|
|
2321
|
+
)
|
|
2322
|
+
assert output == expected
|
|
2323
|
+
|
|
2324
|
+
def test_ignore_flags(self) -> None:
|
|
2325
|
+
output = run_stubtest(
|
|
2326
|
+
stub="", runtime="__all__ = ['f']\ndef f(): pass", options=["--ignore-missing-stub"]
|
|
2327
|
+
)
|
|
2328
|
+
assert output == "Success: no issues found in 1 module\n"
|
|
2329
|
+
|
|
2330
|
+
output = run_stubtest(stub="", runtime="def f(): pass", options=["--ignore-missing-stub"])
|
|
2331
|
+
assert output == "Success: no issues found in 1 module\n"
|
|
2332
|
+
|
|
2333
|
+
output = run_stubtest(
|
|
2334
|
+
stub="def f(__a): ...", runtime="def f(a): pass", options=["--ignore-positional-only"]
|
|
2335
|
+
)
|
|
2336
|
+
assert output == "Success: no issues found in 1 module\n"
|
|
2337
|
+
|
|
2338
|
+
def test_allowlist(self) -> None:
|
|
2339
|
+
# Can't use this as a context because Windows
|
|
2340
|
+
allowlist = tempfile.NamedTemporaryFile(mode="w+", delete=False)
|
|
2341
|
+
try:
|
|
2342
|
+
with allowlist:
|
|
2343
|
+
allowlist.write(f"{TEST_MODULE_NAME}.bad # comment\n# comment")
|
|
2344
|
+
|
|
2345
|
+
output = run_stubtest(
|
|
2346
|
+
stub="def bad(number: int, text: str) -> None: ...",
|
|
2347
|
+
runtime="def bad(asdf, text): pass",
|
|
2348
|
+
options=["--allowlist", allowlist.name],
|
|
2349
|
+
)
|
|
2350
|
+
assert output == "Success: no issues found in 1 module\n"
|
|
2351
|
+
|
|
2352
|
+
# test unused entry detection
|
|
2353
|
+
output = run_stubtest(stub="", runtime="", options=["--allowlist", allowlist.name])
|
|
2354
|
+
assert output == (
|
|
2355
|
+
f"note: unused allowlist entry {TEST_MODULE_NAME}.bad\n"
|
|
2356
|
+
"Found 1 error (checked 1 module)\n"
|
|
2357
|
+
)
|
|
2358
|
+
|
|
2359
|
+
output = run_stubtest(
|
|
2360
|
+
stub="",
|
|
2361
|
+
runtime="",
|
|
2362
|
+
options=["--allowlist", allowlist.name, "--ignore-unused-allowlist"],
|
|
2363
|
+
)
|
|
2364
|
+
assert output == "Success: no issues found in 1 module\n"
|
|
2365
|
+
|
|
2366
|
+
# test regex matching
|
|
2367
|
+
with open(allowlist.name, mode="w+") as f:
|
|
2368
|
+
f.write(f"{TEST_MODULE_NAME}.b.*\n")
|
|
2369
|
+
f.write("(unused_missing)?\n")
|
|
2370
|
+
f.write("unused.*\n")
|
|
2371
|
+
|
|
2372
|
+
output = run_stubtest(
|
|
2373
|
+
stub=textwrap.dedent(
|
|
2374
|
+
"""
|
|
2375
|
+
def good() -> None: ...
|
|
2376
|
+
def bad(number: int) -> None: ...
|
|
2377
|
+
def also_bad(number: int) -> None: ...
|
|
2378
|
+
""".lstrip(
|
|
2379
|
+
"\n"
|
|
2380
|
+
)
|
|
2381
|
+
),
|
|
2382
|
+
runtime=textwrap.dedent(
|
|
2383
|
+
"""
|
|
2384
|
+
def good(): pass
|
|
2385
|
+
def bad(asdf): pass
|
|
2386
|
+
def also_bad(asdf): pass
|
|
2387
|
+
""".lstrip(
|
|
2388
|
+
"\n"
|
|
2389
|
+
)
|
|
2390
|
+
),
|
|
2391
|
+
options=["--allowlist", allowlist.name, "--generate-allowlist"],
|
|
2392
|
+
)
|
|
2393
|
+
assert output == (
|
|
2394
|
+
f"note: unused allowlist entry unused.*\n{TEST_MODULE_NAME}.also_bad\n"
|
|
2395
|
+
)
|
|
2396
|
+
finally:
|
|
2397
|
+
os.unlink(allowlist.name)
|
|
2398
|
+
|
|
2399
|
+
def test_mypy_build(self) -> None:
|
|
2400
|
+
output = run_stubtest(stub="+", runtime="", options=[])
|
|
2401
|
+
assert output == (
|
|
2402
|
+
"error: not checking stubs due to failed mypy compile:\n{}.pyi:1: "
|
|
2403
|
+
"error: invalid syntax [syntax]\n".format(TEST_MODULE_NAME)
|
|
2404
|
+
)
|
|
2405
|
+
|
|
2406
|
+
output = run_stubtest(stub="def f(): ...\ndef f(): ...", runtime="", options=[])
|
|
2407
|
+
assert output == (
|
|
2408
|
+
"error: not checking stubs due to mypy build errors:\n{}.pyi:2: "
|
|
2409
|
+
'error: Name "f" already defined on line 1 [no-redef]\n'.format(TEST_MODULE_NAME)
|
|
2410
|
+
)
|
|
2411
|
+
|
|
2412
|
+
def test_missing_stubs(self) -> None:
|
|
2413
|
+
output = io.StringIO()
|
|
2414
|
+
with contextlib.redirect_stdout(output):
|
|
2415
|
+
test_stubs(parse_options(["not_a_module"]))
|
|
2416
|
+
assert remove_color_code(output.getvalue()) == (
|
|
2417
|
+
"error: not_a_module failed to find stubs\n"
|
|
2418
|
+
"Stub:\nMISSING\nRuntime:\nN/A\n\n"
|
|
2419
|
+
"Found 1 error (checked 1 module)\n"
|
|
2420
|
+
)
|
|
2421
|
+
|
|
2422
|
+
def test_only_py(self) -> None:
|
|
2423
|
+
# in this case, stubtest will check the py against itself
|
|
2424
|
+
# this is useful to support packages with a mix of stubs and inline types
|
|
2425
|
+
with use_tmp_dir(TEST_MODULE_NAME):
|
|
2426
|
+
with open(f"{TEST_MODULE_NAME}.py", "w") as f:
|
|
2427
|
+
f.write("a = 1")
|
|
2428
|
+
output = io.StringIO()
|
|
2429
|
+
with contextlib.redirect_stdout(output):
|
|
2430
|
+
test_stubs(parse_options([TEST_MODULE_NAME]))
|
|
2431
|
+
output_str = remove_color_code(output.getvalue())
|
|
2432
|
+
assert output_str == "Success: no issues found in 1 module\n"
|
|
2433
|
+
|
|
2434
|
+
def test_get_typeshed_stdlib_modules(self) -> None:
|
|
2435
|
+
stdlib = mypy.stubtest.get_typeshed_stdlib_modules(None, (3, 7))
|
|
2436
|
+
assert "builtins" in stdlib
|
|
2437
|
+
assert "os" in stdlib
|
|
2438
|
+
assert "os.path" in stdlib
|
|
2439
|
+
assert "asyncio" in stdlib
|
|
2440
|
+
assert "graphlib" not in stdlib
|
|
2441
|
+
assert "formatter" in stdlib
|
|
2442
|
+
assert "contextvars" in stdlib # 3.7+
|
|
2443
|
+
assert "importlib.metadata" not in stdlib
|
|
2444
|
+
|
|
2445
|
+
stdlib = mypy.stubtest.get_typeshed_stdlib_modules(None, (3, 10))
|
|
2446
|
+
assert "graphlib" in stdlib
|
|
2447
|
+
assert "formatter" not in stdlib
|
|
2448
|
+
assert "importlib.metadata" in stdlib
|
|
2449
|
+
|
|
2450
|
+
def test_signature(self) -> None:
|
|
2451
|
+
def f(a: int, b: int, *, c: int, d: int = 0, **kwargs: Any) -> None:
|
|
2452
|
+
pass
|
|
2453
|
+
|
|
2454
|
+
assert (
|
|
2455
|
+
str(mypy.stubtest.Signature.from_inspect_signature(inspect.signature(f)))
|
|
2456
|
+
== "def (a, b, *, c, d = ..., **kwargs)"
|
|
2457
|
+
)
|
|
2458
|
+
|
|
2459
|
+
def test_builtin_signature_with_unrepresentable_default(self) -> None:
|
|
2460
|
+
sig = mypy.stubtest.safe_inspect_signature(bytes.hex)
|
|
2461
|
+
assert sig is not None
|
|
2462
|
+
assert (
|
|
2463
|
+
str(mypy.stubtest.Signature.from_inspect_signature(sig))
|
|
2464
|
+
== "def (self, sep = ..., bytes_per_sep = ...)"
|
|
2465
|
+
)
|
|
2466
|
+
|
|
2467
|
+
def test_config_file(self) -> None:
|
|
2468
|
+
runtime = "temp = 5\n"
|
|
2469
|
+
stub = "from decimal import Decimal\ntemp: Decimal\n"
|
|
2470
|
+
config_file = f"[mypy]\nplugins={root_dir}/test-data/unit/plugins/decimal_to_int.py\n"
|
|
2471
|
+
output = run_stubtest(stub=stub, runtime=runtime, options=[])
|
|
2472
|
+
assert output == (
|
|
2473
|
+
f"error: {TEST_MODULE_NAME}.temp variable differs from runtime type Literal[5]\n"
|
|
2474
|
+
f"Stub: in file {TEST_MODULE_NAME}.pyi:2\n_decimal.Decimal\nRuntime:\n5\n\n"
|
|
2475
|
+
"Found 1 error (checked 1 module)\n"
|
|
2476
|
+
)
|
|
2477
|
+
output = run_stubtest(stub=stub, runtime=runtime, options=[], config_file=config_file)
|
|
2478
|
+
assert output == "Success: no issues found in 1 module\n"
|
|
2479
|
+
|
|
2480
|
+
def test_no_modules(self) -> None:
|
|
2481
|
+
output = io.StringIO()
|
|
2482
|
+
with contextlib.redirect_stdout(output):
|
|
2483
|
+
test_stubs(parse_options([]))
|
|
2484
|
+
assert remove_color_code(output.getvalue()) == "error: no modules to check\n"
|
|
2485
|
+
|
|
2486
|
+
def test_module_and_typeshed(self) -> None:
|
|
2487
|
+
output = io.StringIO()
|
|
2488
|
+
with contextlib.redirect_stdout(output):
|
|
2489
|
+
test_stubs(parse_options(["--check-typeshed", "some_module"]))
|
|
2490
|
+
assert remove_color_code(output.getvalue()) == (
|
|
2491
|
+
"error: cannot pass both --check-typeshed and a list of modules\n"
|
|
2492
|
+
)
|