userdir-publish 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. userdir_publish-0.0.1/.cspell.json +50 -0
  2. userdir_publish-0.0.1/.editorconfig +17 -0
  3. userdir_publish-0.0.1/.envrc +2 -0
  4. userdir_publish-0.0.1/.github/dependabot.yml +19 -0
  5. userdir_publish-0.0.1/.github/release-drafter.yml +39 -0
  6. userdir_publish-0.0.1/.github/workflows/cd.yml +33 -0
  7. userdir_publish-0.0.1/.github/workflows/ci.yml +38 -0
  8. userdir_publish-0.0.1/.github/workflows/clean-caches.yml +22 -0
  9. userdir_publish-0.0.1/.github/workflows/lock.yml +21 -0
  10. userdir_publish-0.0.1/.github/workflows/pr-linting.yml +14 -0
  11. userdir_publish-0.0.1/.github/workflows/release-drafter.yml +16 -0
  12. userdir_publish-0.0.1/.gitignore +25 -0
  13. userdir_publish-0.0.1/.pre-commit-config.yaml +98 -0
  14. userdir_publish-0.0.1/.pre-commit-hooks/update_schema.py +147 -0
  15. userdir_publish-0.0.1/.prettierignore +1 -0
  16. userdir_publish-0.0.1/.prettierrc.yml +4 -0
  17. userdir_publish-0.0.1/.python-version +1 -0
  18. userdir_publish-0.0.1/.vscode/extensions.json +33 -0
  19. userdir_publish-0.0.1/.vscode/settings.json +45 -0
  20. userdir_publish-0.0.1/LICENSE +21 -0
  21. userdir_publish-0.0.1/PKG-INFO +61 -0
  22. userdir_publish-0.0.1/README.md +31 -0
  23. userdir_publish-0.0.1/codecov.yml +8 -0
  24. userdir_publish-0.0.1/docs/.gitignore +1 -0
  25. userdir_publish-0.0.1/docs/_static/favicon.svg +5 -0
  26. userdir_publish-0.0.1/docs/_templates/view-on-github.html +12 -0
  27. userdir_publish-0.0.1/docs/conf.py +86 -0
  28. userdir_publish-0.0.1/docs/index.md +172 -0
  29. userdir_publish-0.0.1/pyproject.toml +405 -0
  30. userdir_publish-0.0.1/setup.cfg +4 -0
  31. userdir_publish-0.0.1/src/userdir_publish/__init__.py +1 -0
  32. userdir_publish-0.0.1/src/userdir_publish/cli.py +118 -0
  33. userdir_publish-0.0.1/src/userdir_publish/config.py +299 -0
  34. userdir_publish-0.0.1/src/userdir_publish/publish.py +235 -0
  35. userdir_publish-0.0.1/src/userdir_publish/py.typed +0 -0
  36. userdir_publish-0.0.1/src/userdir_publish/version.py +24 -0
  37. userdir_publish-0.0.1/src/userdir_publish.egg-info/PKG-INFO +61 -0
  38. userdir_publish-0.0.1/src/userdir_publish.egg-info/SOURCES.txt +47 -0
  39. userdir_publish-0.0.1/src/userdir_publish.egg-info/dependency_links.txt +1 -0
  40. userdir_publish-0.0.1/src/userdir_publish.egg-info/entry_points.txt +2 -0
  41. userdir_publish-0.0.1/src/userdir_publish.egg-info/requires.txt +2 -0
  42. userdir_publish-0.0.1/src/userdir_publish.egg-info/scm_file_list.json +42 -0
  43. userdir_publish-0.0.1/src/userdir_publish.egg-info/scm_version.json +8 -0
  44. userdir_publish-0.0.1/src/userdir_publish.egg-info/top_level.txt +1 -0
  45. userdir_publish-0.0.1/tests/conftest.py +39 -0
  46. userdir_publish-0.0.1/tests/test_cli.py +123 -0
  47. userdir_publish-0.0.1/tests/test_config.py +342 -0
  48. userdir_publish-0.0.1/tests/test_publish.py +348 -0
  49. userdir_publish-0.0.1/userdir-publish.schema.json +67 -0
