git.schokokeks.org
Repositories
Help
Report an Issue
fakesshagent.git
Code
Commits
Branches
Tags
Suche
Strukturansicht:
cb7012c
Branches
Tags
documentation-tree
master
wishlist
0.1
fakesshagent.git
pyproject.toml
Initial import of code from derivepassphrase
Marco Ricci
commited
cb7012c
at 2026-08-31 14:53:33
pyproject.toml
Blame
History
Raw
[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "fakesshagent" description = "A non-hardened implementation of the SSH agent protocol, for use in testing." readme = "README.md" version = "0.1a1" requires-python = ">= 3.9" license = "Zlib" keywords = [] authors = [ { name = "Marco Ricci", email = "software@the13thletter.info" }, ] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Testing", "Typing :: Typed", ] dependencies = [ "derivepassphrase-sshagentsocketprovider >= 1.0", "typing_extensions", ] [project.optional-dependencies] dev = [ # dev - developers' setup # # Development uses the hatch build system, to isolate all tools in # their own virtual environment... "hatch >= 1.10", # ...but it is still sensible to have most static analysis tools # available in the main virtual environment as well, so that your # editor/IDE setup can access them as well. "mypy >= 1.0", "ruff >= 0.16.0", # Test dependencies should be installed as well, to have static # analysis in the test suite working too. # # `packaging` is needed because the test suite compares version # numbers. # # `pytest-xdist` is used by `hatch test -p`, but for the `psutil` # extra, the `psutil` package provides no wheels for PyPy. Users on # The Annoying OS are especially screwed if they lack the admin # priviledges necessary to install the developers' tools. So skip # the extra, and accept that for PyPy environments, `hatch test -p` # will not be able to distinguish logical and physical CPU core # counts. # # We use `hypothesis.is_hypothesis_test`, which was introduced in # 6.131.0, and `exc_type` for `pytest.importorskip`, which was # introduced in 8.2.0. "coverage[toml] >= 7.4", "coverage-enable-subprocess >= 1.0", "hypothesis >= 6.131.0", "packaging", "pytest >= 8.2", "pytest-randomly >= 3.15", "pytest-xdist >= 3.6.0", 'pytest-xdist[psutil] >= 3.6.0; platform_python_implementation != "PyPy"', # `pytest` 8.4 and higher, and `hypothesis` versions 6.130.13 # through 6.135.1, use syntax only properly available on Python 3.10 # and later: `with (x as y, a as b)`. However, those versions are # not marked as incompatible with Python 3.9. 'pytest < 8.4 ; python_version < "3.10"', 'hypothesis != 6.130.13, != 6.131.*, != 6.132.*, != 6.133.*, != 6.134.*, != 6.135.0, != 6.135.1 ; python_version < "3.10"', # `hypothesis` requires a Rust toolchain since version 6.156, and # publishes wheels for PyPy 3.11 only. PyO3 version 0.27 also dropped # support for PyPy 3.9 and 3.10, and cannot be overridden within # pyproject.toml. 'hypothesis < 6.156 ; platform_python_implementation == "PyPy" and python_version < "3.11"', ] [project.urls] Documentation = "https://the13thletter.info/fakesshagent/" Issues = "https://the13thletter.info/fakesshagent/latest/wishlist/" Source = "https://git.schokokeks.org/fakesshagent.git" [project.entry-points."derivepassphrase.ssh_agent_socket_providers"] stub_agent = "fakesshagent.machinery: STUB_AGENT_ENTRY_POINT" stub_agent_with_address = "fakesshagent.machinery: STUB_AGENT_WITH_ADDRESS_ENTRY_POINT" stub_agent_with_address_and_deterministic_dsa = "fakesshagent.machinery: STUB_AGENT_WITH_ADDRESS_AND_DETERMINISTIC_DSA_ENTRY_POINT" [tool.coverage.html] directory = "html/coverage" [tool.coverage.paths] src = ["src"] tests = ["tests"] [tool.coverage.report] skip_covered = false skip_empty = true precision = 3 partial_branches = [ 'pragma: no branch', ] exclude_also = [ "if __name__ == .__main__.:", 'if (?:typing\.)?TYPE_CHECKING:', "raise AssertionError", "raise NotImplementedError", 'assert False', '(?:typing\.)?assert_never\(', '@overload', 'class .*\(Protocol\):', 'pytest\.fail\(', '@(?:(?:pytest\.)?mark\.)?xfail\(', 'class _Omitted:', 'class _DummyModule:', ] # We use a bunch of "codes", similar to the "type: ignore" comments, as # shorthand notation for why we are excluding a certain piece of code # manually from coverage, instead of writing a verbose explanation at each # call site: # # "external-api" and "unused": The code is defined by an external API not # under our control, or it implements an external interface, and some of the # branches of that code we do not yet use ("unused") or don't ever intend to # use ("external-api"). In particular, in production and in testing use, we # do not expect to hit these code branches unless there are errors in our # code. # # "external": Whether or not we hit this code branch is non-deterministic, # and dependent on external factors that are difficult or impossible for us # to control, predict, or simulate. We therefore categorically exclude all # branches from coverage. (Typically though, one particular branch *will* # actually run. We just don't know ahead of time which one.) (While this # applies to "choice of operating system" and "installed Python/library # version" as well, these cases are usually tagged with more specific codes, # or explained in long-form commentary.) # # "failsafe": Akin to assertions, these are used to catch "impossible" # situations and to still fail in a controlled manner. We do not expect to # hit these code branches during production or testing. # # "debug", "internal" and "interactive": These code branches are not # intended to be called by the general public ("debug", "internal"), or they # are only intended to be called interactively ("interactive"). We do not # expect to hit these code branches during production or testing. [tool.coverage.run] source_pkgs = ["fakesshagent", "tests"] branch = true parallel = true omit = [ "__main__.py", ] dynamic_context = 'test_function' concurrency = ['thread', 'multiprocessing'] sigterm = true relative_files = true [tool.hatch.build.targets.sdist] exclude = [ 'docs/changelog.d/*.md', ] [tool.hatch.env] requires = [ "hatch-mkdocs", ] [tool.hatch.env.collectors.mkdocs.docs] path = "mkdocs.yml" [tool.hatch.envs.docs] extra-dependencies = [ # Our documentation uses formatted function signatures (i.e. with # formatted type annotations), which requires `black`. "black", # We actually use functionality from MkDocs 1.6, so ensure the # version is at least this high. "mkdocs >= 1.6", # Our changelog is assembled from singular entries, orchestrated by # `scriv`. "scriv >= 1.4", ] detached = false [tool.hatch.envs.hatch-check-code] config-path = "/dev/null" dependencies = [ # Override the default dependencies, lest the ruff requirements # conflict. ] features = [ "dev", ] [tool.hatch.envs.hatch-check-fmt] config-path = "/dev/null" dependencies = [ # Override the default dependencies, lest the ruff requirements # conflict. ] features = [ "dev", ] [tool.hatch.envs.hatch-check-types] config-path = "/dev/null" dependencies = [ # Override the default dependencies, lest the ruff requirements # conflict. "pyrefly >= 1.0.0", ] features = [ "dev", ] [tool.hatch.envs.hatch-test] default-args = ['src', 'tests'] dependencies = [ "coverage[toml] >= 7.4", "coverage-enable-subprocess >= 1.0", "hypothesis >= 6.131.0", "packaging", "pytest >= 8.2", "pytest-randomly >= 3.15", "pytest-xdist >= 3.6.0", 'pytest-xdist[psutil] >= 3.6.0; platform_python_implementation != "PyPy"', 'pytest < 8.4 ; python_version < "3.10"', 'hypothesis != 6.130.13, != 6.131.*, != 6.132.*, != 6.133.*, != 6.134.*, != 6.135.0, != 6.135.1 ; python_version < "3.10"', 'hypothesis < 6.156 ; platform_python_implementation == "PyPy" and python_version < "3.11"', ] matrix-name-format = '{variable}_{value}' [[tool.hatch.envs.hatch-test.matrix]] python = ["3.15", "3.14", "3.13", "3.12", "3.11", "3.10", "3.9", "pypy3.11", "pypy3.10", "pypy3.9"] parser-version = ["PEG"] [[tool.hatch.envs.hatch-test.matrix]] python = ["3.9", "pypy3.9"] parser-version = ["LL1"] [tool.hatch.envs.hatch-test.overrides] matrix.parser-version.env-vars = [ { key = "PYTHONOLDPARSER", value = "1", if = ["LL1"] }, ] [tool.hatch.envs.hatch-test.scripts] run = "pytest --hypothesis-profile={env:HYPOTHESIS_PROFILE:default}{env:HATCH_TEST_ARGS:} {args}" run-cov = "coverage run -m pytest --hypothesis-profile={env:HYPOTHESIS_PROFILE:default}{env:HATCH_TEST_ARGS:} {args}" cov-combine = "coverage combine" cov-report = "coverage report" [tool.hatch.envs.types] extra-dependencies = [ "mypy>=1.0.0", ] [tool.hatch.envs.types.scripts] check = "mypy --install-types --non-interactive {args:src/fakesshagent tests}" [tool.mypy] files = ['src/**/*.py', 'tests/**/*.py'] mypy_path = '$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/other-stubs' explicit_package_bases = true implicit_reexport = false sqlite_cache = true enable_error_code = ['ignore-without-code'] [tool.pyrefly] project-includes = [ "src/**/*.py", "tests/**/*.py", ] search-path = [ "src", ".", ] preset = "legacy" infer-return-types = "never" permissive-ignores = true [tool.pyrefly.errors] unnecessary-type-conversion = "ignore" [tool.pytest.ini_options] addopts = '--doctest-modules --dist=loadgroup --import-mode=importlib' pythonpath = [ 'tests', # needed for re-importing test machinery with multiprocessing (spawn) ] testpaths = [ 'src', # doctests in API documentation 'tests', # other tests ] xfail_strict = true [tool.ruff] line-length = 79 src = ["src"] [tool.ruff.format] docstring-code-format = true docstring-code-line-length = "dynamic" preview = true quote-style = "double" [tool.ruff.lint] ignore = [ # Suggested ignore by ruff when also using ruff to format. We *do* # check for E501, because this usually only happens when there is # a text string that should be manually broken. However, for # automated quality control, that specific check is turned off so # that the linting and formatting can proceed, and then *afterwards* # the files are re-linted. We hope that any *true* E501 errors left # over from this *are* text strings that should be manually broken. 'tab-indentation', 'indentation-with-invalid-multiple', 'indentation-with-invalid-multiple-comment', 'over-indented', 'docstring-tab-indentation', 'triple-single-quotes', 'bad-quotes-inline-string', 'bad-quotes-multiline-string', 'bad-quotes-docstring', 'avoidable-escaped-quote', 'missing-trailing-comma', 'prohibited-trailing-comma', 'single-line-implicit-string-concatenation', 'multi-line-implicit-string-concatenation', # We use `assert` regularly to appease the type checker, and because # it is the right language tool for this job. 'assert', # The formatter takes care of trailing commas and docstring code # automatically. 'missing-trailing-comma', 'doc-line-too-long', # We document transitive exceptions as well (if we feel they would # be surprising to the user otherwise). 'docstring-extraneous-exception', # We currently don't have issues for every TODO. Forcing an issue # also goes against the philosophy of TODOs as low-overhead markers # for future work; see # https://gist.github.com/dmnd/ed5d8ef8de2e4cfea174bd5dafcda382 . 'missing-todo-link', # We somewhat regularly use loops where each iteration needs # a separate try-except block. 'try-except-in-loop', # We do not currently use pathlib. The PTH rules are unselected, # but FURB includes several pathlib-related rules. 'read-whole-file', 'write-whole-file', # We catch type-ignore comments without specific code via the mypy # configuration, not via ruff. 'blanket-type-ignore', # Provisionally ignore the `__init__.py` rule, until we can adapt our # codebase. 'non-empty-init-module', # We prefer noqa comments over ruff-specific ignores, for tool # compatibility reasons, even if the comments themselves become harder # to read. Using them in the ruff config section is fine thought, # because that *is* ruff-specific. 'noqa-comments', # Still undecided about this one. 'too-many-statements-in-try-clause', ] preview = true # We select here in the order of presentation on the ruff documentation # website. ruff default selection (v0.6.2) is merely E4, E7, E9 and F. select = [ 'F', 'E', 'W', 'C90', 'I', 'N', 'D', 'UP', 'YTT', 'ANN', 'ASYNC', 'S', 'BLE', 'FBT', 'B', 'A', 'COM', 'CPY', 'C4', 'DTZ', 'T10', 'DJ', 'EM', 'EXE', 'FA', 'ISC', 'ICN', 'LOG', 'G', 'INP', 'PIE', 'T20', 'PYI', 'PT', 'Q', 'RET', 'SLF', 'SLOT', 'SIM', 'TID', 'TC', 'INT', 'ARG', 'PTH', 'TD', # We use TODOs and FIXMEs as notes for later, and don't want the # linter to nag about every occurrence. Disable 'FIX'. # # The "eradicate" rule is prone to a lot of false positives, and it # is unclear to me, and probably confusing to read, where to apply # a noqa marker. Instead, disable 'ERA', and if necessary, specify # it on the command-line. 'PD', 'PGH', 'PL', 'TRY', 'FLY', 'NPY', 'FAST', 'AIR', 'PERF', 'FURB', 'DOC', 'RUF', ] [tool.ruff.lint.per-file-ignores] "**/scripts/*" = [ # Suggested by hatch. 'INP', # Suggested by hatch. 'T20', ] "**/tests/**/*" = [ # Suggested by hatch, assumingly because it may be important to # verify that the value is exactly the empty string, and not just # any falsy value. 'compare-to-empty-string', # Suggested by hatch, assumingly because tests may use "magic # values". 'magic-value-comparison', # Suggested by hatch, because tests are typically organized as # classes and instance methods but may not really be using the # `self` argument. 'no-self-use', # Suggested by hatch, because these warnings may be precisely what # the tests are supposed to test. 'S', # Suggested by hatch, because pytest-style tests conventionally # import code from each other via relative imports. 'relative-imports', # Our tests regularly use arguments named `input` to store an input # (text-/byte-)string. 'builtin-argument-shadowing', # We regularly annotate pytest fixtures like monkeypatch as `Any`. 'any-type', # Our tests generally don't contain docstrings. 'D', 'DOC', # Our tests are regularly parametrized with booleans, for benign # purposes. 'FBT', # One of our standard modules is called `derivepassphrase._types`. # Importing this from the tests directory would then automatically # trigger `PLC2701`. 'import-private-name', # Too many public methods/arguments/returns/branches/locals doesn't # really apply here. 'too-many-public-methods', 'too-many-return-statements', 'too-many-branches', 'too-many-arguments', 'too-many-locals', 'too-many-statements', 'too-many-boolean-expressions', 'too-many-positional-arguments', # To fully test the `derivepassphrase.cli` module (and a couple # other things), we need to call and to mock several internal # functions, which would automatically trigger `SLF001`. 'private-member-access', # pytest does not support sensible introspection of # `assert all(...)` expressions in tests the same way it supports # introspection in `asssert all([...])`. So the extra list # comprehension actually improves debuggability in this case. 'unnecessary-comprehension-in-call', # The tests sometimes include long strings (in non-Python formats) # that should be included verbatim, without artificial line # breaking, so they can be grepped for. 'line-too-long', ] [tool.ruff.lint.flake8-copyright] # Include hatch-enforced SPDX-FileCopyrightText in check. notice-rgx = '(?i)(?:Copyright\s+((?:\(C\)|©)\s+)?|SPDX-FileCopyrightText:\s+)\d{4}((-|,\s)\d{4})*' [tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false mark-parentheses = false parametrize-names-type = 'list' [tool.ruff.lint.flake8-tidy-imports] ban-relative-imports = "all" [tool.ruff.lint.isort] known-first-party = [ "derivepassphrase_sshagentsocketprovider", "fakesshagent", ] [tool.ruff.lint.pycodestyle] ignore-overlong-task-comments = true # for E501 max-doc-length = 72 # for W505 [tool.ruff.lint.pydocstyle] convention = 'google' [tool.scriv] version = "literal: pyproject.toml: project.version" format = "md" fragment_directory = "docs/changelog.d" output_file = "docs/changelog.md" insert_marker = "<!-- scriv changelog start -->" end_marker = "<!-- scriv changelog end -->" md_header_level = "2" entry_title_template = "{% if version %}{{ version }} ({% endif %}{{ date.strftime('%Y-%m-%d') }}{% if version %}){% endif %}"