mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
update to latest mypy
mypy's move to external types-* packages is a PITA, as it requires them to be installed in site-packages, and provides no way to specify a custom site-packages folder, necessitating extra scripts to mock the site-packages path, and copy+rename the stub packages into a separate folder.
This commit is contained in:
parent
d7340d3f07
commit
d120cd7f8a
12 changed files with 186 additions and 11 deletions
|
@ -20,8 +20,15 @@ requests[socks]
|
||||||
send2trash
|
send2trash
|
||||||
snakeviz
|
snakeviz
|
||||||
stringcase
|
stringcase
|
||||||
waitress>=2.0.0b1
|
waitress>=2.0.0
|
||||||
fluent.syntax
|
fluent.syntax
|
||||||
|
types-decorator
|
||||||
|
types-flask
|
||||||
|
types-markdown
|
||||||
|
types-orjson
|
||||||
|
types-protobuf
|
||||||
|
types-requests
|
||||||
|
types-waitress
|
||||||
|
|
||||||
# windows only
|
# windows only
|
||||||
psutil; sys.platform == "win32"
|
psutil; sys.platform == "win32"
|
||||||
|
|
|
@ -12,7 +12,7 @@ attrs==21.2.0
|
||||||
# pytest
|
# pytest
|
||||||
beautifulsoup4==4.9.3
|
beautifulsoup4==4.9.3
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
black==21.5b2
|
black==21.6b0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
certifi==2021.5.30
|
certifi==2021.5.30
|
||||||
# via requests
|
# via requests
|
||||||
|
@ -75,7 +75,7 @@ mypy-extensions==0.4.3
|
||||||
# mypy
|
# mypy
|
||||||
mypy-protobuf==2.4
|
mypy-protobuf==2.4
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
mypy==0.812
|
mypy==0.902
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
orjson==3.5.3
|
orjson==3.5.3
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
@ -89,7 +89,7 @@ pip-tools==6.1.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
pluggy==0.13.1
|
pluggy==0.13.1
|
||||||
# via pytest
|
# via pytest
|
||||||
protobuf==3.17.1
|
protobuf==3.17.3
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
# mypy-protobuf
|
# mypy-protobuf
|
||||||
|
@ -132,13 +132,36 @@ stringcase==1.2.0
|
||||||
toml==0.10.2
|
toml==0.10.2
|
||||||
# via
|
# via
|
||||||
# black
|
# black
|
||||||
|
# mypy
|
||||||
# pep517
|
# pep517
|
||||||
# pylint
|
# pylint
|
||||||
# pytest
|
# pytest
|
||||||
tornado==6.1
|
tornado==6.1
|
||||||
# via snakeviz
|
# via snakeviz
|
||||||
typed-ast==1.4.3
|
types-click==7.1.1
|
||||||
# via mypy
|
# via types-flask
|
||||||
|
types-decorator==0.1.4
|
||||||
|
# via -r requirements.in
|
||||||
|
types-flask==1.1.0
|
||||||
|
# via -r requirements.in
|
||||||
|
types-futures==0.1.3
|
||||||
|
# via types-protobuf
|
||||||
|
types-jinja2==2.11.1
|
||||||
|
# via types-flask
|
||||||
|
types-markdown==0.1.4
|
||||||
|
# via -r requirements.in
|
||||||
|
types-markupsafe==1.1.2
|
||||||
|
# via types-jinja2
|
||||||
|
types-orjson==0.1.0
|
||||||
|
# via -r requirements.in
|
||||||
|
types-protobuf==0.1.12
|
||||||
|
# via -r requirements.in
|
||||||
|
types-requests==0.1.11
|
||||||
|
# via -r requirements.in
|
||||||
|
types-waitress==0.1.6
|
||||||
|
# via -r requirements.in
|
||||||
|
types-werkzeug==1.0.1
|
||||||
|
# via types-flask
|
||||||
typing-extensions==3.10.0.0
|
typing-extensions==3.10.0.0
|
||||||
# via mypy
|
# via mypy
|
||||||
urllib3==1.26.5
|
urllib3==1.26.5
|
||||||
|
|
42
pip/stubs/BUILD.bazel
Normal file
42
pip/stubs/BUILD.bazel
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
|
||||||
|
load("@py_deps//:requirements.bzl", "requirement")
|
||||||
|
load(":stubs.bzl", "copy_stubs")
|
||||||
|
|
||||||
|
_stubs = [
|
||||||
|
"requests",
|
||||||
|
"protobuf",
|
||||||
|
"decorator",
|
||||||
|
"flask",
|
||||||
|
"markdown",
|
||||||
|
"orjson",
|
||||||
|
"waitress",
|
||||||
|
]
|
||||||
|
|
||||||
|
py_binary(
|
||||||
|
name = "gatherstubs",
|
||||||
|
srcs = [
|
||||||
|
"gatherstubs.py",
|
||||||
|
],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
requirement("mypy"),
|
||||||
|
] + [requirement("types-" + stub) for stub in _stubs],
|
||||||
|
)
|
||||||
|
|
||||||
|
py_binary(
|
||||||
|
name = "extendsitepkgs",
|
||||||
|
srcs = [
|
||||||
|
"extendsitepkgs.py",
|
||||||
|
],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
requirement("mypy"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
copy_stubs(
|
||||||
|
name = "stubs",
|
||||||
|
pkgs = [requirement("types-" + stub) for stub in _stubs],
|
||||||
|
tool = ":gatherstubs",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
2
pip/stubs/README.md
Normal file
2
pip/stubs/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
mypy 0.9 assumes stub files will be installed in site-packages, but they are not
|
||||||
|
in Bazel's case, so we need to hack around the issue.
|
10
pip/stubs/extendsitepkgs.py
Normal file
10
pip/stubs/extendsitepkgs.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
import os
|
||||||
|
from mypy import sitepkgs
|
||||||
|
|
||||||
|
pkgs = sitepkgs.getsitepackages()
|
||||||
|
pkgs.append(os.getenv("EXTRA_SITE_PACKAGES"))
|
||||||
|
|
||||||
|
print(pkgs)
|
30
pip/stubs/gatherstubs.py
Normal file
30
pip/stubs/gatherstubs.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
stubs_remap = {"protobuf": "google", "futures": "concurrent"}
|
||||||
|
|
||||||
|
|
||||||
|
def copy_folder(pkgname, path, outbase):
|
||||||
|
stubname = stubs_remap.get(pkgname, pkgname)
|
||||||
|
os.listdir(path)
|
||||||
|
path = f"{path}/{stubname}-stubs"
|
||||||
|
shutil.copytree(path, os.path.join(outbase, f"{stubname}-stubs"))
|
||||||
|
|
||||||
|
|
||||||
|
name_re = re.compile("__types_(.+?)_\d")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
outbase = os.path.abspath(sys.argv[1])
|
||||||
|
|
||||||
|
# copy stubs into top level folder, renaming
|
||||||
|
folder = os.path.join(os.path.dirname(__file__), "../../external")
|
||||||
|
os.chdir(folder)
|
||||||
|
for folder in os.listdir("."):
|
||||||
|
if match := name_re.search(folder):
|
||||||
|
copy_folder(match.group(1), folder, outbase)
|
20
pip/stubs/stubs.bzl
Normal file
20
pip/stubs/stubs.bzl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
def _copy_stubs_impl(ctx):
|
||||||
|
dir = ctx.actions.declare_directory("stubs")
|
||||||
|
ctx.actions.run(
|
||||||
|
outputs = [dir],
|
||||||
|
inputs = ctx.files.pkgs,
|
||||||
|
executable = ctx.executable.tool,
|
||||||
|
arguments = [dir.path],
|
||||||
|
use_default_shell_env = True,
|
||||||
|
)
|
||||||
|
return [
|
||||||
|
DefaultInfo(files = depset([dir]), data_runfiles = ctx.runfiles(files = [dir])),
|
||||||
|
]
|
||||||
|
|
||||||
|
copy_stubs = rule(
|
||||||
|
implementation = _copy_stubs_impl,
|
||||||
|
attrs = {
|
||||||
|
"pkgs": attr.label_list(),
|
||||||
|
"tool": attr.label(executable = True, cfg = "host"),
|
||||||
|
},
|
||||||
|
)
|
|
@ -20,8 +20,14 @@ py_test(
|
||||||
args = [
|
args = [
|
||||||
"anki",
|
"anki",
|
||||||
"$(location mypy.ini)",
|
"$(location mypy.ini)",
|
||||||
|
"$(location //pip/stubs:extendsitepkgs)",
|
||||||
],
|
],
|
||||||
data = ["mypy.ini"],
|
data = [
|
||||||
|
"mypy.ini",
|
||||||
|
"//pip/stubs",
|
||||||
|
"//pip/stubs:extendsitepkgs",
|
||||||
|
],
|
||||||
|
env = {"EXTRA_SITE_PACKAGES": "$(location //pip/stubs)"},
|
||||||
main = "tests/run_mypy.py",
|
main = "tests/run_mypy.py",
|
||||||
deps = [
|
deps = [
|
||||||
"//pylib/anki",
|
"//pylib/anki",
|
||||||
|
|
|
@ -6,13 +6,26 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
(module, ini) = sys.argv[1:]
|
(module, ini, extendsitepkgs) = sys.argv[1:]
|
||||||
ini = os.path.abspath(ini)
|
ini = os.path.abspath(ini)
|
||||||
|
extendsitepkgs = os.path.abspath(extendsitepkgs)
|
||||||
|
extra_site = os.path.abspath(os.getenv("EXTRA_SITE_PACKAGES"))
|
||||||
|
|
||||||
folder = os.path.join(os.path.dirname(__file__), "..")
|
folder = os.path.join(os.path.dirname(__file__), "..")
|
||||||
os.chdir(folder)
|
os.chdir(folder)
|
||||||
|
|
||||||
args = [sys.executable, "-m", "mypy", module, "--config-file", ini]
|
args = [
|
||||||
|
sys.executable,
|
||||||
|
"-m",
|
||||||
|
"mypy",
|
||||||
|
module,
|
||||||
|
"--config-file",
|
||||||
|
ini,
|
||||||
|
"--python-executable",
|
||||||
|
extendsitepkgs,
|
||||||
|
]
|
||||||
|
|
||||||
|
os.environ["EXTRA_SITE_PACKAGES"] = extra_site
|
||||||
|
|
||||||
if sys.platform.startswith("win32"):
|
if sys.platform.startswith("win32"):
|
||||||
# bazel passes in \\?\c:\... path; mypy can't handle it, so we
|
# bazel passes in \\?\c:\... path; mypy can't handle it, so we
|
||||||
|
|
|
@ -46,11 +46,15 @@ py_test(
|
||||||
"aqt",
|
"aqt",
|
||||||
"$(location mypy.ini)",
|
"$(location mypy.ini)",
|
||||||
"$(location @pyqt5//:__init__.py)",
|
"$(location @pyqt5//:__init__.py)",
|
||||||
|
"$(location //pip/stubs:extendsitepkgs)",
|
||||||
],
|
],
|
||||||
data = [
|
data = [
|
||||||
"mypy.ini",
|
"mypy.ini",
|
||||||
|
"//pip/stubs",
|
||||||
|
"//pip/stubs:extendsitepkgs",
|
||||||
"@pyqt5//:__init__.py",
|
"@pyqt5//:__init__.py",
|
||||||
],
|
],
|
||||||
|
env = {"EXTRA_SITE_PACKAGES": "$(location //pip/stubs)"},
|
||||||
main = "tests/run_mypy.py",
|
main = "tests/run_mypy.py",
|
||||||
deps = [
|
deps = [
|
||||||
"//pylib/anki",
|
"//pylib/anki",
|
||||||
|
@ -137,7 +141,10 @@ py_binary(
|
||||||
data = [
|
data = [
|
||||||
# ensure the binary's been built
|
# ensure the binary's been built
|
||||||
"//pip:dmypy",
|
"//pip:dmypy",
|
||||||
|
"//pip/stubs",
|
||||||
|
"//pip/stubs:extendsitepkgs",
|
||||||
],
|
],
|
||||||
|
env = {"EXTRA_SITE_PACKAGES": "$(location //pip/stubs)"},
|
||||||
imports = ["."],
|
imports = ["."],
|
||||||
tags = ["manual"],
|
tags = ["manual"],
|
||||||
deps = [
|
deps = [
|
||||||
|
|
|
@ -32,9 +32,12 @@ if subprocess.run(
|
||||||
"qt/mypy.ini",
|
"qt/mypy.ini",
|
||||||
"bazel-bin/qt/dmypy.runfiles/net_ankiweb_anki/pylib/anki",
|
"bazel-bin/qt/dmypy.runfiles/net_ankiweb_anki/pylib/anki",
|
||||||
"bazel-bin/qt/dmypy.runfiles/net_ankiweb_anki/qt/aqt",
|
"bazel-bin/qt/dmypy.runfiles/net_ankiweb_anki/qt/aqt",
|
||||||
|
"--python-executable",
|
||||||
|
os.path.abspath("pip/stubs/extendsitepkgs"),
|
||||||
],
|
],
|
||||||
env={
|
env={
|
||||||
"MYPYPATH": "bazel-bin/qt/dmypy.runfiles/pyqt5",
|
"MYPYPATH": "bazel-bin/qt/dmypy.runfiles/pyqt5",
|
||||||
|
"EXTRA_SITE_PACKAGES": os.path.abspath(os.getenv("EXTRA_SITE_PACKAGES")),
|
||||||
},
|
},
|
||||||
cwd=workspace,
|
cwd=workspace,
|
||||||
).returncode:
|
).returncode:
|
||||||
|
|
|
@ -6,10 +6,12 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
(module, ini, pyqt_init) = sys.argv[1:]
|
(module, ini, pyqt_init, extendsitepkgs) = sys.argv[1:]
|
||||||
ini = os.path.abspath(ini)
|
ini = os.path.abspath(ini)
|
||||||
pyqt_init = os.path.abspath(pyqt_init)
|
pyqt_init = os.path.abspath(pyqt_init)
|
||||||
pyqt_folder = os.path.dirname(pyqt_init)
|
pyqt_folder = os.path.dirname(pyqt_init)
|
||||||
|
extendsitepkgs = os.path.abspath(extendsitepkgs)
|
||||||
|
extra_site = os.path.abspath(os.getenv("EXTRA_SITE_PACKAGES"))
|
||||||
|
|
||||||
folder = os.path.join(os.path.dirname(__file__), "..")
|
folder = os.path.join(os.path.dirname(__file__), "..")
|
||||||
os.chdir(folder)
|
os.chdir(folder)
|
||||||
|
@ -20,8 +22,18 @@ if __name__ == "__main__":
|
||||||
mypy_path = ".:../pylib:" + pyqt_folder
|
mypy_path = ".:../pylib:" + pyqt_folder
|
||||||
|
|
||||||
os.environ["MYPYPATH"] = mypy_path
|
os.environ["MYPYPATH"] = mypy_path
|
||||||
|
os.environ["EXTRA_SITE_PACKAGES"] = extra_site
|
||||||
|
|
||||||
args = [sys.executable, "-m", "mypy", module, "--config-file", ini]
|
args = [
|
||||||
|
sys.executable,
|
||||||
|
"-m",
|
||||||
|
"mypy",
|
||||||
|
module,
|
||||||
|
"--config-file",
|
||||||
|
ini,
|
||||||
|
"--python-executable",
|
||||||
|
extendsitepkgs,
|
||||||
|
]
|
||||||
|
|
||||||
if sys.platform.startswith("win32"):
|
if sys.platform.startswith("win32"):
|
||||||
# bazel passes in \\?\c:\... path; mypy can't handle it, so we
|
# bazel passes in \\?\c:\... path; mypy can't handle it, so we
|
||||||
|
|
Loading…
Reference in a new issue