@@ -0,0 +1,50 @@
1
+ {
2
+ "enableFiletypes": [
3
+ "git-commit",
4
+ "github-actions-workflow",
5
+ "julia",
6
+ "jupyter"
7
+ ],
8
+ "flagWords": [
9
+ "analyse",
10
+ "colour",
11
+ "comparision",
12
+ "favour",
13
+ "flavour",
14
+ "hte",
15
+ "optimise",
16
+ "paramater",
17
+ "parmater",
18
+ "transision",
19
+ "transisions"
20
+ ],
21
+ "ignorePaths": [
22
+ "**/.cspell.json",
23
+ "*.svg",
24
+ ".editorconfig",
25
+ ".envrc",
26
+ ".github/dependabot.yml",
27
+ ".gitignore",
28
+ ".pre-commit-config.yaml",
29
+ ".prettierignore",
30
+ ".vscode/*",
31
+ "codecov.yml",
32
+ "docs/_templates/*",
33
+ "docs/conf.py",
34
+ "pyproject.toml"
35
+ ],
36
+ "ignoreWords": ["prereleased", "setgid", "toctree", "tombi", "typer", "ugoa"],
37
+ "language": "en-US",
38
+ "useGitignore": true,
39
+ "version": "0.2",
40
+ "words": [
41
+ "docstrings",
42
+ "jdoe",
43
+ "openrsync",
44
+ "PyPA",
45
+ "PyPI",
46
+ "pyproject",
47
+ "usefixtures",
48
+ "userdir"
49
+ ]
50
+ }
@@ -0,0 +1,17 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ indent_size = 2
6
+ indent_style = space
7
+ insert_final_newline = true
8
+ trim_trailing_whitespace = true
9
+
10
+ [*.{py,toml}]
11
+ indent_size = 4
12
+
13
+ [LICENSE]
14
+ indent_size = unset
15
+
16
+ [uv.lock]
17
+ indent_size = 4
@@ -0,0 +1,2 @@
1
+ uv sync --all-extras --quiet
2
+ source .venv/bin/activate
@@ -0,0 +1,19 @@
1
+ version: 2
2
+
3
+ multi-ecosystem-groups:
4
+ lock:
5
+ assignees: [redeboer]
6
+ commit-message: { prefix: MAINT }
7
+ schedule: { interval: quarterly }
8
+
9
+ updates:
10
+ - package-ecosystem: github-actions
11
+ directory: "/"
12
+ labels: [⬆️ Lock]
13
+ multi-ecosystem-group: lock
14
+ patterns: ["*"]
15
+ - package-ecosystem: pre-commit
16
+ directory: "/"
17
+ labels: [⬆️ Lock]
18
+ multi-ecosystem-group: lock
19
+ patterns: ["*"]
@@ -0,0 +1,39 @@
1
+ name-template: userdir-publish $NEXT_PATCH_VERSION
2
+ tag-template: $NEXT_PATCH_VERSION
3
+
4
+ references:
5
+ - main
6
+ - epic/*
7
+
8
+ categories:
9
+ - title: ✨ New features
10
+ label: ✨ Feature
11
+ - title: ⚠️ Enhancements and optimizations
12
+ label: ⚙️ Enhancement
13
+ - title: ⚠️ API changes
14
+ label: ⚠️ Interface
15
+ - title: ⚠️ Changes that may affect behavior
16
+ label: ❗ Behavior
17
+ - title: 🐛 Bug fixes
18
+ label: 🐛 Bug
19
+ - title: 📝 Documentation
20
+ label: 📝 Docs
21
+ - title: 🔨 Maintenance
22
+ labels:
23
+ - 🔨 Maintenance
24
+ - ⬆️ Lock
25
+ - title: 🖱️ Developer Experience
26
+ label: 🖱️ DX
27
+
28
+ change-template: "- $TITLE (#$NUMBER)"
29
+
30
+ replacers:
31
+ - search: /([A-Z]+!?:\s*)(.*)/g
32
+ replace: $2
33
+
34
+ sort-direction: ascending
35
+
36
+ template: |
37
+ $CHANGES
38
+
39
+ _The full changelog as commits can be found [here](https://github.com/RUB-EP1/userdir-publish/compare/$PREVIOUS_TAG...$NEXT_PATCH_VERSION)._
@@ -0,0 +1,33 @@
1
+ name: CD
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - prereleased
7
+ - released
8
+
9
+ jobs:
10
+ milestone:
11
+ if: startsWith(github.ref, 'refs/tags')
12
+ uses: ComPWA/actions/.github/workflows/close-milestone.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
13
+ package-name:
14
+ uses: ComPWA/actions/.github/workflows/get-pypi-name.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
15
+ pypi:
16
+ environment:
17
+ name: PyPI
18
+ url: https://pypi.org/p/${{ needs.package-name.outputs.name }}
19
+ if: startsWith(github.ref, 'refs/tags')
20
+ name: Publish to PyPI
21
+ needs:
22
+ - package-name
23
+ permissions:
24
+ id-token: write
25
+ runs-on: ubuntu-24.04
26
+ steps:
27
+ - uses: ComPWA/actions/build-pypi-distribution@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
28
+ - uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
29
+ push:
30
+ if: startsWith(github.ref, 'refs/tags') && !github.event.release.prerelease
31
+ permissions:
32
+ contents: write
33
+ uses: ComPWA/actions/.github/workflows/push-to-version-branches.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ concurrency:
4
+ group: ${{ github.workflow }}-${{ github.ref }}
5
+ cancel-in-progress: |-
6
+ ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }}
7
+
8
+ on:
9
+ push:
10
+ branches:
11
+ - main
12
+ - epic/*
13
+ - "[0-9]+.[0-9]+.x"
14
+ pull_request:
15
+ branches:
16
+ - main
17
+ - epic/*
18
+ - "[0-9]+.[0-9]+.x"
19
+ workflow_dispatch:
20
+
21
+ jobs:
22
+ doc:
23
+ uses: ComPWA/actions/.github/workflows/ci-docs.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
24
+ permissions:
25
+ pages: write
26
+ id-token: write
27
+ with:
28
+ gh-pages: true
29
+ style:
30
+ secrets:
31
+ token: ${{ secrets.PAT }}
32
+ uses: ComPWA/actions/.github/workflows/style.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
33
+ test:
34
+ uses: ComPWA/actions/.github/workflows/test.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
35
+ with:
36
+ coverage-python-version: "3.14"
37
+ macos-python-version: "3.11"
38
+ multithreaded: false
@@ -0,0 +1,22 @@
1
+ name: Clean caches
2
+
3
+ on:
4
+ pull_request:
5
+ types:
6
+ - closed
7
+ workflow_dispatch:
8
+ inputs:
9
+ ref:
10
+ description: Clean caches for this branch name or ref
11
+ required: false
12
+ type: string
13
+
14
+ jobs:
15
+ cleanup:
16
+ name: Remove caches
17
+ runs-on: ubuntu-slim
18
+ steps:
19
+ - uses: ComPWA/actions/clean-caches@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
20
+ with:
21
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22
+ ref: ${{ inputs.ref }}
@@ -0,0 +1,21 @@
1
+ name: Update
2
+
3
+ concurrency:
4
+ group: ${{ github.workflow }}-${{ github.ref }}
5
+ cancel-in-progress: |-
6
+ ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }}
7
+
8
+ on:
9
+ pull_request:
10
+ branches:
11
+ - main
12
+ - epic/*
13
+ paths:
14
+ - .pre-commit-config.yaml
15
+ workflow_dispatch:
16
+
17
+ jobs:
18
+ lock:
19
+ uses: ComPWA/actions/.github/workflows/lock.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
20
+ secrets:
21
+ token: ${{ secrets.PAT }}
@@ -0,0 +1,14 @@
1
+ name: PR linting
2
+ on:
3
+ pull_request:
4
+ types:
5
+ - edited
6
+ - labeled
7
+ - opened
8
+ - reopened
9
+ - synchronize
10
+ - unlabeled
11
+
12
+ jobs:
13
+ lint-pr:
14
+ uses: ComPWA/actions/.github/workflows/pr-linting.yml@826112415aa683bb2d73df87e84444a047f8cad7 # v4.1.8
@@ -0,0 +1,16 @@
1
+ name: Release Drafter
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - epic/*
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ update_release_draft:
12
+ runs-on: ubuntu-slim
13
+ steps:
14
+ - uses: release-drafter/release-drafter@978bb0b30c5ee8cdd332ced253758157150d43f0 # v7.10.0
15
+ env:
16
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,25 @@
1
+ __pycache__/
2
+ .agents/
3
+ .claude/
4
+ .codex/
5
+ .coverage
6
+ .coverage.*
7
+ .eggs/
8
+ .fuse_*
9
+ .idea/
10
+ .lycheecache
11
+ .pytest_cache/
12
+ *.egg-info/
13
+ *.pyc
14
+ **.code-workspace
15
+ *build/
16
+ *venv/
17
+ AGENTS.md
18
+ CLAUDE.md
19
+ coverage.xml
20
+ dist/
21
+ htmlcov/
22
+ prof/
23
+ pyvenv*/
24
+ uv.lock
25
+ version.py
@@ -0,0 +1,98 @@
1
+ ci:
2
+ autofix_commit_msg: "MAINT: implement pre-commit autofixes"
3
+ autoupdate_commit_msg: "MAINT: upgrade lock files"
4
+ autoupdate_schedule: quarterly
5
+ skip:
6
+ - schema
7
+ - tombi-format
8
+ - tombi-lint
9
+ - ty
10
+
11
+ repos:
12
+ - repo: meta
13
+ hooks:
14
+ - id: check-hooks-apply
15
+ - id: check-useless-excludes
16
+
17
+ - repo: https://github.com/ComPWA/policy
18
+ rev: 0.10.3
19
+ hooks:
20
+ - id: check-dev-files
21
+
22
+ - repo: https://github.com/astral-sh/ruff-pre-commit
23
+ rev: v0.17.3
24
+ hooks:
25
+ - id: ruff-check
26
+ args: [--fix]
27
+ - id: ruff-format
28
+
29
+ - repo: https://github.com/pre-commit/pre-commit-hooks
30
+ rev: v6.0.0
31
+ hooks:
32
+ - id: check-ast
33
+ - id: check-case-conflict
34
+ - id: check-json
35
+ - id: check-merge-conflict
36
+ - id: check-toml
37
+ - id: check-vcs-permalinks
38
+ - id: check-yaml
39
+ - id: debug-statements
40
+ - id: end-of-file-fixer
41
+ - id: mixed-line-ending
42
+ - id: name-tests-test
43
+ name: Tests should start with test_
44
+ args: ["--django"]
45
+ - id: trailing-whitespace
46
+
47
+ - repo: https://github.com/tombi-toml/tombi-pre-commit
48
+ rev: v1.10.0
49
+ hooks:
50
+ - id: tombi-format
51
+ - id: tombi-lint
52
+ args: [--error-on-warnings]
53
+
54
+ - repo: https://github.com/ComPWA/prettier-pre-commit
55
+ rev: v3.9.10
56
+ hooks:
57
+ - id: prettier
58
+
59
+ - repo: https://github.com/streetsidesoftware/cspell-cli
60
+ rev: v10.4.0
61
+ hooks:
62
+ - id: cspell
63
+
64
+ - repo: https://github.com/LilSpazJoekp/docstrfmt
65
+ rev: v2.2.1
66
+ hooks:
67
+ - id: docstrfmt
68
+
69
+ - repo: https://github.com/editorconfig-checker/editorconfig-checker.python
70
+ rev: 3.11.1
71
+ hooks:
72
+ - id: editorconfig-checker
73
+ name: editorconfig
74
+ alias: ec
75
+ exclude: >-
76
+ (?x)^(
77
+ .*\.py
78
+ )$
79
+
80
+ - repo: local
81
+ hooks:
82
+ - id: schema
83
+ name: Generate JSON schema for the configuration
84
+ entry: uv run --no-default-groups python .pre-commit-hooks/update_schema.py
85
+ language: unsupported
86
+ files: >-
87
+ (?x)^(
88
+ \.pre-commit-hooks/update_schema\.py|
89
+ src/userdir_publish/config\.py|
90
+ userdir-publish\.schema\.json
91
+ )$
92
+ pass_filenames: false
93
+
94
+ - repo: https://github.com/astral-sh/ty-pre-commit
95
+ rev: v0.0.97
96
+ hooks:
97
+ - id: ty
98
+ args: [--group=types, --no-default-groups]
@@ -0,0 +1,147 @@
1
+ """Generate the JSON Schema for the ``[tool.userdir-publish]`` TOML table.
2
+
3
+ Run this script to update the committed schema file. It only rewrites the file when its
4
+ content changes, so that Prettier can own the formatting.
5
+ """
6
+
7
+ import ast
8
+ import inspect
9
+ import itertools
10
+ import json
11
+ import textwrap
12
+ from dataclasses import MISSING, fields
13
+ from pathlib import Path
14
+ from typing import Any, get_args, get_origin, get_type_hints
15
+
16
+ from userdir_publish.config import TOOL_NAME, Settings
17
+
18
+ SCHEMA_PATH = Path(f"{TOOL_NAME}.schema.json")
19
+
20
+
21
+ def main() -> int:
22
+ """Write the schema if it is outdated and return 1, so that the hook fails."""
23
+ if schema_is_current():
24
+ return 0
25
+ SCHEMA_PATH.write_text(render_schema())
26
+ return 1
27
+
28
+
29
+ def schema_is_current() -> bool:
30
+ """Check whether the committed schema is semantically up to date.
31
+
32
+ >>> schema_is_current()
33
+ True
34
+ """
35
+ try:
36
+ committed = json.loads(SCHEMA_PATH.read_text())
37
+ except (FileNotFoundError, json.JSONDecodeError):
38
+ return False
39
+ return committed == create_schema()
40
+
41
+
42
+ def create_schema() -> dict[str, Any]:
43
+ r"""Project the `.Settings` dataclass onto ``[tool.userdir-publish]``.
44
+
45
+ The defaults and examples in the schema form a valid configuration:
46
+
47
+ >>> import tempfile
48
+ >>> from userdir_publish.config import load_settings
49
+ >>> lines = [f"[tool.{TOOL_NAME}]"]
50
+ >>> for key, field_schema in create_schema()["properties"].items():
51
+ ... value = field_schema.get("default", field_schema.get("examples", [None])[0])
52
+ ... if isinstance(value, str):
53
+ ... lines.append(f'{key} = "{value}"')
54
+ >>> with tempfile.TemporaryDirectory() as tmp:
55
+ ... root = Path(tmp)
56
+ ... _ = (root / "pyproject.toml").write_text("\n".join(lines))
57
+ ... settings = load_settings(project_root=root, user_config=root / "none")
58
+ >>> settings.host
59
+ 'web.example.edu'
60
+ """
61
+ descriptions = _get_attribute_docstrings(Settings)
62
+ type_hints = get_type_hints(Settings)
63
+ properties: dict[str, Any] = {}
64
+ for settings_field in fields(Settings):
65
+ if settings_field.name.startswith("_"):
66
+ continue
67
+ field_schema = {
68
+ "description": descriptions[settings_field.name],
69
+ **_to_json_type(
70
+ annotation=type_hints[settings_field.name],
71
+ pattern=settings_field.metadata.get("pattern"),
72
+ ),
73
+ }
74
+ if settings_field.default not in {MISSING, None}:
75
+ default = settings_field.default
76
+ field_schema["default"] = (
77
+ list(default) if isinstance(default, tuple) else default
78
+ )
79
+ if "examples" in settings_field.metadata:
80
+ field_schema["examples"] = settings_field.metadata["examples"]
81
+ properties[settings_field.name.replace("_", "-")] = field_schema
82
+ return {
83
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
84
+ "title": f"{TOOL_NAME} configuration",
85
+ "description": f"Configuration for the tool.{TOOL_NAME} TOML table.",
86
+ "type": "object",
87
+ "x-tombi-table-keys-order": "ascending",
88
+ "properties": dict(sorted(properties.items())),
89
+ "additionalProperties": False,
90
+ }
91
+
92
+
93
+ def render_schema() -> str:
94
+ """Render the generated schema in its committed representation."""
95
+ return json.dumps(create_schema(), indent=2) + "\n"
96
+
97
+
98
+ def _to_json_type(annotation: Any, pattern: str | None = None) -> dict[str, Any]:
99
+ """Convert a type annotation of a `.Settings` field to a JSON Schema type.
100
+
101
+ A *pattern* constrains the plain strings that the annotation accepts.
102
+
103
+ >>> _to_json_type(str | None)
104
+ {'type': 'string'}
105
+ >>> _to_json_type(tuple[str, ...])
106
+ {'type': 'array', 'items': {'type': 'string'}}
107
+ >>> from typing import Literal
108
+ >>> _to_json_type(Literal["a", "b"] | str, pattern="^c+$")
109
+ {'anyOf': [{'enum': ['a', 'b']}, {'type': 'string', 'pattern': '^c+$'}]}
110
+ """
111
+ args = [arg for arg in get_args(annotation) if arg is not type(None)]
112
+ origin = get_origin(annotation)
113
+ if annotation is str:
114
+ if pattern is None:
115
+ return {"type": "string"}
116
+ return {"type": "string", "pattern": pattern}
117
+ if origin is tuple:
118
+ return {"type": "array", "items": _to_json_type(args[0])}
119
+ if repr(origin) == "typing.Literal":
120
+ return {"enum": list(args)}
121
+ if len(args) == 1:
122
+ return _to_json_type(args[0], pattern)
123
+ if len(args) > 1:
124
+ return {"anyOf": [_to_json_type(arg, pattern) for arg in args]}
125
+ msg = f"Cannot convert {annotation} to a JSON Schema type"
126
+ raise NotImplementedError(msg)
127
+
128
+
129
+ def _get_attribute_docstrings(cls: type) -> dict[str, str]:
130
+ """Collect the docstrings that follow the attribute definitions of a class."""
131
+ module = ast.parse(textwrap.dedent(inspect.getsource(cls)))
132
+ body = module.body[0].body # ty: ignore[unresolved-attribute]
133
+ docstrings: dict[str, str] = {}
134
+ for node, next_node in itertools.pairwise(body):
135
+ if (
136
+ isinstance(node, ast.AnnAssign)
137
+ and isinstance(node.target, ast.Name)
138
+ and isinstance(next_node, ast.Expr)
139
+ and isinstance(next_node.value, ast.Constant)
140
+ and isinstance(next_node.value.value, str)
141
+ ):
142
+ docstrings[node.target.id] = inspect.cleandoc(next_node.value.value)
143
+ return docstrings
144
+
145
+
146
+ if __name__ == "__main__":
147
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ LICENSE
@@ -0,0 +1,4 @@
1
+ overrides:
2
+ - files: ["*.schema.json"]
3
+ options:
4
+ objectWrap: collapse
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,33 @@
1
+ {
2
+ "recommendations": [
3
+ "astral-sh.ty",
4
+ "charliermarsh.ruff",
5
+ "eamodio.gitlens",
6
+ "esbenp.prettier-vscode",
7
+ "executablebookproject.myst-highlight",
8
+ "github.vscode-github-actions",
9
+ "github.vscode-pull-request-github",
10
+ "mhutchie.git-graph",
11
+ "ms-python.python",
12
+ "ms-vscode.live-server",
13
+ "redhat.vscode-yaml",
14
+ "soulcode.vscode-unwanted-extensions",
15
+ "stkb.rewrap",
16
+ "streetsidesoftware.code-spell-checker",
17
+ "tombi-toml.tombi"
18
+ ],
19
+ "unwantedRecommendations": [
20
+ "davidanson.vscode-markdownlint",
21
+ "garaioag.garaio-vscode-unwanted-recommendations",
22
+ "ms-python.black-formatter",
23
+ "ms-python.flake8",
24
+ "ms-python.isort",
25
+ "ms-python.mypy-type-checker",
26
+ "ms-python.pylint",
27
+ "ms-python.vscode-pylance",
28
+ "ryanluker.vscode-coverage-gutters",
29
+ "tamasfe.even-better-toml",
30
+ "travisillig.vscode-json-stable-stringify",
31
+ "tyriar.sort-lines"
32
+ ]
33
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "[css][html][json][jsonc][markdown][yaml]": {
3
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
4
+ },
5
+ "[git-commit]": {
6
+ "editor.rulers": [72],
7
+ "rewrap.wrappingColumn": 72
8
+ },
9
+ "[json]": {
10
+ "editor.wordWrap": "on"
11
+ },
12
+ "[python]": {
13
+ "editor.codeActionsOnSave": {
14
+ "source.organizeImports": "explicit"
15
+ },
16
+ "editor.defaultFormatter": "charliermarsh.ruff"
17
+ },
18
+ "[toml]": {
19
+ "editor.defaultFormatter": "tombi-toml.tombi"
20
+ },
21
+ "diffEditor.experimental.showMoves": true,
22
+ "editor.formatOnSave": true,
23
+ "github-actions.workflows.pinned.workflows": [".github/workflows/ci.yml"],
24
+ "gitlens.telemetry.enabled": false,
25
+ "livePreview.defaultPreviewPath": "docs/_build/html",
26
+ "notebook.codeActionsOnSave": {
27
+ "notebook.source.organizeImports": "explicit"
28
+ },
29
+ "notebook.formatOnSave.enabled": true,
30
+ "python.defaultInterpreterPath": ".venv/bin/python",
31
+ "python.terminal.activateEnvironment": false,
32
+ "python.testing.pytestEnabled": true,
33
+ "python.testing.unittestEnabled": false,
34
+ "redhat.telemetry.enabled": false,
35
+ "rewrap.wrappingColumn": 88,
36
+ "ruff.enable": true,
37
+ "ruff.importStrategy": "fromEnvironment",
38
+ "ruff.organizeImports": true,
39
+ "telemetry.telemetryLevel": "off",
40
+ "testing.coverageToolbarEnabled": true,
41
+ "testing.showCoverageInExplorer": true,
42
+ "ty.completions.autoImport": false,
43
+ "ty.diagnosticMode": "workspace",
44
+ "ty.importStrategy": "fromEnvironment"
45
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RUB-EP1
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.