diff --git a/.efrocachemap b/.efrocachemap index 56d3fb66..6cf03f6d 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4068,26 +4068,26 @@ "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "8624f0d3fa5414204d138a8476e9e460", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "2587621d0c3048ef54bc4bb16d89f481", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "05fae5b1cd78420264b47845a3906878", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "54630e134d422ed010f66cfade0a7039", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "55a876ca75282829290734a6ac66317a", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "2a52aa57bd46c9fd9d3b775932a4cd2f", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "4e6545a90d26c03c27813da58b478190", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "b3ba73ebad2f3a0b256d85b14e97cef5", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "98d9cfb5f00591c868b9ccbee52fa9e5", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "a29c7ef8e1ab1152bbb1cc19c8d618e6", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "b06f66e40e56760b1c4e6219d69f4d0f", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "809817f1aad7de3560b09b76d3995120", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "7e26218e4ed4fb7e316b7e1faee7aa5a", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "e8059a5654ba9a52e0fd59e5f8802fbc", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "2649fb0d26b27025da149be404369505", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "9378675f3ca191b8e5562017993232e9", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "318110d18dc080bbe8ca0bebf4243e3f", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "66d49b0c135475f76056849bfc9259fd", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4b8fe7d5454d1dc3383ecba3a6f75d13", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "a87c9018c9846a27596012b6689ddbd2", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "2668b413da2d1dd597a6a6b8c6ae9ee8", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "5d38798c383cae78c227c427ae967281", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "0df69387ebe2fb149694a267a1df4c24", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "153abebe70483d17d933127e894908c4", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "fd6768fe1167b8e24db5eb9e33360456", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "8377309f0d570de541e9210752463bab", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "b4b774fef02d72f58f8083430cbc8334", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9b100c7bf923a8f01de1b5984f62e7e5", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ac5ecfa5b0e10bcc0d333875bfff9d29", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "241d315d379eb10ec7c2c7ccc8efa99e", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "9d57aaf4d56398e67695659eedce569c", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "d22fdee9f1355dd8965f56a97518ad85", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "b85955e00c3a076af273849fd436b18c", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "a044700e51b426cd333ab32308bfc033", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "e4bcb7821639ffb7e5b0616d509d3c3d", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "91a3fcefaf965260efb388f4477c8ce3", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "4a54dbbe24033a862a2dac3eb76f98b3", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c82081e53a00d198137c934efae1ed72", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "d8ee381eafbca03eee21e1218935f499", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f6e6fc30a1d2a3ccb2d5f43bf91c4402", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "498921f7eb2afd327d4b900cb70e31f9", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f", @@ -4104,14 +4104,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "92394eb19387c363471ce134ac9e6a1b", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "496f928d8cb2b2d1098c43c708d3aa85", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "f410fb4c2404475130e1a293e9dd6619", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "9326d4bc4859604e48c7f7e673880f1a", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "3a61d82f6d9a2f6fbda245d7cdab1bbd", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "95052b835c2bf55292f1982a1be2e54b", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "82265f3b1c5a4cbb44369ce37ed76ebd", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "47bd30d45ba7b779488e0435f0492dc1", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "4c049db7c0a8311852f742083e8df3ae", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "0016db9bd4fbf158d19f5a6e84aa2f74", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "40c9f4c7076ef9013dde9afd05d89b95", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "4e74f1959b833486aa1cee0affa1aaef", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "4e39a9a8222a683aa074a0698c26c498", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "9509a8782beb8fd0fc477d0afe3cc6c0", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "091fd49e9c75b202b4f481b65f91a100", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "87567923e411e713f82429f56abd9d84", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "5e6707e7b299474ae4a43a1df2919a55", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318", "src/ballistica/base/mgen/pyembed/binding_base.inc": "eeddad968b176000e31c65be6206a2bc", diff --git a/.gitignore b/.gitignore index d5e260ad..f8268232 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ local.properties .mypy_cache .pytest_cache .mypy.ini +.pyrightconfig.json .pycheckers .flycheck-dir-locals.el .pylintrc diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index 1573004c..535342e7 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -2385,6 +2385,7 @@ pyobjc pyoffs pypaths + pyrightconfig pysitedir pysources pytest diff --git a/CHANGELOG.md b/CHANGELOG.md index c98b385c..69f2c519 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.25 (build 21204, api 8, 2023-07-28) +### 1.7.25 (build 21206, api 8, 2023-07-29) - `getconfig` and `setconfig` in `efrotools` are now `getprojectconfig` and `setprojectconfig` (to reflect the file name changes that happened in 1.7.20). @@ -47,7 +47,7 @@ ourselves inside a standalone binary, is called 'monolithic'. To build and run Ballistica in modular form, you can do `make cmake-modular` or `make cmake-modular-server`. This should make it easier to use certain things like - Python debuggers with Ballistica. While I expect most builds of the game to + Python debuggers with Ballistica. While I expect most builds of the engine to remain monolithic, this may become the default for certain situations such as server builds or possibly Linux builds if it seems beneficial. We'll see. Modular mode should work on Linux and Mac currently; other platforms remain diff --git a/Makefile b/Makefile index cd5af619..9fc5eb31 100644 --- a/Makefile +++ b/Makefile @@ -37,8 +37,9 @@ endif # Prereq targets that should be safe to run anytime; even if project-files # are out of date. -PREREQS_SAFE = .cache/checkenv .dir-locals.el .mypy.ini .pycheckers .pylintrc \ - .style.yapf .clang-format ballisticakit-cmake/.clang-format .editorconfig +PREREQS_SAFE = .cache/checkenv .dir-locals.el .mypy.ini .pyrightconfig.json \ + .pycheckers .pylintrc .style.yapf .clang-format \ + ballisticakit-cmake/.clang-format .editorconfig # Prereq targets that may break if the project needs updating should go here. # An example is compile-command-databases; these might try to run cmake and @@ -798,6 +799,10 @@ dmypy: py_check_prereqs dmypy-stop: py_check_prereqs @tools/pcommand dmypy -stop +# Run Pyright checks on all Python code. +pyright: py_check_prereqs + @tools/pcommand pyright + # Run PyCharm checks on all Python code. pycharm: py_check_prereqs @tools/pcommand pycharm @@ -1188,6 +1193,9 @@ ENV_SRC = tools/pcommand tools/batools/build.py .mypy.ini: config/toolconfigsrc/mypy.ini $(TOOL_CFG_SRC) @$(TOOL_CFG_INST) $< $@ +.pyrightconfig.json: config/toolconfigsrc/pyrightconfig.json $(TOOL_CFG_SRC) + @$(TOOL_CFG_INST) $< $@ + .pycheckers: config/toolconfigsrc/pycheckers $(TOOL_CFG_SRC) @$(TOOL_CFG_INST) $< $@ diff --git a/ballisticakit-cmake/.idea/dictionaries/ericf.xml b/ballisticakit-cmake/.idea/dictionaries/ericf.xml index 8a6af652..5d3c5eae 100644 --- a/ballisticakit-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticakit-cmake/.idea/dictionaries/ericf.xml @@ -1395,6 +1395,7 @@ pymodulenames pyobj pyobjs + pyrightconfig pysitedir pythondevmode pythonenumsmodule diff --git a/config/spinoffconfig.py b/config/spinoffconfig.py index 79201a04..00d0f51e 100644 --- a/config/spinoffconfig.py +++ b/config/spinoffconfig.py @@ -217,6 +217,7 @@ ctx.no_filter_file_names = { # ELSE files with these extensions WILL be filtered. ctx.filter_file_extensions = { '.py', + '.pyi', '.md', '.cpp', '.cc', diff --git a/config/toolconfigsrc/pyrightconfig.json b/config/toolconfigsrc/pyrightconfig.json new file mode 100644 index 00000000..4a4f9044 --- /dev/null +++ b/config/toolconfigsrc/pyrightconfig.json @@ -0,0 +1,9 @@ +{ + "include": [ + "tools" + ], + "typeCheckingMode": "basic", + "reportMissingTypeStubs": true, + "stubPath": "src/stubs", + "pythonPlatform": "Linux" +} diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 3a005a6e..95e1b4b7 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -50,7 +50,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21204 +TARGET_BALLISTICA_BUILD = 21206 TARGET_BALLISTICA_VERSION = '1.7.25' diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index fc428350..5de4aa6e 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21204; +const int kEngineBuildNumber = 21206; const char* kEngineVersion = "1.7.25"; #if BA_MONOLITHIC_BUILD diff --git a/src/ballistica/shared/python/python_command.cc b/src/ballistica/shared/python/python_command.cc index 04d82510..ab04999f 100644 --- a/src/ballistica/shared/python/python_command.cc +++ b/src/ballistica/shared/python/python_command.cc @@ -8,8 +8,9 @@ // Save/restore current command for logging/etc. // this isn't exception-safe, but we should never let -// exceptions bubble up through python api calls anyway +// exceptions bubble up through Python api calls anyway // or we'll have bigger problems on our hands. +// FIXME: What about thread safety? Seems like this isn't. #define PUSH_PYCOMMAND(OBJ) \ PythonCommand* prev_pycmd = current_command_; \ current_command_ = OBJ @@ -180,11 +181,8 @@ auto PythonCommand::Eval(bool print_errors, PyObject* globals, PyObject* locals) .Get(); } -#pragma clang diagnostic push -#pragma ide diagnostic ignored "RedundantCast" assert(PyDict_Check(globals)); assert(PyDict_Check(locals)); -#pragma clang diagnostic pop if (!eval_code_obj_.Get()) { CompileForEval(print_errors); diff --git a/src/ballistica/shared/python/python_command.h b/src/ballistica/shared/python/python_command.h index f3a84095..a0a34704 100644 --- a/src/ballistica/shared/python/python_command.h +++ b/src/ballistica/shared/python/python_command.h @@ -15,11 +15,11 @@ namespace ballistica { // Note to self: Originally I though I'd be using this in a lot of places, // so I added the ability to compile once and run repeatedly, quietly // capture output instead of printing it, etc. Now, however, its usage is -// pretty much limited to a few places such as handling stdin and the -// in-app console. (Most places it is much cleaner to work with proper -// python modules and just interact with PyObject* refs to them) I should -// look and see if python's default high level calls would suffice for these -// purposes and potentially kill this off. +// pretty much limited to a few places such as handling stdin and the in-app +// console. Most places it is much cleaner to work with proper python +// modules and just interact with PyObject* refs to them. I should look and +// see if Python's default high level calls would suffice for these purposes +// and potentially kill this off. class PythonCommand { public: PythonCommand(); @@ -58,7 +58,7 @@ class PythonCommand { void CompileForEval(bool print_errors); private: - bool dead_ = false; + bool dead_{}; PythonRef file_code_obj_; PythonRef eval_code_obj_; std::string command_; diff --git a/src/stubs/ansiwrap.pyi b/src/stubs/ansiwrap.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/ansiwrap.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/src/stubs/astroid/__init__.pyi b/src/stubs/astroid/__init__.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/astroid/__init__.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/src/stubs/astroid/nodes.pyi b/src/stubs/astroid/nodes.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/astroid/nodes.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/src/stubs/openstep_parser.pyi b/src/stubs/openstep_parser.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/openstep_parser.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/src/stubs/pbxproj/__init__.pyi b/src/stubs/pbxproj/__init__.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/pbxproj/__init__.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/src/stubs/pbxproj/pbxextensions.pyi b/src/stubs/pbxproj/pbxextensions.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/pbxproj/pbxextensions.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/src/stubs/pylint.pyi b/src/stubs/pylint.pyi new file mode 100644 index 00000000..edbb4bff --- /dev/null +++ b/src/stubs/pylint.pyi @@ -0,0 +1,5 @@ +# Everything resolves to Any. +from typing import Any + +def __getattr__(name) -> Any: + ... diff --git a/tools/batools/docs.py b/tools/batools/docs.py index 012087ab..0c9c05e1 100755 --- a/tools/batools/docs.py +++ b/tools/batools/docs.py @@ -2,6 +2,8 @@ # """Documentation generation functionality.""" +# pyright: reportPrivateImportUsage=false + from __future__ import annotations import os diff --git a/tools/batools/dummymodule.py b/tools/batools/dummymodule.py index c2ae4d54..02bd6746 100755 --- a/tools/batools/dummymodule.py +++ b/tools/batools/dummymodule.py @@ -972,7 +972,7 @@ def generate_dummy_modules(projroot: str) -> None: ) print( f'{Clr.BLD}{Clr.BLU}Generated {gencount} dummy-modules' - f' {Clr.RST}(in {builddir}){Clr.RST}{Clr.BLD}{Clr.BLU}.', + f' {Clr.RST}(in {builddir}){Clr.RST}{Clr.BLD}{Clr.BLU}.{Clr.RST}', flush=True, ) diff --git a/tools/efro/dataclassio/_outputter.py b/tools/efro/dataclassio/_outputter.py index 406265cc..b084cfeb 100644 --- a/tools/efro/dataclassio/_outputter.py +++ b/tools/efro/dataclassio/_outputter.py @@ -13,7 +13,7 @@ import dataclasses import typing import types import datetime -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, cast, Any from efro.util import check_utc from efro.dataclassio._base import ( @@ -29,7 +29,6 @@ from efro.dataclassio._base import ( from efro.dataclassio._prep import PrepSession if TYPE_CHECKING: - from typing import Any from efro.dataclassio._base import IOAttrs @@ -302,7 +301,7 @@ class _Outputter: return self._process_dict(cls, fieldpath, anntype, value, ioattrs) if dataclasses.is_dataclass(origin): - if not isinstance(value, origin): + if not isinstance(value, cast(Any, origin)): raise TypeError( f'Expected a {origin} for {fieldpath};' f' found a {type(value)}.' diff --git a/tools/efro/log.py b/tools/efro/log.py index f48b54ce..77902265 100644 --- a/tools/efro/log.py +++ b/tools/efro/log.py @@ -388,11 +388,11 @@ class LogHandler(logging.Handler): # warning log which results in another, etc. now = time.monotonic() # noinspection PyUnboundLocalVariable - duration = now - starttime + duration = now - starttime # pyright: ignore # noinspection PyUnboundLocalVariable - format_duration = formattime - starttime + format_duration = formattime - starttime # pyright: ignore # noinspection PyUnboundLocalVariable - echo_duration = echotime - formattime + echo_duration = echotime - formattime # pyright: ignore if duration > 0.05 and ( self._last_slow_emit_warning_time is None or now > self._last_slow_emit_warning_time + 10.0 diff --git a/tools/efrotools/efrocache.py b/tools/efrotools/efrocache.py index 3c323856..3555fb11 100644 --- a/tools/efrotools/efrocache.py +++ b/tools/efrotools/efrocache.py @@ -572,7 +572,7 @@ def warm_start_cache() -> None: base_url = get_repository_base_url() local_cache_dir = get_local_cache_dir() - # We maintain a starter-cache on the staging server, which is simply + # We maintain a starter archive on the staging server, which is simply # a set of commonly used recent cache entries compressed into a # single archive. If we have no local cache yet we can download and # expand this to give us a nice head start and greatly reduce the @@ -580,7 +580,7 @@ def warm_start_cache() -> None: # single compressed archive is much more efficient than downloading # thousands) if not os.path.exists(local_cache_dir): - print('Downloading efrocache starter-cache...', flush=True) + print('Downloading efrocache starter-archive...', flush=True) # Download and decompress the starter-cache into a temp dir # and then move it into place as our shiny new cache dir. diff --git a/tools/efrotools/filecommand.py b/tools/efrotools/filecommand.py index 7a543fdd..0930413e 100644 --- a/tools/efrotools/filecommand.py +++ b/tools/efrotools/filecommand.py @@ -37,7 +37,7 @@ class _FileBatchesRun: # pylint: disable=useless-suppression # pylint: disable=no-name-in-module, import-error # noinspection PyUnresolvedReferences - from Cocoa import NSWorkspace + from Cocoa import NSWorkspace # pyright: ignore self._shared_nsworkspace = NSWorkspace.sharedWorkspace() # pylint: enable=useless-suppression @@ -85,6 +85,7 @@ class _FileBatchesRun: # them out of the dir list we'll dive into and pass # them directly to our batch for processing. if self._include_mac_packages: + assert self._shared_nsworkspace is not None for dirname in list(dirs): fullpath = os.path.join(root, dirname) if self._shared_nsworkspace.isFilePackageAtPath_( diff --git a/tools/efrotools/pcommand2.py b/tools/efrotools/pcommand2.py index 77c0fbf6..0683eb45 100644 --- a/tools/efrotools/pcommand2.py +++ b/tools/efrotools/pcommand2.py @@ -67,3 +67,20 @@ def openal_gather() -> None: raise CleanError('No args expected.') gather() + + +def pyright() -> None: + """Run Pyright checks on project Python code.""" + import subprocess + + from efro.terminal import Clr + + from efro.error import CleanError + + print(f'{Clr.BLU}Running Pyright (experimental)...{Clr.RST}') + try: + subprocess.run( + ['pyright', '--project', '.pyrightconfig.json'], check=True + ) + except Exception as exc: + raise CleanError('Pyright failed.') from exc diff --git a/tools/pcommand b/tools/pcommand index 71d93675..afc42b70 100755 --- a/tools/pcommand +++ b/tools/pcommand @@ -56,6 +56,7 @@ from efrotools.pcommand2 import ( sortlines, openal_build_android, openal_gather, + pyright, ) from batools.pcommand import ( resize_image,