1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.10"
# dependencies = []
# ///
import os
import re
import sys
SUBS = [
# builtins
("async def", "def"),
("async with", "with"),
("await ", ""),
("async for", "for"),
("AsyncIterator", "Iterator"),
("AsyncIterable", "Iterable"),
("__aiter__", "__iter__"),
("__anext__", "__next__"),
("AsyncMock", "MagicMock"),
("assert_awaited_once", "assert_called_once"),
(r"Awaitable\[([^\]]+)\]", r"\1"),
# our public API
("AsyncCacheProxy", "SyncCacheProxy"),
("AsyncBaseStorage", "SyncBaseStorage"),
("AsyncCacheClient", "SyncCacheClient"),
("AsyncSqliteStorage", "SyncSqliteStorage"),
("anysqlite", "sqlite3"),
("@pytest.mark.anyio", ""),
("from anyio import Lock", "from threading import RLock"),
("self._lock = Lock", "self._lock = RLock"),
("aiter_stream", "iter_stream"),
("aiter_raw", "iter_raw"),
("aprint_sqlite_state", "print_sqlite_state"),
("make_async_iterator", "make_sync_iterator"),
("AsyncCacheTransport", "SyncCacheTransport"),
(
"hishel._core._storages._async_base",
"hishel._core._storages._sync_base",
),
# Third-party libraries
("AsyncClient", "Client"),
("aread", "read"),
("aclose", "close"),
("handle_async_request", "handle_request"),
("AsyncBaseTransport", "BaseTransport"),
("AsyncHTTPTransport", "HTTPTransport"),
]
COMPILED_SUBS = [(re.compile(regex), repl) for regex, repl in SUBS]
USED_SUBS = set()
def unasync_line(line):
for index, (regex, repl) in enumerate(COMPILED_SUBS):
old_line = line
line = re.sub(regex, repl, line)
if index not in USED_SUBS:
if line != old_line:
USED_SUBS.add(index)
return line
def unasync_file(in_path, out_path):
with open(in_path) as in_file:
with open(out_path, "w", newline="") as out_file:
for line in in_file.readlines():
line = unasync_line(line)
out_file.write(line)
def unasync_file_check(in_path, out_path):
with open(in_path) as in_file:
with open(out_path) as out_file:
for in_line, out_line in zip(in_file.readlines(), out_file.readlines()):
expected = unasync_line(in_line)
if out_line != expected:
print(f"unasync mismatch between {in_path!r} and {out_path!r}")
print(f"Async code: {in_line!r}")
print(f"Expected sync code: {expected!r}")
print(f"Actual sync code: {out_line!r}")
sys.exit(1)
def unasync_dir(in_dir, out_dir, check_only=False):
for dirpath, dirnames, filenames in os.walk(in_dir):
for filename in filenames:
if not filename.endswith(".py"):
continue
rel_dir = os.path.relpath(dirpath, in_dir)
in_path = os.path.normpath(os.path.join(in_dir, rel_dir, filename))
out_path = os.path.normpath(os.path.join(out_dir, rel_dir, filename))
print(in_path, "->", out_path)
if check_only:
unasync_file_check(in_path, out_path)
else:
unasync_file(in_path, out_path)
def main():
check_only = "--check" in sys.argv
FILES = [
(
"tests/_core/_async/test_sqlite_storage.py",
"tests/_core/_sync/test_sqlite_storage.py",
),
("tests/test_async_httpx.py", "tests/test_sync_httpx.py"),
("hishel/_async_cache.py", "hishel/_sync_cache.py"),
("hishel/_core/_storages/_async_base.py", "hishel/_core/_storages/_sync_base.py"),
("hishel/_core/_storages/_async_sqlite.py", "hishel/_core/_storages/_sync_sqlite.py"),
("hishel/_async_httpx.py", "hishel/_sync_httpx.py"),
]
for in_path, out_path in FILES:
if check_only:
unasync_file_check(in_path, out_path)
else:
unasync_file(in_path, out_path)
print(f"Wrote {out_path}")
if len(USED_SUBS) != len(SUBS):
unused_subs = [SUBS[i] for i in range(len(SUBS)) if i not in USED_SUBS]
from pprint import pprint
print("This SUBS was not used")
pprint(unused_subs)
if __name__ == "__main__":
main()
|