diff --git a/.efrocachemap b/.efrocachemap
index 3ac2821f..b970591a 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -420,8 +420,8 @@
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/04/0a/c4f7d2794b018593ab0b2bcb07f0",
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/06/4d/18777c9a2eb2207a2891a2837a70",
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/81/90/23ab1ecc8c55267bd904a9c05344",
- "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/dd/76/4336a2d6094a2153984c22bf3713",
- "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/29/69/ec6b8725aa7dfa41d0b59f1e9ec1",
+ "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/69/87/5e3820d12fc53bd102f3dc1401dc",
+ "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/d0/7c/87e7c5b3685a64f0a3ecd9a16b99",
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/49/5f/b29bb65369040892fe6601801637",
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/c3/3f/c37ac3c65ac65f171af9313a502a",
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/5a/9e/e8cad6f08b2b19803ab20fdc80d0",
@@ -437,10 +437,10 @@
"assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/17/78/3fd0dca40e632ce53d03a944e7fa",
"assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/d5/19/5e450e35b83fe68722330d03b896",
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/87/2d/027aa239eb66ea8f496562f4fd83",
- "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/a9/71/817446169ae436e6775f76cd5aec",
+ "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/9a/3d/9aff685d04d2e1cabb2f9ddafcf3",
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/33/04/b1c54ce2b8979cc983aecc781228",
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/0a/84/bbb6ed2abf66509406f534cbbb52",
- "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/86/bf/284e1d1c6f07720828754b1ad4c9",
+ "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/e4/1a/489284781f8d24b743de3c05da1a",
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/88/4b/6745a1a58220772e259f0de51196",
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/42/b5/7612cce15fe4555889585108b3ef",
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/44/3c/7cc06ca8d5475e1687d0ed05bdbf",
@@ -450,7 +450,7 @@
"assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/b9/6b/adf28849d42f4c195dacf4f53902",
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/50/9f/be006ba19be6a69a57837eb6dca0",
"assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/9a/8a/f7b2521c1904ffc83262dff1e11b",
- "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/b8/8c/ac972d1936acf2aaa1d06a4b5ce6",
+ "assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/26/62/a072404c02c576a5c3f09059b582",
"assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/cb/ae/e4006b346df70380788f24fa2716",
"assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/04/52/683a27aaf9aa7c63e7e595f80d08",
"assets/build/ba_data/data/maps/big_g.json": "https://files.ballistica.net/cache/ba1/47/0a/a617cc85d927b576c4e6fc1091ed",
@@ -940,7 +940,7 @@
"assets/build/ba_data/models/zoeTorso.bob": "https://files.ballistica.net/cache/ba1/88/66/74a21f09ca6cfbfe7352219e43e6",
"assets/build/ba_data/models/zoeUpperArm.bob": "https://files.ballistica.net/cache/ba1/99/38/b7694cae0804260eeb337aa1676a",
"assets/build/ba_data/models/zoeUpperLeg.bob": "https://files.ballistica.net/cache/ba1/83/4f/28b2202d0109fa93272c0b09fa2d",
- "assets/build/ba_data/python-site-packages/typing_extensions.py": "https://files.ballistica.net/cache/ba1/e2/34/5db33f5dc674461d7672a88bd999",
+ "assets/build/ba_data/python-site-packages/typing_extensions.py": "https://files.ballistica.net/cache/ba1/57/e0/d240d3e3163e12faa7274410aff1",
"assets/build/ba_data/python-site-packages/yaml/__init__.py": "https://files.ballistica.net/cache/ba1/ad/6c/07ad575eb2b280b2d22c53c0938f",
"assets/build/ba_data/python-site-packages/yaml/composer.py": "https://files.ballistica.net/cache/ba1/3e/aa/d7fcfc4707ad19a6964d72654b82",
"assets/build/ba_data/python-site-packages/yaml/constructor.py": "https://files.ballistica.net/cache/ba1/ad/dc/d8a51b583ad1cc74917bb189f9f9",
@@ -3928,16 +3928,16 @@
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
- "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/34/30/1f0f29bf2082ba1491ec5f693e5a",
- "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/41/a9/8cb926cd717fd8a1a777683bc7e0",
- "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/48/13/22c0bb0c91cf41ab34ebda463562",
- "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/62/e0/cc4ac50696743a8864ba4c793a37",
- "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3e/8b/bda7c882274919de97200a73efe5",
- "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2b/6a/1346ce95d3fceaf22b336a6fe697",
- "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d2/1f/3099ca907a025537990c263a9cf8",
- "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3d/49/fd6cda67307cacb8d7b8d654561d",
- "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/b7/a8/c401f564941805196e2e0abed89c",
- "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/80/3a/977fd3e5392e435660f12d467d4c",
- "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/08/72/73a8a403b228498aad76d9c5ce79",
- "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ae/4d/358c50a4e2cf4cd7b2d4c2b65b32"
+ "build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3f/99/9b94f7d478142a08e02c769b64ba",
+ "build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0d/f0/aed2b96addcc73e2de400aed2bdf",
+ "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a0/07/c0bf82b57e34f20a58069edbf651",
+ "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ca/a7/0c55882b9794255f1c5dede196b7",
+ "build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c5/56/b033099ea96d4113fc434519f2bb",
+ "build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/58/45/c307135aeb9b0ff3f98778db9db9",
+ "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e1/c0/d4e431d897d7bed37f6af21a9c9f",
+ "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/60/1d/ed514d5f0e2d6c0d6ca7a9a4c059",
+ "build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/ae/93/1a312729ea081233baf8a5f36be3",
+ "build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/74/c8/64608e7c5a716cc336fc6425edf2",
+ "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/39/db/0246df61ce4d65a8e805437aa3d7",
+ "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/80/4a/b0729f19eee793ddb1a2f7b73fb1"
}
\ No newline at end of file
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 59d1f046..f78d0797 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -56,6 +56,7 @@
allsettings
allteams
aman
+ amazonaws
aname
anamorphosis
andr
@@ -597,6 +598,7 @@
enumtype
enumval
envhash
+ envname
envval
epath
epicfail
@@ -892,6 +894,7 @@
hatmotion
hattach
hcalc
+ hcfg
hdpi
headercheckline
headerregistry
@@ -918,11 +921,14 @@
homebook
homebrew
hometest
+ hostconfig
+ hostuser
hout
howtoplay
hpos
hscrollwidget
hspacing
+ httprequest
hurtiness
hval
iasset
@@ -1096,6 +1102,7 @@
libxm
libxmu
libxz
+ linbeast
lindex
lindexorig
linebits
@@ -1130,6 +1137,7 @@
lnums
loadpackage
localconfig
+ localuser
locationgroup
locationgroups
locationlist
@@ -1512,6 +1520,7 @@
pragmas
prch
prec
+ precommand
preexec
preflightfast
preflightfull
@@ -1919,6 +1928,7 @@
subdeps
subdirs
subfolders
+ subname
subpath
subplatform
subplatforms
@@ -1946,7 +1956,9 @@
syncable
syncall
syncalllist
+ synccfg
synccheck
+ syncconfig
syncforce
syncfull
syncitem
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3cae4162..e146c484 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-### 1.5.25 (20172)
+### 1.5.25 (20174)
- Added Venetian language (thanks Federico!)
- Fixed an issue where chosen-one flashes would remain if the player leaves the game
- Added android input-device detection log messages for debugging
diff --git a/docs/ba_module.md b/docs/ba_module.md
index 988f71c3..2242f408 100644
--- a/docs/ba_module.md
+++ b/docs/ba_module.md
@@ -1,5 +1,5 @@
-
last updated on 2020-08-23 for Ballistica version 1.5.25 build 20172
+last updated on 2020-08-31 for Ballistica version 1.5.25 build 20175
This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!
diff --git a/tests/test_efro/test_entity.py b/tests/test_efro/test_entity.py
index 063ab689..8af4cf0e 100644
--- a/tests/test_efro/test_entity.py
+++ b/tests/test_efro/test_entity.py
@@ -27,8 +27,13 @@ from enum import Enum, unique
import pytest
+# Seeming to get some non-deterministic behavior here as of pylint 2.6.0
+# Where sometimes pylint wants these in one order and sometimes another.
+# pylint: disable=useless-suppression
+# pylint: disable=wrong-import-order
from efro import entity
from efrotools.statictest import static_type_equals
+# pylint: enable=useless-suppression
if TYPE_CHECKING:
pass
diff --git a/tools/efro/terminal.py b/tools/efro/terminal.py
index 3c852e82..3919de7b 100644
--- a/tools/efro/terminal.py
+++ b/tools/efro/terminal.py
@@ -27,7 +27,7 @@ from enum import Enum, unique
from typing import TYPE_CHECKING
if TYPE_CHECKING:
- from typing import Any
+ from typing import Any, ClassVar, Type
@unique
@@ -155,109 +155,169 @@ def _windows_enable_color() -> bool:
return False
-class Clr:
+class ClrBase:
+ """Base class for color convenience class."""
+ RST: ClassVar[str]
+ BLD: ClassVar[str]
+ UND: ClassVar[str]
+ INV: ClassVar[str]
+
+ # Normal foreground colors
+ BLK: ClassVar[str]
+ RED: ClassVar[str]
+ GRN: ClassVar[str]
+ YLW: ClassVar[str]
+ BLU: ClassVar[str]
+ MAG: ClassVar[str]
+ CYN: ClassVar[str]
+ WHT: ClassVar[str]
+
+ # Normal background colors.
+ BBLK: ClassVar[str]
+ BRED: ClassVar[str]
+ BGRN: ClassVar[str]
+ BYLW: ClassVar[str]
+ BBLU: ClassVar[str]
+ BMAG: ClassVar[str]
+ BCYN: ClassVar[str]
+ BWHT: ClassVar[str]
+
+ # Strong foreground colors
+ SBLK: ClassVar[str]
+ SRED: ClassVar[str]
+ SGRN: ClassVar[str]
+ SYLW: ClassVar[str]
+ SBLU: ClassVar[str]
+ SMAG: ClassVar[str]
+ SCYN: ClassVar[str]
+ SWHT: ClassVar[str]
+
+ # Strong background colors.
+ SBBLK: ClassVar[str]
+ SBRED: ClassVar[str]
+ SBGRN: ClassVar[str]
+ SBYLW: ClassVar[str]
+ SBBLU: ClassVar[str]
+ SBMAG: ClassVar[str]
+ SBCYN: ClassVar[str]
+ SBWHT: ClassVar[str]
+
+
+class Clr1(ClrBase):
"""Convenience class for color terminal output.
- These will be set to ANSI color escape sequences if the current process
- seems to be an interactive terminal (sys.__stdout__.isatty()), otherwise
- they will be empty strings.
- If the environment variable EFRO_TERMCOLORS is set to 0 or 1, that
- value will be used instead.
+ This version has colors always enabled. Generally you should use Clr which
+ points to the correct enabled/disabled class depending on the environment.
"""
- _envval = os.environ.get('EFRO_TERMCOLORS')
- color_enabled = (True if _envval == '1' else
- False if _envval == '0' else _default_color_enabled())
- if color_enabled:
+ color_enabled = True
- # Styles
- RST = TerminalColor.RESET.value
- BLD = TerminalColor.BOLD.value
- UND = TerminalColor.UNDERLINE.value
- INV = TerminalColor.INVERSE.value
+ # Styles
+ RST = TerminalColor.RESET.value
+ BLD = TerminalColor.BOLD.value
+ UND = TerminalColor.UNDERLINE.value
+ INV = TerminalColor.INVERSE.value
- # Normal foreground colors
- BLK = TerminalColor.BLACK.value
- RED = TerminalColor.RED.value
- GRN = TerminalColor.GREEN.value
- YLW = TerminalColor.YELLOW.value
- BLU = TerminalColor.BLUE.value
- MAG = TerminalColor.MAGENTA.value
- CYN = TerminalColor.CYAN.value
- WHT = TerminalColor.WHITE.value
+ # Normal foreground colors
+ BLK = TerminalColor.BLACK.value
+ RED = TerminalColor.RED.value
+ GRN = TerminalColor.GREEN.value
+ YLW = TerminalColor.YELLOW.value
+ BLU = TerminalColor.BLUE.value
+ MAG = TerminalColor.MAGENTA.value
+ CYN = TerminalColor.CYAN.value
+ WHT = TerminalColor.WHITE.value
- # Normal background colors.
- BBLK = TerminalColor.BG_BLACK.value
- BRED = TerminalColor.BG_RED.value
- BGRN = TerminalColor.BG_GREEN.value
- BYLW = TerminalColor.BG_YELLOW.value
- BBLU = TerminalColor.BG_BLUE.value
- BMAG = TerminalColor.BG_MAGENTA.value
- BCYN = TerminalColor.BG_CYAN.value
- BWHT = TerminalColor.BG_WHITE.value
+ # Normal background colors.
+ BBLK = TerminalColor.BG_BLACK.value
+ BRED = TerminalColor.BG_RED.value
+ BGRN = TerminalColor.BG_GREEN.value
+ BYLW = TerminalColor.BG_YELLOW.value
+ BBLU = TerminalColor.BG_BLUE.value
+ BMAG = TerminalColor.BG_MAGENTA.value
+ BCYN = TerminalColor.BG_CYAN.value
+ BWHT = TerminalColor.BG_WHITE.value
- # Strong foreground colors
- SBLK = TerminalColor.STRONG_BLACK.value
- SRED = TerminalColor.STRONG_RED.value
- SGRN = TerminalColor.STRONG_GREEN.value
- SYLW = TerminalColor.STRONG_YELLOW.value
- SBLU = TerminalColor.STRONG_BLUE.value
- SMAG = TerminalColor.STRONG_MAGENTA.value
- SCYN = TerminalColor.STRONG_CYAN.value
- SWHT = TerminalColor.STRONG_WHITE.value
+ # Strong foreground colors
+ SBLK = TerminalColor.STRONG_BLACK.value
+ SRED = TerminalColor.STRONG_RED.value
+ SGRN = TerminalColor.STRONG_GREEN.value
+ SYLW = TerminalColor.STRONG_YELLOW.value
+ SBLU = TerminalColor.STRONG_BLUE.value
+ SMAG = TerminalColor.STRONG_MAGENTA.value
+ SCYN = TerminalColor.STRONG_CYAN.value
+ SWHT = TerminalColor.STRONG_WHITE.value
- # Strong background colors.
- SBBLK = TerminalColor.STRONG_BG_BLACK.value
- SBRED = TerminalColor.STRONG_BG_RED.value
- SBGRN = TerminalColor.STRONG_BG_GREEN.value
- SBYLW = TerminalColor.STRONG_BG_YELLOW.value
- SBBLU = TerminalColor.STRONG_BG_BLUE.value
- SBMAG = TerminalColor.STRONG_BG_MAGENTA.value
- SBCYN = TerminalColor.STRONG_BG_CYAN.value
- SBWHT = TerminalColor.STRONG_BG_WHITE.value
+ # Strong background colors.
+ SBBLK = TerminalColor.STRONG_BG_BLACK.value
+ SBRED = TerminalColor.STRONG_BG_RED.value
+ SBGRN = TerminalColor.STRONG_BG_GREEN.value
+ SBYLW = TerminalColor.STRONG_BG_YELLOW.value
+ SBBLU = TerminalColor.STRONG_BG_BLUE.value
+ SBMAG = TerminalColor.STRONG_BG_MAGENTA.value
+ SBCYN = TerminalColor.STRONG_BG_CYAN.value
+ SBWHT = TerminalColor.STRONG_BG_WHITE.value
- else:
- # Styles
- RST = ''
- BLD = ''
- UND = ''
- INV = ''
- # Normal foreground colors
- BLK = ''
- RED = ''
- GRN = ''
- YLW = ''
- BLU = ''
- MAG = ''
- CYN = ''
- WHT = ''
+class Clr0(ClrBase):
+ """Convenience class for color terminal output.
- # Normal background colors.
- BBLK = ''
- BRED = ''
- BGRN = ''
- BYLW = ''
- BBLU = ''
- BMAG = ''
- BCYN = ''
- BWHT = ''
+ This version has colors disabled. Generally you should use Clr which
+ points to the correct enabled/disabled class depending on the environment.
+ """
+ color_enabled = False
- # Strong foreground colors
- SBLK = ''
- SRED = ''
- SGRN = ''
- SYLW = ''
- SBLU = ''
- SMAG = ''
- SCYN = ''
- SWHT = ''
+ # Styles
+ RST = ''
+ BLD = ''
+ UND = ''
+ INV = ''
- # Strong background colors.
- SBBLK = ''
- SBRED = ''
- SBGRN = ''
- SBYLW = ''
- SBBLU = ''
- SBMAG = ''
- SBCYN = ''
- SBWHT = ''
+ # Normal foreground colors
+ BLK = ''
+ RED = ''
+ GRN = ''
+ YLW = ''
+ BLU = ''
+ MAG = ''
+ CYN = ''
+ WHT = ''
+
+ # Normal background colors.
+ BBLK = ''
+ BRED = ''
+ BGRN = ''
+ BYLW = ''
+ BBLU = ''
+ BMAG = ''
+ BCYN = ''
+ BWHT = ''
+
+ # Strong foreground colors
+ SBLK = ''
+ SRED = ''
+ SGRN = ''
+ SYLW = ''
+ SBLU = ''
+ SMAG = ''
+ SCYN = ''
+ SWHT = ''
+
+ # Strong background colors.
+ SBBLK = ''
+ SBRED = ''
+ SBGRN = ''
+ SBYLW = ''
+ SBBLU = ''
+ SBMAG = ''
+ SBCYN = ''
+ SBWHT = ''
+
+
+_envval = os.environ.get('EFRO_TERMCOLORS')
+_color_enabled: bool = (True if _envval == '1' else
+ False if _envval == '0' else _default_color_enabled())
+Clr: Type[ClrBase]
+if _color_enabled:
+ Clr = Clr1
+else:
+ Clr = Clr0
diff --git a/tools/efrotools/code.py b/tools/efrotools/code.py
index 35f47d78..63ec4bc3 100644
--- a/tools/efrotools/code.py
+++ b/tools/efrotools/code.py
@@ -622,7 +622,7 @@ def dmypy(projroot: Path) -> None:
try:
args = [
'dmypy', 'run', '--timeout', '3600', '--', '--config-file',
- '.mypy.ini', '--follow-imports=error', '--pretty'
+ '.mypy.ini', '--pretty'
] + filenames
subprocess.run(args, check=True)
except Exception as exc:
diff --git a/tools/efrotools/filecache.py b/tools/efrotools/filecache.py
index 1d582e38..77539068 100644
--- a/tools/efrotools/filecache.py
+++ b/tools/efrotools/filecache.py
@@ -26,8 +26,8 @@ import json
import os
from typing import TYPE_CHECKING
-from efro.terminal import Clr
from efrotools import get_files_hash
+from efro.terminal import Clr
if TYPE_CHECKING:
from typing import Dict, Optional, Sequence, Any