Sourcing python-remove-tests-dir-hook Sourcing python-catch-conflicts-hook.sh Sourcing python-remove-bin-bytecode-hook.sh Sourcing pypa-build-hook Using pypaBuildPhase Sourcing python-runtime-deps-check-hook Using pythonRuntimeDepsCheckHook Sourcing pypa-install-hook Using pypaInstallPhase Sourcing python-imports-check-hook.sh Using pythonImportsCheckPhase Sourcing python-namespaces-hook Sourcing python-catch-conflicts-hook.sh Sourcing pytest-check-hook Using pytestCheckPhase Running phase: unpackPhase unpacking source archive /nix/store/nbbck5mbjbvf4ndsly4l1kzm9i7lbczv-zhost-cli source root is zhost-cli setting SOURCE_DATE_EPOCH to timestamp 315619200 of file "zhost-cli/zhost_cli/pdf.py" Running phase: patchPhase Running phase: updateAutotoolsGnuConfigScriptsPhase Running phase: configurePhase no configure script, doing nothing Running phase: buildPhase Executing pypaBuildPhase Creating a wheel... pypa build flags: --no-isolation --outdir dist/ --wheel * Getting build dependencies for wheel... * Building wheel... Successfully built zhost_cli-0.1.0-py3-none-any.whl Finished creating a wheel... Finished executing pypaBuildPhase Running phase: pythonRuntimeDepsCheckHook Executing pythonRuntimeDepsCheck Checking runtime dependencies for zhost_cli-0.1.0-py3-none-any.whl Finished executing pythonRuntimeDepsCheck Running phase: installPhase Executing pypaInstallPhase Successfully installed zhost_cli-0.1.0-py3-none-any.whl Finished executing pypaInstallPhase Running phase: pythonOutputDistPhase Executing pythonOutputDistPhase Finished executing pythonOutputDistPhase Running phase: fixupPhase shrinking RPATHs of ELF executables and libraries in /nix/store/xwmk6nwcd8qiyd9k3kzd6jvv53jxgc8x-zhost-cli-0.1.0 checking for references to /build/ in /nix/store/xwmk6nwcd8qiyd9k3kzd6jvv53jxgc8x-zhost-cli-0.1.0... patching script interpreter paths in /nix/store/xwmk6nwcd8qiyd9k3kzd6jvv53jxgc8x-zhost-cli-0.1.0 stripping (with command strip and flags -S -p) in /nix/store/xwmk6nwcd8qiyd9k3kzd6jvv53jxgc8x-zhost-cli-0.1.0/lib /nix/store/xwmk6nwcd8qiyd9k3kzd6jvv53jxgc8x-zhost-cli-0.1.0/bin shrinking RPATHs of ELF executables and libraries in /nix/store/5rj6v5fd4q4iprwv95vyv820fpymilkk-zhost-cli-0.1.0-dist checking for references to /build/ in /nix/store/5rj6v5fd4q4iprwv95vyv820fpymilkk-zhost-cli-0.1.0-dist... patching script interpreter paths in /nix/store/5rj6v5fd4q4iprwv95vyv820fpymilkk-zhost-cli-0.1.0-dist Rewriting #!/nix/store/gxzhl7aaiid7zp3y47jqqiq7zg5mqpwp-python3-3.14.6/bin/python3.14 to #!/nix/store/gxzhl7aaiid7zp3y47jqqiq7zg5mqpwp-python3-3.14.6 wrapping `/nix/store/xwmk6nwcd8qiyd9k3kzd6jvv53jxgc8x-zhost-cli-0.1.0/bin/zhost-cli'... Executing pythonRemoveTestsDir Finished executing pythonRemoveTestsDir Running phase: installCheckPhase no Makefile or custom installCheckPhase, doing nothing Running phase: pythonCatchConflictsPhase Running phase: pythonRemoveBinBytecodePhase Running phase: pythonImportsCheckPhase Executing pythonImportsCheckPhase Running phase: pytestCheckPhase Executing pytestCheckPhase 12 files already formatted RUF012 Mutable default value for class attribute --> tests/test_cli.py:19:46 | 17 | class State: 18 | version = 10 19 | collections: dict[str, dict[str, Any]] = {} | ^^ 20 | items: dict[str, dict[str, Any]] = {} 21 | settings: dict[str, dict[str, Any]] = {} | help: Consider initializing in `__init__` or annotating with `typing.ClassVar` RUF012 Mutable default value for class attribute --> tests/test_cli.py:20:40 | 18 | version = 10 19 | collections: dict[str, dict[str, Any]] = {} 20 | items: dict[str, dict[str, Any]] = {} | ^^ 21 | settings: dict[str, dict[str, Any]] = {} 22 | fulltext: dict[str, dict[str, Any]] = {} | help: Consider initializing in `__init__` or annotating with `typing.ClassVar` RUF012 Mutable default value for class attribute --> tests/test_cli.py:21:43 | 19 | collections: dict[str, dict[str, Any]] = {} 20 | items: dict[str, dict[str, Any]] = {} 21 | settings: dict[str, dict[str, Any]] = {} | ^^ 22 | fulltext: dict[str, dict[str, Any]] = {} 23 | requests: list[dict[str, Any]] = [] | help: Consider initializing in `__init__` or annotating with `typing.ClassVar` RUF012 Mutable default value for class attribute --> tests/test_cli.py:22:43 | 20 | items: dict[str, dict[str, Any]] = {} 21 | settings: dict[str, dict[str, Any]] = {} 22 | fulltext: dict[str, dict[str, Any]] = {} | ^^ 23 | requests: list[dict[str, Any]] = [] 24 | counter = 0 | help: Consider initializing in `__init__` or annotating with `typing.ClassVar` RUF012 Mutable default value for class attribute --> tests/test_cli.py:23:38 | 21 | settings: dict[str, dict[str, Any]] = {} 22 | fulltext: dict[str, dict[str, Any]] = {} 23 | requests: list[dict[str, Any]] = [] | ^^ 24 | counter = 0 | help: Consider initializing in `__init__` or annotating with `typing.ClassVar` UP043 [*] Unnecessary default type arguments --> tests/test_cli.py:261:48 | 260 | @pytest.fixture() 261 | def server(monkeypatch: pytest.MonkeyPatch) -> Generator[str, None, None]: | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 262 | State.version, State.collections, State.items, State.requests, State.counter = ( 263 | 10, | help: Remove default type arguments | 260 | @pytest.fixture() - def server(monkeypatch: pytest.MonkeyPatch) -> Generator[str, None, None]: 261 + def server(monkeypatch: pytest.MonkeyPatch) -> Generator[str]: 262 | State.version, State.collections, State.items, State.requests, State.counter = ( | RUF015 Prefer `next(...)` over single element slice --> tests/test_cli.py:325:9 | 323 | main(["-j", "item", "find", "x"]) 324 | assert {i["key"] for i in json.loads(capsys.readouterr().out)} == {"PAPER222"} 325 | q = [r for r in _reqs("GET", "/users/1/items") if "q" in r["query"]][0] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 326 | assert q["query"]["qmode"] == ["everything"] | help: Replace with `next(...)` RUF015 Prefer `next(...)` over single element slice --> tests/test_cli.py:412:12 | 410 | State.items["PAPER222"] = {"key": "PAPER222", "itemType": "journalArticle"} 411 | main(["note", "add", "PAPER222", "--text", "
hi
"]) 412 | note = [ | ____________^ 413 | | r for r in _reqs("POST", "/users/1/items") if r["body"][0]["itemType"] == "note" 414 | | ][0] | |________^ 415 | assert note["body"][0]["parentItem"] == "PAPER222" 416 | main(["note", "list", "PAPER222"]) | help: Replace with `next(...)` SIM115 Use a context manager for opening files --> tests/test_cli.py:424:5 | 422 | ) -> None: 423 | pdf = f"{tmp_path}/p.pdf" 424 | open(pdf, "wb").write(b"%PDF-1.7 data") | ^^^^ 425 | State.items["PAPER222"] = {"key": "PAPER222", "itemType": "journalArticle"} 426 | main(["pdf", "attach", "PAPER222", "--pdf", pdf]) | RUF015 Prefer `next(...)` over single element slice --> tests/test_cli.py:429:11 | 427 | assert any(r["path"].startswith("/uploads/") for r in State.requests) 428 | # the attachment was created under the paper 429 | att = [ | ___________^ 430 | | r 431 | | for r in _reqs("POST", "/users/1/items") 432 | | if r["body"][0]["itemType"] == "attachment" 433 | | ][0] | |________^ 434 | assert att["body"][0]["parentItem"] == "PAPER222" 435 | out_path = f"{tmp_path}/dl.pdf" | help: Replace with `next(...)` SIM115 Use a context manager for opening files --> tests/test_cli.py:437:12 | 435 | out_path = f"{tmp_path}/dl.pdf" 436 | main(["pdf", "fetch", "PAPER222", "--output", out_path]) 437 | assert open(out_path, "rb").read().startswith(b"%PDF") | ^^^^ RUF015 Prefer `next(...)` over single element slice --> tests/test_cli.py:458:11 | 456 | } 457 | main(["highlight", "add", "PAPER222", "--pdf", pdf, "--text", "highlight this"]) 458 | ann = [ | ___________^ 459 | | r 460 | | for r in _reqs("POST", "/users/1/items") 461 | | if r["body"][0]["itemType"] == "annotation" 462 | | ][0] | |________^ 463 | assert ann["body"][0]["parentItem"] == "ATTAC222" 464 | assert ann["body"][0]["annotationText"] == "highlight this" | help: Replace with `next(...)` SIM115 Use a context manager for opening files --> tests/test_cli.py:503:5 | 501 | ) -> None: 502 | pdf = f"{tmp_path}/p.pdf" 503 | open(pdf, "wb").write(b"%PDF-1.7 data") | ^^^^ 504 | main(["-j", "item", "add", "--title", "P", "--pdf", pdf]) 505 | out = json.loads(capsys.readouterr().out) | SIM115 Use a context manager for opening files --> tests/test_cli.py:546:5 | 544 | ) -> None: 545 | pdf = f"{tmp_path}/p.pdf" 546 | open(pdf, "wb").write(b"%PDF-1.7 new") | ^^^^ 547 | State.items["PAPER222"] = {"key": "PAPER222", "itemType": "journalArticle"} 548 | State.items["ATTAC222"] = { | SIM115 Use a context manager for opening files --> tests/test_cli.py:656:27 | 654 | main(["library", "export", out]) 655 | 656 | manifest = json.loads(open(f"{out}/manifest.json").read()) | ^^^^ 657 | assert manifest["counts"]["items"] == 1 # one top-level paper | SIM115 Use a context manager for opening files --> tests/test_cli.py:659:22 | 657 | assert manifest["counts"]["items"] == 1 # one top-level paper 658 | 659 | rec = json.loads(open(f"{out}/items/PAPER222.json").read()) | ^^^^ 660 | assert rec["item"]["data"]["title"] == "P" 661 | assert {c["key"] for c in rec["children"]} == {"ATTAC222", "NOTE2222"} | SIM115 Use a context manager for opening files --> tests/test_cli.py:664:12 | 662 | assert rec["fulltext"]["ATTAC222"]["content"] == "full body" 663 | 664 | assert open(f"{out}/files/ATTAC222/p.pdf", "rb").read().startswith(b"%PDF") | ^^^^ 665 | colls = json.loads(open(f"{out}/collections.json").read()) 666 | assert any(c["key"] == "FOLDER22" for c in colls) | SIM115 Use a context manager for opening files --> tests/test_cli.py:665:24 | 664 | assert open(f"{out}/files/ATTAC222/p.pdf", "rb").read().startswith(b"%PDF") 665 | colls = json.loads(open(f"{out}/collections.json").read()) | ^^^^ 666 | assert any(c["key"] == "FOLDER22" for c in colls) | SIM115 Use a context manager for opening files --> tests/test_cli.py:717:43 | 715 | exported_items = {p[:-5] for p in os.listdir(f"{out}/items")} 716 | assert exported_items == {"PAPER222", "SUBPAP22", "CROSS222"} 717 | colls = {c["key"] for c in json.loads(open(f"{out}/collections.json").read())} | ^^^^ 718 | assert colls == {"ROOT2222", "FOLDER22", "SUBCOL22"} 719 | cross = json.loads(open(f"{out}/items/CROSS222.json").read()) | SIM115 Use a context manager for opening files --> tests/test_cli.py:719:24 | 717 | colls = {c["key"] for c in json.loads(open(f"{out}/collections.json").read())} 718 | assert colls == {"ROOT2222", "FOLDER22", "SUBCOL22"} 719 | cross = json.loads(open(f"{out}/items/CROSS222.json").read()) | ^^^^ 720 | assert cross["item"]["data"]["collections"] == ["FOLDER22"] | SIM115 Use a context manager for opening files --> tests/test_cli.py:734:27 | 732 | main(["library", "export", out]) 733 | 734 | settings = json.loads(open(f"{out}/settings.json").read()) | ^^^^ 735 | assert settings["tagColors"]["value"] == [{"name": "read", "color": "#5fb236"}] | SIM115 Use a context manager for opening files --> zhost_cli/client.py:274:16 | 272 | ) -> Response: 273 | """Run the full authorize -> upload -> register sequence for `path`.""" 274 | data = open(path, "rb").read() | ^^^^ 275 | md5 = hashlib.md5(data).hexdigest() 276 | stat = os.stat(path) | Found 22 errors. [*] 1 fixable with the `--fix` option (4 hidden fixes can be enabled with the `--unsafe-fixes` option).