Recent commits to derivepassphrase.git (f3bcf5b55a4aa19b733a1d1fa9562ff201f06adf) https://git.schokokeks.org/derivepassphrase.git/tree/f3bcf5b55a4aa19b733a1d1fa9562ff201f06adf Recent commits feed provided by GitList. Ensure that `pytest` picks up the newly-split test modules again If a test module is merely converted to a package, then `pytest` will no longer pick it up, because the name `__init__.py` does not match the test module name pattern anymore. So, rename them. Also set the `pytest` import mode to `importlib`, as per the documentation's suggestion. I haven't had any trouble with this *yet*, but now I have similarly named modules, so this might otherwise crop up in the future. https://git.schokokeks.org/derivepassphrase.git/commit/f3bcf5b55a4aa19b733a1d1fa9562ff201f06adf software@the13thletter.info (Marco Ricci) Sat, 09 Aug 2025 18:49:50 +0200 f3bcf5b55a4aa19b733a1d1fa9562ff201f06adf Split the CLI tests into one file per class/group The CLI tests, already loosely grouped through the use of classes, are now distributed to different files, one file per test class. This is mostly an attempt to keep the file size managable. Navigating in a multi-thousand-line Python file with very similar looking tests gets disorienting very quickly. https://git.schokokeks.org/derivepassphrase.git/commit/9ad57b1f6bde28fb9da3f0a3bd2fd4188455dd2a software@the13thletter.info (Marco Ricci) Sat, 09 Aug 2025 16:22:42 +0200 9ad57b1f6bde28fb9da3f0a3bd2fd4188455dd2a Format and lint all test files https://git.schokokeks.org/derivepassphrase.git/commit/d4cd8ce103374859a324c50deab8954a08c4626d software@the13thletter.info (Marco Ricci) Sat, 09 Aug 2025 15:19:17 +0200 d4cd8ce103374859a324c50deab8954a08c4626d Use leaf module imports in all test modules Instead of importing submodules and navigating to them via the top-level module (`import spam.ham.eggs`), use leaf module imports (`from spam.ham import eggs`). Though there is sometimes the need to rename the imported module, doing so leads to shorter expressions in general. It also allows static analysis tools to accurately detect whether a module is in use or not. (Such a detection is much more murky if the whole module path needs to be traversed each time.) https://git.schokokeks.org/derivepassphrase.git/commit/a5135873c0ebd313b0272b449b620a10115511f3 software@the13thletter.info (Marco Ricci) Sat, 09 Aug 2025 15:12:40 +0200 a5135873c0ebd313b0272b449b620a10115511f3 Split off "heavy duty" tests from the respective test file Split off the slow, `hypothesis`-based integration tests (the "heavy duty" tests) from the `test_derivepassphrase_cli`, `test_derivepassphrase_ssh_agent` and `test_derivepassphrase_types` modules into separate submodules named `heavy_duty`. Additionally, mark the contents of these `heavy_duty` submodules with the `heavy_duty` `pytest` mark. We do this both because the integration tests are slow and because they are relatively large per test: you typically write a whole new class plus support code per test, plus you reexport one of the class's attributes as a top-level, auto-discoverable test. Though specifically marked, the tests are still run by default. https://git.schokokeks.org/derivepassphrase.git/commit/493fe930240feade37cec6aef097a9740cea550e software@the13thletter.info (Marco Ricci) Sat, 09 Aug 2025 14:44:43 +0200 493fe930240feade37cec6aef097a9740cea550e Turn the `vault` test config functions into methods Turn the `is_valid_test_config`, `is_smudgable_vault_test_config` and `_test_config_ids` functions into methods of the `VaultTestConfig` class: `is_valid`, `is_smudgable` and `_test_id`. This fits the overall intent of only providing types and some simple predicates or transformations, and it reads much nicer if a short method name is used instead of an explicit function name. (And if a one-argument function is required, it can be obtained, as a bound method, from the class.) https://git.schokokeks.org/derivepassphrase.git/commit/4b8ef3e200e3de1167e073c9163be34cd77205fa software@the13thletter.info (Marco Ricci) Fri, 08 Aug 2025 23:09:22 +0200 4b8ef3e200e3de1167e073c9163be34cd77205fa Reformat tests after refactoring https://git.schokokeks.org/derivepassphrase.git/commit/9216af9db7d5575dda22b5a5f5bffc028a446cd3 software@the13thletter.info (Marco Ricci) Fri, 08 Aug 2025 22:58:55 +0200 9216af9db7d5575dda22b5a5f5bffc028a446cd3 Split the top-level `tests` module into subpackages Split the top-level `tests` module into a pair of subpackages `tests.data` and `tests.machinery`, grouping them by import requirements. This "stratifies" the data, and (in some cases) reduces the amount of necessary support code while also (always) forcing us to carefully consider the scope and the prerequisites of every test support datum or function. As a practical example of the benefits of this stratification, the `test_key_signatures_and_outputs.py` script can get away with importing only the lowest stratum `tests.data`, and thus does not need `pytest` or `hypothesis` installed to run. There are five strata, defined by the five subordinate modules in the `tests` package: `tests.data`, `tests.data.callables`, `tests.machinery`, `tests.machinery.pytest` and `tests.machinery.hypothesis`. Each module may import from modules earlier in the list, but not later. The `tests.data.callables` submodule and the `tests.machinery` subpackage differ in that the `test.data.callables` are still expected to be functional and useful even without a testing system, the latter not necessarily. https://git.schokokeks.org/derivepassphrase.git/commit/f2b427b0887e6b0b4184cfb6353faf4d66cbe4de software@the13thletter.info (Marco Ricci) Fri, 08 Aug 2025 22:58:18 +0200 f2b427b0887e6b0b4184cfb6353faf4d66cbe4de Change the code style to use double quotes for strings As is standard in Python auto-formatting (Black, Ruff), we now use double quotes for strings where possible, reverting to single quotes only where necessary. (The numerous code changes in `scripts/`, `src/` and `tests/` stem from the auto-formatter re-adjusting the quotes.) Background: I originally started out as a Perl programmer, and in Perl, single quotes signify literal strings without any interpolation whatsoever, and double quotes signify strings with interpolation and escape sequences. In those languages, the choice of string quotes makes a subtle difference. In Python, the choice of quote character does not matter, so while there is no reason to prefer one over the other, the inertia of being used to "single means literal, double means interpolated" meant that I basically kept my existing style of quoting. Python, meanwhile, although careful not to *prescribe* one quote character or the other (see PEP 8), uses double quotes by default in `str.__repr__` and in docstrings (see PEP 257). The Black auto-formatter, which Ruff is modeled on, also defaults to double quotes, arguing in its style guide that (among other things) the empty string with double quotes unambiguously looks like an empty string, regardless of fonts and syntax highlighting, but the empty string with single quotes not necessarily: it may look like a single double quote character. More importantly, auto-formatters are specifically designed to make these (essentially arbitrary) decisions about code formatting for you, in the name of a uniform code style such that a reader can focus on the code *content*, not the code *presentation*. The concrete set of arbitrary decisions is essentially secondary, but the Black team (and the Ruff team too) have a pretty good track record of keeping the resulting code readable and sensibly diffable, and this styling decision has long been established by Black and "blackened" code "in the wild" (and thus tested), so I have no reason to object to this particular arbitrary choice. Furthermore, there's no need to manually adjust all quote characters, or even to pay much attention during code authoring to the quote characters; the auto-formatting pass will take care of harmonizing them for you. Given these reasons, continuing to insist on single-quoted strings, in Python, out of some vague sense of familiarity with *other* programming languages where quote characters have different meanings, seems rather untenable to me. https://git.schokokeks.org/derivepassphrase.git/commit/e98174420e001619acfd84a076f9df498076c89c software@the13thletter.info (Marco Ricci) Tue, 05 Aug 2025 21:11:03 +0200 e98174420e001619acfd84a076f9df498076c89c Merge topic branch 'ssh-agent-socket-providers' into master * ssh-agent-socket-providers: Add a changelog entry for the SSH agent socket provider feature Make all command/format/feature enums self-testing Document the new level of support for SSH agents (also in `--version` output) Update the "SSH key" feature flag in `--version` output Support looking up a socket provider, even if merely registered Add tests for the SSH agent socket provider machinery Introduce a stubbed SSH agent, for testing Introduce SSH agent socket providers Turn the `ssh_agent` submodule into a subpackage Generalize the error message for missing SSH agent support https://git.schokokeks.org/derivepassphrase.git/commit/0003d4596d632d41c7c03ff8145c152c9d0e4531 software@the13thletter.info (Marco Ricci) Mon, 04 Aug 2025 21:41:47 +0200 0003d4596d632d41c7c03ff8145c152c9d0e4531