mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
Update Ruff and lint cleanup
Bump Python tooling to Ruff 0.16.2 and datamodel-code-generator 0.72.3, add the py313 target in pre-commit, and refresh the engine lockfile. This also narrows broad exception handling and applies small Python cleanups across the engine and helper scripts to satisfy newer lint rules without changing runtime behavior.
This commit is contained in:
@@ -65,6 +65,8 @@ tasks:
|
||||
cmds:
|
||||
# Auto-fixers first, then the report-only tools (codespell, gitleaks) so a
|
||||
# finding there does not stop the fixers from running.
|
||||
- task: ruff-format
|
||||
vars: { FIX: '1' }
|
||||
- task: ruff
|
||||
vars: { FIX: '1' }
|
||||
- task: ruff-format
|
||||
@@ -101,12 +103,12 @@ tasks:
|
||||
ruff:
|
||||
deps: [install]
|
||||
cmds:
|
||||
- uv run --project engine --locked --group pre-commit ruff check --isolated --line-length=120 {{if .FIX}}--fix {{end}}$(git ls-files {{.PY_FILES}})
|
||||
- uv run --project engine --locked --group pre-commit ruff check --isolated --target-version=py313 --line-length=120 {{if .FIX}}--fix {{end}}$(git ls-files {{.PY_FILES}})
|
||||
|
||||
ruff-format:
|
||||
deps: [install]
|
||||
cmds:
|
||||
- uv run --project engine --locked --group pre-commit ruff format --isolated --line-length=120 {{if .FIX}}{{else}}--check {{end}}$(git ls-files {{.PY_FILES}})
|
||||
- uv run --project engine --locked --group pre-commit ruff format --isolated --target-version=py313 --line-length=120 {{if .FIX}}{{else}}--check {{end}}$(git ls-files {{.PY_FILES}})
|
||||
|
||||
codespell:
|
||||
deps: [install]
|
||||
|
||||
@@ -61,7 +61,7 @@ def resize_image(input_image_path, output_image_path, max_size=(16383, 16383)):
|
||||
# If dimensions are within the allowed limits, save the image directly
|
||||
image.save(output_image_path, format="WEBP", quality=100)
|
||||
print(f"The image was successfully saved as WebP: {output_image_path}")
|
||||
except Exception as e:
|
||||
except (OSError, ValueError) as e:
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@ engine = [
|
||||
# Type checking, testing, model generation, and formatting tools for the engine.
|
||||
engine-dev = [
|
||||
"anyio>=4.14.2",
|
||||
"datamodel-code-generator[ruff]==0.64.0",
|
||||
"datamodel-code-generator[ruff]==0.72.3",
|
||||
"pyright>=1.1.411",
|
||||
"pytest>=9.1.1",
|
||||
"referencing>=0.37.0",
|
||||
"ruff==0.15.5",
|
||||
"ruff==0.16.2",
|
||||
]
|
||||
# Dependencies for the Cucumber/Python integration test suite.
|
||||
cucumber = [
|
||||
@@ -65,7 +65,7 @@ updater-signatures = [
|
||||
# Pinned repository-wide pre-commit tooling.
|
||||
pre-commit = [
|
||||
"codespell==2.4.3",
|
||||
"ruff==0.15.5",
|
||||
"ruff==0.16.2",
|
||||
"tomli-w==1.2.0",
|
||||
]
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ async def apply_config(request: ConfigPushRequest, http_request: Request) -> Con
|
||||
save_config(request)
|
||||
# Claim the stamp we just wrote so this worker's watcher does not rebuild for it.
|
||||
app.state.config_cache_stamp = cache_stamp()
|
||||
except Exception: # noqa: BLE001 - best-effort persist, never fail the applied push
|
||||
except Exception: # best-effort persist, never fail the applied push
|
||||
logger.warning("Applied AI config but failed to persist the encrypted cache", exc_info=True)
|
||||
notes.append(
|
||||
"Config applied on this worker but could not be persisted; it will not survive an"
|
||||
|
||||
@@ -17,6 +17,7 @@ from pydantic_ai import Agent
|
||||
|
||||
from stirling.services import AppRuntime
|
||||
|
||||
|
||||
class MyAgent:
|
||||
def __init__(self, runtime: AppRuntime) -> None:
|
||||
rag = runtime.rag_capability
|
||||
|
||||
@@ -139,7 +139,7 @@ class DocumentService:
|
||||
try:
|
||||
results = await self._store.search(col_name, query_embedding, k, principals)
|
||||
all_results.extend(results)
|
||||
except Exception: # noqa: BLE001 - any backend error on one collection should not stop the others
|
||||
except Exception: # any backend error on one collection should not stop the others
|
||||
logger.warning(
|
||||
"Skipping collection %s during cross-collection search",
|
||||
col_name,
|
||||
|
||||
Generated
+25
-25
@@ -534,7 +534,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "datamodel-code-generator"
|
||||
version = "0.64.0"
|
||||
version = "0.72.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "argcomplete" },
|
||||
@@ -546,9 +546,9 @@ dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "pyyaml" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9c/d2/86c94a2836ed42231653a7ddaefa0a5bc23418167a876bba7376c96b3a35/datamodel_code_generator-0.64.0.tar.gz", hash = "sha256:9c592900a00b20e416494273c22435f5a9aef6ea8c7b9190747522a60497a1cb", size = 1316440, upload-time = "2026-06-14T17:24:50.528Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/14/4b/4652f0bb085a564982c3e515a0b02bcee21765ddac967bcf152a70d2af14/datamodel_code_generator-0.72.3.tar.gz", hash = "sha256:a20160de09b76d4a293ccba5a9ee5c341b5365890237ac1ff812f420e4c09f3b", size = 1965678, upload-time = "2026-08-10T18:58:41.636Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/23/94/71338e2f0146ac10747a5537b3a1e45256e66b7c229869eb0ee787111b41/datamodel_code_generator-0.64.0-py3-none-any.whl", hash = "sha256:b7cd8bd41a312aa997aec6150670bad781847c5b674f17e4d70e78208a0fb990", size = 374698, upload-time = "2026-06-14T17:24:48.809Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/fd/9d8a0594aedcc6ee8133b21dd3543d6021842e013058803a69918720d0aa/datamodel_code_generator-0.72.3-py3-none-any.whl", hash = "sha256:4536f6dd12dd86c9c7a78b16ef83ae9aa7a9cbdb8bef8a3b63baa4ad9d3d3829", size = 554226, upload-time = "2026-08-10T18:58:40.087Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -711,15 +711,15 @@ engine = [
|
||||
]
|
||||
engine-dev = [
|
||||
{ name = "anyio", specifier = ">=4.14.2" },
|
||||
{ name = "datamodel-code-generator", extras = ["ruff"], specifier = "==0.64.0" },
|
||||
{ name = "datamodel-code-generator", extras = ["ruff"], specifier = "==0.72.3" },
|
||||
{ name = "pyright", specifier = ">=1.1.411" },
|
||||
{ name = "pytest", specifier = ">=9.1.1" },
|
||||
{ name = "referencing", specifier = ">=0.37.0" },
|
||||
{ name = "ruff", specifier = "==0.15.5" },
|
||||
{ name = "ruff", specifier = "==0.16.2" },
|
||||
]
|
||||
pre-commit = [
|
||||
{ name = "codespell", specifier = "==2.4.3" },
|
||||
{ name = "ruff", specifier = "==0.15.5" },
|
||||
{ name = "ruff", specifier = "==0.16.2" },
|
||||
{ name = "tomli-w", specifier = "==1.2.0" },
|
||||
]
|
||||
tools = [
|
||||
@@ -2791,27 +2791,27 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.15.5"
|
||||
version = "0.16.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/77/9b/840e0039e65fcf12758adf684d2289024d6140cde9268cc59887dc55189c/ruff-0.15.5.tar.gz", hash = "sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2", size = 4574214, upload-time = "2026-03-05T20:06:34.946Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/73/e1/4508a569211b35599016e84ba65c1a992b7a4004b4b6c4bea02a851cba1b/ruff-0.16.2.tar.gz", hash = "sha256:c3d7828d12e8927a6fc65fe38e2c2541b9e762d360a1786d752cb1b8883b3c9c", size = 4885811, upload-time = "2026-08-07T13:31:01.432Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/47/20/5369c3ce21588c708bcbe517a8fbe1a8dfdb5dfd5137e14790b1da71612c/ruff-0.15.5-py3-none-linux_armv6l.whl", hash = "sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c", size = 10478185, upload-time = "2026-03-05T20:06:29.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/ed/e81dd668547da281e5dce710cf0bc60193f8d3d43833e8241d006720e42b/ruff-0.15.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080", size = 10859201, upload-time = "2026-03-05T20:06:32.632Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/8f/533075f00aaf19b07c5cd6aa6e5d89424b06b3b3f4583bfa9c640a079059/ruff-0.15.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010", size = 10184752, upload-time = "2026-03-05T20:06:40.312Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/0e/ba49e2c3fa0395b3152bad634c7432f7edfc509c133b8f4529053ff024fb/ruff-0.15.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65", size = 10534857, upload-time = "2026-03-05T20:06:19.581Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/71/39234440f27a226475a0659561adb0d784b4d247dfe7f43ffc12dd02e288/ruff-0.15.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440", size = 10309120, upload-time = "2026-03-05T20:06:00.435Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/87/4140aa86a93df032156982b726f4952aaec4a883bb98cb6ef73c347da253/ruff-0.15.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204", size = 11047428, upload-time = "2026-03-05T20:05:51.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/f7/4953e7e3287676f78fbe85e3a0ca414c5ca81237b7575bdadc00229ac240/ruff-0.15.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8", size = 11914251, upload-time = "2026-03-05T20:06:22.887Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/46/0f7c865c10cf896ccf5a939c3e84e1cfaeed608ff5249584799a74d33835/ruff-0.15.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681", size = 11333801, upload-time = "2026-03-05T20:05:57.168Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/01/a10fe54b653061585e655f5286c2662ebddb68831ed3eaebfb0eb08c0a16/ruff-0.15.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a", size = 11206821, upload-time = "2026-03-05T20:06:03.441Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/0d/2132ceaf20c5e8699aa83da2706ecb5c5dcdf78b453f77edca7fb70f8a93/ruff-0.15.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca", size = 11133326, upload-time = "2026-03-05T20:06:25.655Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/cb/2e5259a7eb2a0f87c08c0fe5bf5825a1e4b90883a52685524596bfc93072/ruff-0.15.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd", size = 10510820, upload-time = "2026-03-05T20:06:37.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/20/b67ce78f9e6c59ffbdb5b4503d0090e749b5f2d31b599b554698a80d861c/ruff-0.15.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d", size = 10302395, upload-time = "2026-03-05T20:05:54.504Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/e5/719f1acccd31b720d477751558ed74e9c88134adcc377e5e886af89d3072/ruff-0.15.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752", size = 10754069, upload-time = "2026-03-05T20:06:06.422Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/9c/d1db14469e32d98f3ca27079dbd30b7b44dbb5317d06ab36718dee3baf03/ruff-0.15.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2", size = 11304315, upload-time = "2026-03-05T20:06:10.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/3a/950367aee7c69027f4f422059227b290ed780366b6aecee5de5039d50fa8/ruff-0.15.5-py3-none-win32.whl", hash = "sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74", size = 10551676, upload-time = "2026-03-05T20:06:13.705Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/00/bf077a505b4e649bdd3c47ff8ec967735ce2544c8e4a43aba42ee9bf935d/ruff-0.15.5-py3-none-win_amd64.whl", hash = "sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe", size = 11678972, upload-time = "2026-03-05T20:06:45.379Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/4e/cd76eca6db6115604b7626668e891c9dd03330384082e33662fb0f113614/ruff-0.15.5-py3-none-win_arm64.whl", hash = "sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b", size = 10965572, upload-time = "2026-03-05T20:06:16.984Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/57/db19951540f98859c956b50bdb4d31089b4d91e9f15e2968e7d5193806d5/ruff-0.16.2-py3-none-linux_armv6l.whl", hash = "sha256:3c8de4cf2181f01d57946d87d777aa52916976fc09942aed89938fab5e013318", size = 10847925, upload-time = "2026-08-07T13:30:14.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/5a/995fe85a8470d3e391ac0f7fa8054bb454eaf33ee138196d6172ed1079c0/ruff-0.16.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9a48cc05c6fbc811ca81b5d7ba95375affea6582d1b8024e455e41afbbf55344", size = 11072662, upload-time = "2026-08-07T13:30:18.143Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/53/370d767c61c71a971a4ace36703a7ecd8c393956349a7325d7fab2b56827/ruff-0.16.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a2c0d14fcbb26c91f0f867a6dc9bd71bbc30b1b6151829c884f23faeab2e5700", size = 10566771, upload-time = "2026-08-07T13:30:20.899Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/d6/9d96948caf5a632be62d62202d5ec914d6856f204fd79eb036e5915e79ea/ruff-0.16.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:335c621622c4650330be50842561c6586ac6971bb8ab5407fe34dcc9efb16bbe", size = 10975825, upload-time = "2026-08-07T13:30:23.517Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/92/ea87129b3414acb0b5770563779c51804d37ac67675c7ba35447ddb14773/ruff-0.16.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e66910f2c37cc753f9ef6580c914a621b80c4fa3549d3e3521e29d0f5bfc3f", size = 10649437, upload-time = "2026-08-07T13:30:26.097Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/43/f8f291dcd4af5bb7872b74fdfa41a7cd7c856ca1d4069670971cf1b9f5cb/ruff-0.16.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7e36fbfba65510548156902bcf1350a979a958ce0347ce0f90d73894036b39f", size = 11446761, upload-time = "2026-08-07T13:30:28.752Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/4a/ef991fb2fcf516ab71f0808adcdd8da5e18c8cde447f4ceaf5f47a5132a5/ruff-0.16.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0eab35f80df8f134aae5d1630e751901321d317cc8e50dc39e36fa3ed34cd12", size = 12336364, upload-time = "2026-08-07T13:30:31.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/24/f615e74f307e6ca0e56a482872477b856c70d530aa356abfb6dfe5ca8a80/ruff-0.16.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40ea8c0594feb894e89c8c61ab9c103d38b0ea72dfde6c594107147ca31b1140", size = 11630720, upload-time = "2026-08-07T13:30:34.426Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/d3/8ef50149e8412a77f7ab409efdef0e2b23803707a3863da4fc64cb23d459/ruff-0.16.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab3d62dde0b19facdd632008cc4827fc28ada7736c6bd35ab6f1050f0bfed53f", size = 11466130, upload-time = "2026-08-07T13:30:36.958Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/a7/a19334985c4dea8c381981fa252cd854c7ee52dc4b1686dc16f4a911c702/ruff-0.16.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:e43e1f5b8388da9eca1b9e88328d47a5cec794633ccf6f7484ac2dd15eee92c0", size = 11523634, upload-time = "2026-08-07T13:30:39.822Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/6c/96d192b0e742412ceda08c0a50f9669b253dde9fd6a60ea1a10c9fa79a63/ruff-0.16.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c24788a980581e1d7ea3a0cbe4344c4fbeb0a6a9b1f4713aa46bb104f8294690", size = 10949807, upload-time = "2026-08-07T13:30:42.745Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/51/e26599ceca11e79ee255c7df515995561edf87e9ca1893284e44d98f5a86/ruff-0.16.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:81806b08329130005dd4a8a8394a0c9da8c6f4cafb16ba438d2a2ee6a18bedf1", size = 10646891, upload-time = "2026-08-07T13:30:45.522Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/01/800c4b1f97bc8d7c6029e06b1f20473a3cf1e13c4933d8f3342add83fc55/ruff-0.16.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4ce4e02bad779bef557f541a1b31f20d6abeae1cc05ed1b1ac019d4ffd1044c8", size = 11162063, upload-time = "2026-08-07T13:30:48.131Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/d0/1477ea50fc5a0d4b0b71d1d63d50770bdd794d90b43e37a7618e63ec9894/ruff-0.16.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e0422abdf70070255fc4073ce9dfc814cc03db577013761ddd09bc1e4a9a4fbd", size = 11556038, upload-time = "2026-08-07T13:30:50.686Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/76/a7776f32048d991e16d4fa8ff91790b877342d3596cc3ed04acdbf1aaedc/ruff-0.16.2-py3-none-win32.whl", hash = "sha256:bf3a63d78fb39f4bf5ac8ae52051c5520505301abe19ba4e204c453b3f09bb0b", size = 10872850, upload-time = "2026-08-07T13:30:53.471Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/0d/929c800d920e61397d82a01b60bffc68da3052c17d31de59efaad2e4ed75/ruff-0.16.2-py3-none-win_amd64.whl", hash = "sha256:bcabe2f6d0fc7819f1431793005af4e4de7371927d037345bf941252b195b9fa", size = 12023338, upload-time = "2026-08-07T13:30:56.193Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/6c/93e26c22c5f78ff87363e07da49c84955affbeb1098bd1936bf3b3f293bf/ruff-0.16.2-py3-none-win_arm64.whl", hash = "sha256:d614e95cedf38a2053fd351c55b103ba30d017d61688fdbfd40ee0412852a99f", size = 11374065, upload-time = "2026-08-07T13:30:58.775Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -75,7 +75,7 @@ def parse_unicode_mapping(mapping_path):
|
||||
print(f"Parsed ToUnicode CMap: {len(gid_to_unicode)} mappings", file=sys.stderr)
|
||||
return gid_to_unicode
|
||||
|
||||
except Exception as e:
|
||||
except (OSError, UnicodeError, ValueError, TypeError, KeyError) as e:
|
||||
print(f"Warning: Failed to parse Unicode mapping: {e}", file=sys.stderr)
|
||||
return {}
|
||||
|
||||
@@ -122,7 +122,7 @@ def wrap_cff_as_otf(input_path, output_path, tounicode_path=None):
|
||||
else:
|
||||
# Fallback to CharStrings keys
|
||||
charstrings = cff_font.CharStrings
|
||||
glyph_order = [".notdef"] + [name for name in charstrings.keys() if name != ".notdef"]
|
||||
glyph_order = [".notdef"] + [name for name in charstrings if name != ".notdef"]
|
||||
|
||||
otf.setGlyphOrder(glyph_order)
|
||||
|
||||
@@ -186,10 +186,10 @@ def wrap_cff_as_otf(input_path, output_path, tounicode_path=None):
|
||||
min_lsb = min(min_lsb, lsb)
|
||||
min_rsb = min(min_rsb, rsb)
|
||||
max_extent = max(max_extent, extent)
|
||||
except Exception:
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
pass # Some glyphs may not have outlines
|
||||
|
||||
except Exception:
|
||||
except (AttributeError, KeyError, TypeError, ValueError):
|
||||
pass # Use defaults
|
||||
|
||||
widths[glyph_name] = width
|
||||
@@ -308,14 +308,14 @@ def wrap_cff_as_otf(input_path, output_path, tounicode_path=None):
|
||||
unicode_val = int(glyph_name[3:], 16)
|
||||
if unicode_val not in unicode_to_glyph:
|
||||
unicode_to_glyph[unicode_val] = glyph_name
|
||||
except Exception:
|
||||
except ValueError:
|
||||
pass
|
||||
elif glyph_name.startswith("u") and len(glyph_name) >= 5:
|
||||
try:
|
||||
unicode_val = int(glyph_name[1:], 16)
|
||||
if unicode_val not in unicode_to_glyph:
|
||||
unicode_to_glyph[unicode_val] = glyph_name
|
||||
except Exception:
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# === Create cmap table ===
|
||||
@@ -476,8 +476,8 @@ def wrap_cff_as_otf(input_path, output_path, tounicode_path=None):
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: Conversion failed: {str(e)}", file=sys.stderr)
|
||||
except (OSError, ValueError, TypeError, KeyError, RuntimeError) as e:
|
||||
print(f"ERROR: Conversion failed: {e!s}", file=sys.stderr)
|
||||
import traceback
|
||||
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
|
||||
@@ -116,12 +116,11 @@ def write_readme(progress_list: list[tuple[str, int]]) -> None:
|
||||
for i, line in enumerate(content[2:], start=2):
|
||||
for progress in progress_list:
|
||||
language, value = progress
|
||||
if language in line:
|
||||
if match := re.search(r"\!\[(\d+(\.\d+)?)%\]\(.*\)", line):
|
||||
content[i] = line.replace(
|
||||
match.group(0),
|
||||
f"",
|
||||
)
|
||||
if language in line and (match := re.search(r"\!\[(\d+(\.\d+)?)%\]\(.*\)", line)):
|
||||
content[i] = line.replace(
|
||||
match.group(0),
|
||||
f"",
|
||||
)
|
||||
|
||||
with open(
|
||||
os.path.join(os.getcwd(), "devGuide", "HowToAddNewLanguage.md"),
|
||||
@@ -261,12 +260,11 @@ def compare_files(
|
||||
# Missing translation (same as default and not ignored)
|
||||
fails += 1
|
||||
missing_str_keys.append(default_key)
|
||||
if default_value != file_value:
|
||||
if default_key in sort_ignore_translation[language]["ignore"]:
|
||||
if default_key == "language.direction":
|
||||
continue
|
||||
# Remove from ignore if actually translated
|
||||
sort_ignore_translation[language]["ignore"].remove(default_key)
|
||||
if default_value != file_value and default_key in sort_ignore_translation[language]["ignore"]:
|
||||
if default_key == "language.direction":
|
||||
continue
|
||||
# Remove from ignore if actually translated
|
||||
sort_ignore_translation[language]["ignore"].remove(default_key)
|
||||
|
||||
if show_missing_keys:
|
||||
if len(missing_str_keys) > 0:
|
||||
|
||||
@@ -116,11 +116,7 @@ def _classify_backend(package_name: str) -> str | None:
|
||||
return "saas"
|
||||
if p.startswith("stirling.software.proprietary"):
|
||||
return "proprietary"
|
||||
if (
|
||||
p.startswith("stirling.software.SPDF")
|
||||
or p.startswith("stirling.software.common")
|
||||
or p.startswith("org.apache.pdfbox")
|
||||
):
|
||||
if p.startswith(("stirling.software.SPDF", "stirling.software.common", "org.apache.pdfbox")):
|
||||
return "core"
|
||||
return None
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ def _parse_jacoco_xml(path: Path) -> dict[str, CounterTotals]:
|
||||
|
||||
def _bar(pct: float, width: int = 20) -> str:
|
||||
"""Render a fixed-width ASCII progress bar. Markdown-safe on all consoles."""
|
||||
filled = int(round(pct / 100.0 * width))
|
||||
filled = round(pct / 100.0 * width)
|
||||
return "[" + "#" * filled + "-" * (width - filled) + "]"
|
||||
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ def download_pdf(
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
dest.write_bytes(content)
|
||||
return url, dest, None
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
except (OSError, ValueError, requests.RequestException) as exc:
|
||||
return url, None, str(exc)
|
||||
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ def collect_known_signatures(signatures_dir: Path) -> dict[str, dict]:
|
||||
for json_file in signatures_dir.rglob("*.json"):
|
||||
try:
|
||||
payload = load_signature_file(json_file)
|
||||
except Exception:
|
||||
except (OSError, ValueError, TypeError, json.JSONDecodeError):
|
||||
continue
|
||||
pdf = payload.get("pdf")
|
||||
for font in payload.get("fonts", []):
|
||||
@@ -148,9 +148,9 @@ def run_signature_tool(gradle_cmd: str, pdf: Path, output_path: Path, pretty: bo
|
||||
cmd,
|
||||
shell=True,
|
||||
cwd=cwd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if completed.returncode != 0:
|
||||
raise RuntimeError(f"Gradle Type3SignatureTool failed for {pdf}:\n{completed.stderr.strip()}")
|
||||
@@ -179,7 +179,7 @@ def extract_fonts_from_payload(payload: dict) -> list[dict]:
|
||||
def write_report(report_path: Path, fonts_by_signature: dict[str, dict]) -> None:
|
||||
ordered = sorted(fonts_by_signature.values(), key=lambda entry: entry["signature"])
|
||||
report = {
|
||||
"generatedAt": dt.datetime.utcnow().isoformat(timespec="seconds") + "Z",
|
||||
"generatedAt": dt.datetime.now(dt.UTC).isoformat(timespec="seconds").replace("+00:00", "Z"),
|
||||
"totalSignatures": len(ordered),
|
||||
"fonts": ordered,
|
||||
}
|
||||
@@ -202,13 +202,13 @@ def main() -> None:
|
||||
if signature_path.exists() and not args.force:
|
||||
try:
|
||||
payload = load_signature_file(signature_path)
|
||||
except Exception as exc:
|
||||
except (OSError, ValueError, TypeError, json.JSONDecodeError) as exc:
|
||||
print(f"[WARN] Failed to parse cached signature {signature_path}: {exc}")
|
||||
payload = None
|
||||
else:
|
||||
try:
|
||||
run_signature_tool(args.gradle_cmd, pdf, signature_path, args.pretty, REPO_ROOT)
|
||||
except Exception as exc:
|
||||
except (OSError, RuntimeError, subprocess.SubprocessError) as exc:
|
||||
print(f"[ERROR] Harvest failed for {pdf}: {exc}", file=sys.stderr)
|
||||
continue
|
||||
payload = load_signature_file(signature_path)
|
||||
|
||||
@@ -8,7 +8,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
def run(cmd, cwd=None):
|
||||
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, check=False)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(f"Command {' '.join(cmd)} failed: {result.stderr}")
|
||||
return result.stdout
|
||||
@@ -55,7 +55,7 @@ def main():
|
||||
for pdf in sorted(samples_dir.glob("*.pdf")):
|
||||
try:
|
||||
output = run(["pdffonts", str(pdf)])
|
||||
except Exception as exc:
|
||||
except (OSError, RuntimeError) as exc:
|
||||
print(f"Skipping {pdf.name}: {exc}")
|
||||
continue
|
||||
for font_name, encoding in parse_pdffonts(output):
|
||||
|
||||
@@ -48,11 +48,9 @@ SKIP_URL_FRAGMENTS = (
|
||||
def _is_app_url(url: str) -> bool:
|
||||
if not url:
|
||||
return False
|
||||
if not (url.startswith("http://") or url.startswith("https://")):
|
||||
if not (url.startswith(("http://", "https://"))):
|
||||
return False
|
||||
if any(frag in url for frag in SKIP_URL_FRAGMENTS):
|
||||
return False
|
||||
return True
|
||||
return not any(frag in url for frag in SKIP_URL_FRAGMENTS)
|
||||
|
||||
|
||||
def aggregate(dump_dir: Path) -> dict:
|
||||
|
||||
@@ -61,7 +61,7 @@ def cached_version() -> str | None:
|
||||
if not BIN.exists():
|
||||
return None
|
||||
try:
|
||||
return subprocess.run([str(BIN), "version"], capture_output=True, text=True).stdout.strip()
|
||||
return subprocess.run([str(BIN), "version"], capture_output=True, text=True, check=False).stdout.strip()
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import csv
|
||||
import json
|
||||
import re
|
||||
import tomllib
|
||||
from datetime import datetime
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -28,7 +28,7 @@ class AITranslationHelper:
|
||||
try:
|
||||
with open(file_path, "rb") as f:
|
||||
return tomllib.load(f)
|
||||
except (FileNotFoundError, Exception) as e:
|
||||
except (OSError, tomllib.TOMLDecodeError) as e:
|
||||
print(f"Error loading {file_path}: {e}")
|
||||
return {}
|
||||
|
||||
@@ -47,7 +47,7 @@ class AITranslationHelper:
|
||||
golden_truth = self._load_translation_file(self.golden_truth_file)
|
||||
batch_data = {
|
||||
"metadata": {
|
||||
"created_at": datetime.now().isoformat(),
|
||||
"created_at": datetime.now(UTC).isoformat(),
|
||||
"source_language": "en-US",
|
||||
"target_languages": languages,
|
||||
"max_entries_per_language": max_entries_per_language,
|
||||
@@ -105,9 +105,8 @@ class AITranslationHelper:
|
||||
key not in lang_flat
|
||||
or lang_flat[key] == value
|
||||
or (isinstance(lang_flat[key], str) and lang_flat[key].startswith("[UNTRANSLATED]"))
|
||||
):
|
||||
if not self._is_expected_identical(key, value):
|
||||
untranslated[key] = value
|
||||
) and not self._is_expected_identical(key, value):
|
||||
untranslated[key] = value
|
||||
|
||||
return untranslated
|
||||
|
||||
@@ -286,7 +285,7 @@ class AITranslationHelper:
|
||||
golden_flat = self._flatten_dict(golden_truth)
|
||||
|
||||
if output_format == "csv":
|
||||
output_file = Path(f"translations_export_{datetime.now().strftime('%Y%m%d')}.csv")
|
||||
output_file = Path(f"translations_export_{datetime.now(UTC).strftime('%Y%m%d')}.csv")
|
||||
|
||||
with open(output_file, "w", newline="", encoding="utf-8") as csvfile:
|
||||
fieldnames = ["key", "context", "en_US"] + languages
|
||||
@@ -322,7 +321,7 @@ class AITranslationHelper:
|
||||
print(f"Exported to {output_file}")
|
||||
|
||||
elif output_format == "json":
|
||||
output_file = Path(f"translations_export_{datetime.now().strftime('%Y%m%d')}.json")
|
||||
output_file = Path(f"translations_export_{datetime.now(UTC).strftime('%Y%m%d')}.json")
|
||||
export_data = {"languages": languages, "translations": {}}
|
||||
|
||||
for key, en_value in golden_flat.items():
|
||||
|
||||
@@ -10,9 +10,9 @@ import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import time
|
||||
import tomllib
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ def run_command(cmd, description=""):
|
||||
print(f"Step: {description}")
|
||||
print(f"{'=' * 60}")
|
||||
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, check=False)
|
||||
|
||||
if result.stdout:
|
||||
print(result.stdout)
|
||||
@@ -155,7 +155,7 @@ def translate_batches(batch_files, language_code, api_key, timeout=600, model="g
|
||||
cmd = f'python3 scripts/translations/batch_translator.py "{batch_file}" --language {language_code} --api-key "{api_key}" --model {model}'
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout, check=False)
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"✗ Timed out after {timeout}s: {batch_file}", file=sys.stderr)
|
||||
return None
|
||||
@@ -388,7 +388,7 @@ Examples:
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n⚠ Translation interrupted by user")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
except (OSError, ValueError, RuntimeError, subprocess.SubprocessError) as e:
|
||||
print(f"\n\n✗ Error: {e}")
|
||||
import traceback
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ Return ONLY the translated JSON. No markdown, no explanations, just the JSON obj
|
||||
print(f"Error: AI returned invalid JSON: {e}")
|
||||
print(f"Response: {translated_text[:500]}...")
|
||||
raise
|
||||
except Exception as e:
|
||||
except (OSError, ValueError, KeyError, RuntimeError) as e:
|
||||
print(f"Error during translation: {e}")
|
||||
raise
|
||||
|
||||
@@ -182,11 +182,11 @@ Return ONLY the translated JSON. No markdown, no explanations, just the JSON obj
|
||||
|
||||
placeholder_pattern = r"\{[^}]+\}|\{\{[^}]+\}\}"
|
||||
|
||||
for key in original.keys():
|
||||
for key, original_value in original.items():
|
||||
if key not in translated:
|
||||
continue
|
||||
|
||||
orig_value = str(original[key])
|
||||
orig_value = str(original_value)
|
||||
trans_value = str(translated[key])
|
||||
|
||||
# Find all placeholders in original
|
||||
@@ -366,7 +366,7 @@ Examples:
|
||||
if i < len(input_files):
|
||||
time.sleep(args.delay)
|
||||
|
||||
except Exception as e:
|
||||
except (OSError, ValueError, KeyError, RuntimeError) as e:
|
||||
print(f"✗ Failed: {e}")
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
@@ -79,7 +79,7 @@ def get_language_completion(locales_dir: Path, language: str) -> float | None:
|
||||
|
||||
return (translated / total * 100) if total > 0 else 0.0
|
||||
|
||||
except Exception as e:
|
||||
except (OSError, TypeError, KeyError, ValueError, tomllib.TOMLDecodeError) as e:
|
||||
print(f"Warning: Could not calculate completion for {language}: {e}")
|
||||
return None
|
||||
|
||||
@@ -124,6 +124,7 @@ def translate_language(
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
timeout=timeout * 5, # Overall timeout = 5x per-batch timeout
|
||||
)
|
||||
|
||||
@@ -144,8 +145,8 @@ def translate_language(
|
||||
except subprocess.TimeoutExpired:
|
||||
safe_print(f"[{language}] ✗ Timeout exceeded")
|
||||
return (language, False, "Timeout exceeded")
|
||||
except Exception as e:
|
||||
safe_print(f"[{language}] ✗ Error: {str(e)}")
|
||||
except (OSError, TypeError, KeyError, ValueError, tomllib.TOMLDecodeError) as e:
|
||||
safe_print(f"[{language}] ✗ Error: {e!s}")
|
||||
return (language, False, str(e))
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class CompactTranslationExtractor:
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File not found: {file_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError) as e:
|
||||
print(f"Error: Invalid TOML file {file_path}: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -51,7 +51,7 @@ class CompactTranslationExtractor:
|
||||
with open(self.ignore_file, "rb") as f:
|
||||
ignore_data = tomllib.load(f)
|
||||
return {lang: set(data.get("ignore", [])) for lang, data in ignore_data.items()}
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError, TypeError, AttributeError) as e:
|
||||
print(
|
||||
f"Warning: Could not load ignore file {self.ignore_file}: {e}",
|
||||
file=sys.stderr,
|
||||
|
||||
@@ -28,7 +28,7 @@ class TOMLBeautifier:
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File not found: {file_path}")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError) as e:
|
||||
print(f"Error: Invalid TOML in {file_path}: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -172,11 +172,11 @@ class TOMLBeautifier:
|
||||
|
||||
def get_key_order(obj: dict, path: str = "") -> list[str]:
|
||||
keys = []
|
||||
for key in obj.keys():
|
||||
for key, value in obj.items():
|
||||
new_path = f"{path}.{key}" if path else key
|
||||
keys.append(new_path)
|
||||
if isinstance(obj[key], dict):
|
||||
keys.extend(get_key_order(obj[key], new_path))
|
||||
if isinstance(value, dict):
|
||||
keys.extend(get_key_order(value, new_path))
|
||||
return keys
|
||||
|
||||
golden_order = get_key_order(self.golden_structure)
|
||||
|
||||
@@ -33,7 +33,7 @@ def get_line_context(file_path, line_num, context_lines=3):
|
||||
context.append(f"{marker}{i + 1:4d}: {lines[i].rstrip()}")
|
||||
|
||||
return "\n".join(context)
|
||||
except Exception as e:
|
||||
except (OSError, UnicodeError, IndexError) as e:
|
||||
return f"Could not read context: {e}"
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ def get_character_context(file_path, char_pos, context_chars=100):
|
||||
"after": after,
|
||||
"display": f"{before}[{error_char}]{after}",
|
||||
}
|
||||
except Exception:
|
||||
except (IndexError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ def validate_toml_file(file_path):
|
||||
result["valid"] = True
|
||||
result["entry_count"] = count_keys(data)
|
||||
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError, TypeError, ValueError) as e:
|
||||
error_msg = str(e)
|
||||
result["error"] = error_msg
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class TranslationAnalyzer:
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File not found: {file_path}")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError) as e:
|
||||
print(f"Error: Invalid file {file_path}: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -51,7 +51,7 @@ class TranslationAnalyzer:
|
||||
for patterns in [data.get("ignore", [])]
|
||||
if patterns
|
||||
}
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError, TypeError, AttributeError) as e:
|
||||
print(f"Warning: Could not load ignore file {self.ignore_file}: {e}")
|
||||
return {}
|
||||
|
||||
@@ -165,9 +165,8 @@ class TranslationAnalyzer:
|
||||
for key in relevant_keys:
|
||||
if key in target_flat:
|
||||
value = target_flat[key]
|
||||
if not (isinstance(value, str) and value.startswith("[UNTRANSLATED]")):
|
||||
if key not in untranslated: # Not identical to en-US (unless expected)
|
||||
properly_translated += 1
|
||||
if not (isinstance(value, str) and value.startswith("[UNTRANSLATED]")) and key not in untranslated:
|
||||
properly_translated += 1
|
||||
|
||||
completion_rate = (properly_translated / total_keys) * 100 if total_keys > 0 else 0
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
import tomllib
|
||||
from datetime import datetime
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -39,14 +39,14 @@ class TranslationMerger:
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File not found: {file_path}")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError) as e:
|
||||
print(f"Error: Invalid file {file_path}: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
def _save_translation_file(self, data: dict[str, Any], file_path: Path, backup: bool = False) -> None:
|
||||
"""Save TOML translation file with backup option."""
|
||||
if backup and file_path.exists():
|
||||
backup_path = file_path.with_suffix(f".backup.{datetime.now().strftime('%Y%m%d_%H%M%S')}.toml")
|
||||
backup_path = file_path.with_suffix(f".backup.{datetime.now(UTC).strftime('%Y%m%d_%H%M%S')}.toml")
|
||||
shutil.copy2(file_path, backup_path)
|
||||
print(f"Backup created: {backup_path}")
|
||||
|
||||
@@ -64,7 +64,7 @@ class TranslationMerger:
|
||||
|
||||
# Convert to sets for faster lookup
|
||||
return {lang: set(data.get("ignore", [])) for lang, data in ignore_data.items()}
|
||||
except Exception as e:
|
||||
except (OSError, tomllib.TOMLDecodeError, TypeError, AttributeError) as e:
|
||||
print(f"Warning: Could not load ignore file {self.ignore_file}: {e}")
|
||||
return {}
|
||||
|
||||
@@ -264,7 +264,7 @@ class TranslationMerger:
|
||||
|
||||
self._set_nested_value(target_data, key, translation)
|
||||
applied_count += 1
|
||||
except Exception as e:
|
||||
except (KeyError, TypeError, ValueError) as e:
|
||||
errors.append(f"Error setting {key}: {e}")
|
||||
|
||||
if applied_count > 0:
|
||||
@@ -316,7 +316,7 @@ class TranslationMerger:
|
||||
"source_language": "en-US",
|
||||
"target_language": target_file.parent.name,
|
||||
"total_entries": len(untranslated),
|
||||
"created_at": datetime.now().isoformat(),
|
||||
"created_at": datetime.now(UTC).isoformat(),
|
||||
"instructions": 'Translate the "original" values to the target language. Keep the same keys.',
|
||||
},
|
||||
"translations": {},
|
||||
|
||||
@@ -37,8 +37,8 @@ def validate_translation_file(file_path: Path) -> tuple[bool, str]:
|
||||
with open(file_path, "rb") as f:
|
||||
tomllib.load(f)
|
||||
return True, "Valid TOML"
|
||||
except Exception as e:
|
||||
return False, f"Error reading file: {str(e)}"
|
||||
except (OSError, tomllib.TOMLDecodeError) as e:
|
||||
return False, f"Error reading file: {e!s}"
|
||||
|
||||
|
||||
def validate_structure(en_us_keys: set[str], lang_keys: set[str], lang_code: str) -> dict:
|
||||
@@ -139,9 +139,8 @@ def main():
|
||||
# Validate all languages except en-US
|
||||
languages = []
|
||||
for d in locales_dir.iterdir():
|
||||
if d.is_dir() and d.name != "en-US":
|
||||
if (d / "translation.toml").exists():
|
||||
languages.append(d.name)
|
||||
if d.is_dir() and d.name != "en-US" and (d / "translation.toml").exists():
|
||||
languages.append(d.name)
|
||||
|
||||
results = []
|
||||
json_errors = []
|
||||
|
||||
@@ -40,11 +40,11 @@ def validate_language(en_us_flat: dict[str, str], lang_flat: dict[str, str], lan
|
||||
"""Validate placeholders for a language against en-US."""
|
||||
issues = []
|
||||
|
||||
for key in en_us_flat:
|
||||
for key, en_text in en_us_flat.items():
|
||||
if key not in lang_flat:
|
||||
continue
|
||||
|
||||
en_placeholders = find_placeholders(en_us_flat[key])
|
||||
en_placeholders = find_placeholders(en_text)
|
||||
lang_placeholders = find_placeholders(lang_flat[key])
|
||||
|
||||
if en_placeholders != lang_placeholders:
|
||||
@@ -56,7 +56,7 @@ def validate_language(en_us_flat: dict[str, str], lang_flat: dict[str, str], lan
|
||||
"key": key,
|
||||
"missing": missing,
|
||||
"extra": extra,
|
||||
"en_text": en_us_flat[key],
|
||||
"en_text": en_text,
|
||||
"lang_text": lang_flat[key],
|
||||
}
|
||||
issues.append(issue)
|
||||
@@ -127,9 +127,8 @@ def main():
|
||||
# Validate all languages except en-US
|
||||
languages = []
|
||||
for d in locales_dir.iterdir():
|
||||
if d.is_dir() and d.name != "en-US":
|
||||
if (d / "translation.toml").exists():
|
||||
languages.append(d.name)
|
||||
if d.is_dir() and d.name != "en-US" and (d / "translation.toml").exists():
|
||||
languages.append(d.name)
|
||||
|
||||
all_issues = []
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ def load_json(path: Path) -> dict[str, object]:
|
||||
try:
|
||||
with path.open("r", encoding="utf-8") as handle:
|
||||
return json.load(handle)
|
||||
except Exception as exc: # pragma: no cover - fatal configuration error
|
||||
except (OSError, UnicodeError, json.JSONDecodeError) as exc: # pragma: no cover - fatal configuration error
|
||||
print(f"ERROR: Failed to load glyph JSON '{path}': {exc}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
@@ -298,7 +298,7 @@ def build_ttf_glyph(glyph: GlyphSource, max_error: float) -> object | None:
|
||||
|
||||
try:
|
||||
glyph_obj = pen.glyph()
|
||||
except Exception:
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
return None
|
||||
return glyph_obj
|
||||
|
||||
@@ -472,7 +472,7 @@ def main() -> None:
|
||||
units_per_em=args.units_per_em,
|
||||
cu2qu_error=args.cu2qu_error,
|
||||
)
|
||||
except Exception as exc:
|
||||
except (OSError, ValueError, TypeError, RuntimeError) as exc:
|
||||
print(f"ERROR: Failed to generate fonts: {exc}", file=sys.stderr)
|
||||
if otf_output.exists():
|
||||
otf_output.unlink()
|
||||
|
||||
@@ -100,7 +100,7 @@ def normalize_source_path(pdf_path: str | None) -> str | None:
|
||||
try:
|
||||
source = Path(pdf_path)
|
||||
rel = source.relative_to(REPO_ROOT)
|
||||
except Exception:
|
||||
except ValueError:
|
||||
rel = Path(pdf_path)
|
||||
return str(rel).replace("\\", "/")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user