ledgered 0.7.2.dev4__tar.gz → 0.7.2.dev8__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 (55) hide show
  1. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/.github/workflows/build_and_tests.yml +1 -1
  2. ledgered-0.7.2.dev8/.github/workflows/fast-checks.yml +41 -0
  3. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/.gitignore +0 -1
  4. ledgered-0.7.2.dev8/.pre-commit-config.yaml +28 -0
  5. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/CHANGELOG.md +2 -1
  6. {ledgered-0.7.2.dev4/src/ledgered.egg-info → ledgered-0.7.2.dev8}/PKG-INFO +3 -2
  7. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/pyproject.toml +4 -10
  8. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/__version__.py +2 -2
  9. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/binary.py +10 -11
  10. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/github.py +15 -14
  11. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/cli.py +89 -72
  12. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/manifest.py +11 -7
  13. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/tests.py +9 -6
  14. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/use_cases.py +4 -2
  15. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/utils.py +1 -1
  16. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/serializers.py +1 -5
  17. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8/src/ledgered.egg-info}/PKG-INFO +3 -2
  18. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered.egg-info/SOURCES.txt +1 -0
  19. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/_data/minimal.toml +1 -1
  20. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/functional/conftest.py +7 -3
  21. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/functional/manifest/test_cli.py +22 -26
  22. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/functional/test_github.py +4 -3
  23. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/manifest/test_app.py +0 -1
  24. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/manifest/test_manifest.py +2 -2
  25. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/manifest/test_tests.py +44 -17
  26. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/manifest/test_use_cases.py +1 -4
  27. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/test_binary.py +8 -9
  28. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/test_github.py +1 -4
  29. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/test_serializers.py +15 -15
  30. ledgered-0.7.2.dev4/.github/workflows/fast-checks.yml +0 -64
  31. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/.github/workflows/codeql-analysis.yml +0 -0
  32. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/LICENSE +0 -0
  33. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/README.md +0 -0
  34. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/doc/binary.md +0 -0
  35. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/doc/manifest.md +0 -0
  36. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/setup.cfg +0 -0
  37. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/__init__.py +0 -0
  38. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/__init__.py +0 -0
  39. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/app.py +0 -0
  40. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/constants.py +0 -0
  41. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/manifest/errors.py +0 -0
  42. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered/utils/__init__.py +0 -0
  43. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered.egg-info/dependency_links.txt +0 -0
  44. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered.egg-info/entry_points.txt +0 -0
  45. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered.egg-info/requires.txt +0 -0
  46. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/src/ledgered.egg-info/top_level.txt +0 -0
  47. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/_data/Cargo.toml +0 -0
  48. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/_data/Makefile +0 -0
  49. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/_data/full_correct.toml +0 -0
  50. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/_data/ledger_app.toml +0 -0
  51. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/_data/one_leaf.toml +0 -0
  52. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/functional/__init__.py +0 -0
  53. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/functional/manifest/__init__.py +0 -0
  54. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/__init__.py +0 -0
  55. {ledgered-0.7.2.dev4 → ledgered-0.7.2.dev8}/tests/unit/manifest/__init__.py +0 -0
@@ -25,7 +25,7 @@ jobs:
25
25
  strategy:
26
26
  fail-fast: false
27
27
  matrix:
28
- python_version: ['3.10', '3.11', '3.12', '3.13']
28
+ python_version: ['3.9', '3.10', '3.11', '3.12', '3.13']
29
29
  steps:
30
30
  - name: Clone
31
31
  uses: actions/checkout@v4
@@ -0,0 +1,41 @@
1
+ name: Fast checks
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - develop
8
+ - master
9
+ pull_request:
10
+
11
+ jobs:
12
+ ruff:
13
+ name: Checks & format
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Ruff - lint check
18
+ uses: astral-sh/ruff-action@v3
19
+ - name: Ruff - format check
20
+ run: ruff format --check
21
+
22
+ mypy:
23
+ name: Type checking
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - run: pip install mypy types-toml
28
+ - name: Mypy type checking
29
+ run: mypy src
30
+
31
+ misspell:
32
+ name: Check misspellings
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - name: Check misspellings
37
+ uses: codespell-project/actions-codespell@v1
38
+ with:
39
+ builtin: clear,rare
40
+ check_filenames: true
41
+ ignore_words_list: assertIn,crate,
@@ -6,4 +6,3 @@ coverage.xml
6
6
  build/
7
7
  dist/
8
8
  __version__.py
9
-
@@ -0,0 +1,28 @@
1
+ # To install hooks, run:
2
+ # pre-commit install --hook-type pre-commit
3
+ # pre-commit install --hook-type commit-msg
4
+
5
+ repos:
6
+ - repo: https://github.com/pre-commit/pre-commit-hooks
7
+ rev: v5.0.0
8
+ hooks:
9
+ - id: trailing-whitespace
10
+ - id: end-of-file-fixer
11
+ - id: check-yaml
12
+ - id: check-toml
13
+ - id: check-added-large-files
14
+
15
+ - repo: https://github.com/astral-sh/ruff-pre-commit
16
+ rev: v0.9.3
17
+ hooks:
18
+ - id: ruff-format
19
+ args: ["--check"]
20
+ - id: ruff
21
+
22
+ - repo: https://github.com/pre-commit/mirrors-mypy
23
+ rev: v1.14.1
24
+ hooks:
25
+ - id: mypy
26
+ additional_dependencies:
27
+ - types-toml
28
+ - types-requests
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+
8
9
  ## [0.8.0] - 2025-??-??
9
10
 
10
11
  ### Added
@@ -14,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
15
 
15
16
  ### Changed
16
17
 
17
- - Package tested & published on Python3.12 and 3.13. Python 3.8 and 3.9 support is dropped.
18
+ - Package tested & published on Python3.12 and 3.13. Python 3.8 support is dropped.
18
19
 
19
20
 
20
21
  ## [0.7.1] - 2024-04-30
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ledgered
3
- Version: 0.7.2.dev4
3
+ Version: 0.7.2.dev8
4
4
  Summary: Python tools, utils, libraries, to be used with Ledger cryptodevices
5
5
  Author-email: Ledger <hello@ledger.fr>
6
6
  License: MIT License
@@ -28,6 +28,7 @@ License: MIT License
28
28
  Project-URL: Home, https://github.com/LedgerHQ/ledgered
29
29
  Classifier: License :: OSI Approved :: MIT License
30
30
  Classifier: Programming Language :: Python :: 3
31
+ Classifier: Programming Language :: Python :: 3.9
31
32
  Classifier: Programming Language :: Python :: 3.10
32
33
  Classifier: Programming Language :: Python :: 3.11
33
34
  Classifier: Programming Language :: Python :: 3.12
@@ -36,7 +37,7 @@ Classifier: Operating System :: POSIX :: Linux
36
37
  Classifier: Operating System :: Microsoft :: Windows
37
38
  Classifier: Operating System :: MacOS :: MacOS X
38
39
  Classifier: Typing :: Typed
39
- Requires-Python: >=3.10
40
+ Requires-Python: >=3.9
40
41
  Description-Content-Type: text/markdown
41
42
  License-File: LICENSE
42
43
  Requires-Dist: toml
@@ -17,6 +17,7 @@ license = { file = "LICENSE" }
17
17
  classifiers = [
18
18
  "License :: OSI Approved :: MIT License",
19
19
  "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
20
21
  "Programming Language :: Python :: 3.10",
21
22
  "Programming Language :: Python :: 3.11",
22
23
  "Programming Language :: Python :: 3.12",
@@ -27,7 +28,7 @@ classifiers = [
27
28
  "Typing :: Typed",
28
29
  ]
29
30
  dynamic = [ "version" ]
30
- requires-python = ">=3.10"
31
+ requires-python = ">=3.9"
31
32
  dependencies = [
32
33
  "toml",
33
34
  "pyelftools",
@@ -54,10 +55,6 @@ local_scheme = "no-local-version"
54
55
  [tool.mypy]
55
56
  ignore_missing_imports = true
56
57
 
57
- [tool.yapf]
58
- based_on_style = "pep8"
59
- column_limit = 100
60
-
61
58
  [tool.coverage.report]
62
59
  show_missing = true
63
60
  exclude_lines = [
@@ -65,8 +62,5 @@ exclude_lines = [
65
62
  "pragma: no cover"
66
63
  ]
67
64
 
68
- [tool.bandit]
69
- skips = ["B101"]
70
-
71
- [tool.flake8]
72
- max-line-length = 100
65
+ [tool.ruff]
66
+ line-length = 100
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.7.2.dev4'
16
- __version_tuple__ = version_tuple = (0, 7, 2, 'dev4')
15
+ __version__ = version = '0.7.2.dev8'
16
+ __version_tuple__ = version_tuple = (0, 7, 2, 'dev8')
@@ -32,7 +32,6 @@ class Sections(Jsonable):
32
32
 
33
33
 
34
34
  class LedgerBinaryApp:
35
-
36
35
  def __init__(self, binary_path: Union[str, Path]):
37
36
  if isinstance(binary_path, str):
38
37
  binary_path = Path(binary_path)
@@ -41,7 +40,8 @@ class LedgerBinaryApp:
41
40
  with self._path.open("rb") as filee:
42
41
  sections = {
43
42
  s.name.replace(LEDGER_PREFIX, ""): s.data().decode().strip()
44
- for s in ELFFile(filee).iter_sections() if LEDGER_PREFIX in s.name
43
+ for s in ELFFile(filee).iter_sections()
44
+ if LEDGER_PREFIX in s.name
45
45
  }
46
46
  self._sections = Sections(**sections)
47
47
 
@@ -51,16 +51,15 @@ class LedgerBinaryApp:
51
51
 
52
52
 
53
53
  def set_parser() -> ArgumentParser:
54
- parser = ArgumentParser(prog="ledger-binary",
55
- description="Utilitary to parse Ledger embedded application ELF file "
56
- "and output metadatas")
57
- parser.add_argument('-v', '--verbose', action='count', default=0)
54
+ parser = ArgumentParser(
55
+ prog="ledger-binary",
56
+ description="Utilitary to parse Ledger embedded application ELF file and output metadatas",
57
+ )
58
+ parser.add_argument("-v", "--verbose", action="count", default=0)
58
59
  parser.add_argument("binary", type=Path, help="The ledger embedded application ELF file")
59
- parser.add_argument("-j",
60
- "--json",
61
- required=False,
62
- action="store_true",
63
- help="outputs as JSON rather than text")
60
+ parser.add_argument(
61
+ "-j", "--json", required=False, action="store_true", help="outputs as JSON rather than text"
62
+ )
64
63
  return parser
65
64
 
66
65
 
@@ -17,14 +17,14 @@ class Condition(IntEnum):
17
17
 
18
18
 
19
19
  class NoManifestException(FileNotFoundError):
20
-
21
20
  def __init__(self, repository: "AppRepository"):
22
- super().__init__(f"`ledger_app.toml` manifest not found in repository '{repository.url}', "
23
- f"branch '{repository.current_branch}'.")
21
+ super().__init__(
22
+ f"`ledger_app.toml` manifest not found in repository '{repository.url}', "
23
+ f"branch '{repository.current_branch}'."
24
+ )
24
25
 
25
26
 
26
27
  class AppRepository(PyRepository.Repository):
27
-
28
28
  def __init__(self, *args, **kwargs) -> None:
29
29
  super().__init__(*args, **kwargs)
30
30
  self._manifest: Optional[Manifest] = None
@@ -60,8 +60,9 @@ class AppRepository(PyRepository.Repository):
60
60
  def makefile(self) -> str:
61
61
  if self._makefile is None:
62
62
  # paths on Windows contain "\" which are not compatible with GitHub remote paths
63
- makefile = self.get_contents(str(self.makefile_path).replace("\\", "/"),
64
- ref=self.current_branch)
63
+ makefile = self.get_contents(
64
+ str(self.makefile_path).replace("\\", "/"), ref=self.current_branch
65
+ )
65
66
  # `get_contents` can return a list, but here there can only be one Makefile / Cargo.toml
66
67
  assert isinstance(makefile, PyContentFile.ContentFile)
67
68
  self._makefile = makefile.decoded_content.decode()
@@ -72,9 +73,9 @@ class AppRepository(PyRepository.Repository):
72
73
  variants = []
73
74
  for line in self.makefile.splitlines():
74
75
  if "VARIANTS" in line:
75
- variants.extend(line.split(' ')[3:])
76
+ variants.extend(line.split(" ")[3:])
76
77
  elif "VARIANT_VALUES = " in line:
77
- variants.extend(line.split(" = ")[1].split(' '))
78
+ variants.extend(line.split(" = ")[1].split(" "))
78
79
  return variants
79
80
 
80
81
  @property
@@ -90,14 +91,15 @@ class AppRepository(PyRepository.Repository):
90
91
 
91
92
 
92
93
  class GitHubApps(list):
93
-
94
94
  def __init__(self, apps: List[AppRepository]):
95
95
  super().__init__([r for r in apps if r.name.startswith("app-")])
96
96
 
97
- def filter(self,
98
- name: Optional[str] = None,
99
- archived: Condition = Condition.WITH,
100
- private: Condition = Condition.WITH) -> "GitHubApps":
97
+ def filter(
98
+ self,
99
+ name: Optional[str] = None,
100
+ archived: Condition = Condition.WITH,
101
+ private: Condition = Condition.WITH,
102
+ ) -> "GitHubApps":
101
103
  new_list = [i for i in self]
102
104
  # archived filtering
103
105
  if archived == Condition.WITHOUT:
@@ -120,7 +122,6 @@ class GitHubApps(list):
120
122
 
121
123
 
122
124
  class GitHubLedgerHQ(PyGithub):
123
-
124
125
  def __init__(self, *args, **kwargs) -> None:
125
126
  super().__init__(*args, **kwargs)
126
127
  self._org = self.get_organization(LEDGER_ORG_NAME)
@@ -37,81 +37,99 @@ def text_output(content: Dict, indent: int = 0) -> None:
37
37
 
38
38
 
39
39
  def set_parser() -> ArgumentParser:
40
- parser = ArgumentParser(prog="ledger-manifest",
41
- description="Utilitary to parse and check an application "
42
- "'ledger_app.toml' manifest")
40
+ parser = ArgumentParser(
41
+ prog="ledger-manifest",
42
+ description="Utilitary to parse and check an application 'ledger_app.toml' manifest",
43
+ )
43
44
 
44
45
  # generic options
45
46
  parser.add_argument("-v", "--verbose", action="count", default=0)
46
- parser.add_argument("-c",
47
- "--check",
48
- required=False,
49
- type=Path,
50
- default=None,
51
- help="Check the manifest content against the provided directory.")
47
+ parser.add_argument(
48
+ "-c",
49
+ "--check",
50
+ required=False,
51
+ type=Path,
52
+ default=None,
53
+ help="Check the manifest content against the provided directory.",
54
+ )
52
55
 
53
56
  # display options
54
- parser.add_argument("manifest",
55
- type=Path,
56
- help=f"The manifest file (generally '{MANIFEST_FILE_NAME}' at the root of "
57
- "the application's repository), or the name of the app if the `--url` "
58
- "option is activated")
59
- parser.add_argument("-u",
60
- "--url",
61
- action="store_true",
62
- default=False,
63
- help="Tells if the `manifest` is a repository HTTP URL rather than a file")
64
- parser.add_argument("-os",
65
- "--output-sdk",
66
- required=False,
67
- action="store_true",
68
- default=False,
69
- help="outputs the SDK type")
70
- parser.add_argument("-ob",
71
- "--output-build-directory",
72
- required=False,
73
- action="store_true",
74
- default=False,
75
- help="outputs the build directory (where the Makefile in C app, or the "
76
- "Cargo.toml in Rust app is expected to be)")
77
- parser.add_argument("-od",
78
- "--output-devices",
79
- required=False,
80
- action="store_true",
81
- default=False,
82
- help="outputs the list of devices supported by the application")
83
- parser.add_argument("-otu",
84
- "--output-tests-unit-directory",
85
- required=False,
86
- action="store_true",
87
- default=False,
88
- help="outputs the directory of the unit tests. Fails if none")
89
- parser.add_argument("-otp",
90
- "--output-tests-pytest-directory",
91
- required=False,
92
- action="store_true",
93
- default=False,
94
- help="outputs the directory of the pytest (functional) tests. Fails if "
95
- "none")
96
- parser.add_argument("-otd",
97
- "--output-tests-dependencies",
98
- required=False,
99
- action='store',
100
- default=None,
101
- nargs='*',
102
- help="outputs the given use cases. Fails if none")
103
- parser.add_argument("-ouc",
104
- "--output-use-cases",
105
- required=False,
106
- default=None,
107
- action='store',
108
- nargs='*',
109
- help="outputs the given use cases. Fails if none")
110
- parser.add_argument("-j",
111
- "--json",
112
- required=False,
113
- action="store_true",
114
- help="outputs as JSON rather than text")
57
+ parser.add_argument(
58
+ "manifest",
59
+ type=Path,
60
+ help=f"The manifest file (generally '{MANIFEST_FILE_NAME}' at the root of "
61
+ "the application's repository), or the name of the app if the `--url` "
62
+ "option is activated",
63
+ )
64
+ parser.add_argument(
65
+ "-u",
66
+ "--url",
67
+ action="store_true",
68
+ default=False,
69
+ help="Tells if the `manifest` is a repository HTTP URL rather than a file",
70
+ )
71
+ parser.add_argument(
72
+ "-os",
73
+ "--output-sdk",
74
+ required=False,
75
+ action="store_true",
76
+ default=False,
77
+ help="outputs the SDK type",
78
+ )
79
+ parser.add_argument(
80
+ "-ob",
81
+ "--output-build-directory",
82
+ required=False,
83
+ action="store_true",
84
+ default=False,
85
+ help="outputs the build directory (where the Makefile in C app, or the "
86
+ "Cargo.toml in Rust app is expected to be)",
87
+ )
88
+ parser.add_argument(
89
+ "-od",
90
+ "--output-devices",
91
+ required=False,
92
+ action="store_true",
93
+ default=False,
94
+ help="outputs the list of devices supported by the application",
95
+ )
96
+ parser.add_argument(
97
+ "-otu",
98
+ "--output-tests-unit-directory",
99
+ required=False,
100
+ action="store_true",
101
+ default=False,
102
+ help="outputs the directory of the unit tests. Fails if none",
103
+ )
104
+ parser.add_argument(
105
+ "-otp",
106
+ "--output-tests-pytest-directory",
107
+ required=False,
108
+ action="store_true",
109
+ default=False,
110
+ help="outputs the directory of the pytest (functional) tests. Fails if none",
111
+ )
112
+ parser.add_argument(
113
+ "-otd",
114
+ "--output-tests-dependencies",
115
+ required=False,
116
+ action="store",
117
+ default=None,
118
+ nargs="*",
119
+ help="outputs the given use cases. Fails if none",
120
+ )
121
+ parser.add_argument(
122
+ "-ouc",
123
+ "--output-use-cases",
124
+ required=False,
125
+ default=None,
126
+ action="store",
127
+ nargs="*",
128
+ help="outputs the given use cases. Fails if none",
129
+ )
130
+ parser.add_argument(
131
+ "-j", "--json", required=False, action="store_true", help="outputs as JSON rather than text"
132
+ )
115
133
  return parser
116
134
 
117
135
 
@@ -170,8 +188,7 @@ def main() -> None: # pragma: no cover
170
188
  non_empty = len(dependencies) > 0
171
189
  if len(args.output_tests_dependencies) != 0:
172
190
  dependencies = {
173
- k: v
174
- for (k, v) in dependencies.items() if k in args.output_tests_dependencies
191
+ k: v for (k, v) in dependencies.items() if k in args.output_tests_dependencies
175
192
  }
176
193
  if not len(dependencies) and non_empty:
177
194
  logger.error("No use case match these ones: '%s'", args.output_tests_dependencies)
@@ -17,10 +17,9 @@ class Manifest(Jsonable):
17
17
  tests: Optional[TestsConfig]
18
18
  use_cases: Optional[UseCasesConfig]
19
19
 
20
- def __init__(self,
21
- app: Dict,
22
- tests: Optional[Dict] = None,
23
- use_cases: Optional[Dict] = None) -> None:
20
+ def __init__(
21
+ self, app: Dict, tests: Optional[Dict] = None, use_cases: Optional[Dict] = None
22
+ ) -> None:
24
23
  self.app = AppConfig(**app)
25
24
  self.tests = None if tests is None else TestsConfig(**tests)
26
25
  self.use_cases = None if use_cases is None else UseCasesConfig(**use_cases)
@@ -43,8 +42,13 @@ class Manifest(Jsonable):
43
42
  def check(self, base_directory: Union[str, Path]) -> None:
44
43
  base_directory = Path(base_directory)
45
44
  assert base_directory.is_dir(), f"Given '{base_directory}' must be a directory"
46
- build_file = base_directory / self.app.build_directory / \
47
- ("Cargo.toml" if self.app.is_rust else "Makefile")
45
+ build_file = (
46
+ base_directory
47
+ / self.app.build_directory
48
+ / ("Cargo.toml" if self.app.is_rust else "Makefile")
49
+ )
48
50
  logging.info("Checking existence of file %s", build_file)
49
- assert build_file.is_file(), f"No file '{build_file}' (from the given base directory " \
51
+ assert build_file.is_file(), (
52
+ f"No file '{build_file}' (from the given base directory "
50
53
  f"'{base_directory}' + the manifest path '{self.app.build_directory}') was found"
54
+ )
@@ -33,8 +33,9 @@ class TestsDependencyConfig(Jsonable):
33
33
 
34
34
  @property
35
35
  def dir(self) -> Path:
36
- return (self._base_dir / APPLICATION_DIRECTORY_NAME /
37
- f"{self._name}-{self.ref}-{self.use_case}")
36
+ return (
37
+ self._base_dir / APPLICATION_DIRECTORY_NAME / f"{self._name}-{self.ref}-{self.use_case}"
38
+ )
38
39
 
39
40
  def __eq__(self, other: object) -> bool:
40
41
  if not isinstance(other, TestsDependencyConfig):
@@ -81,10 +82,12 @@ class TestsConfig(Jsonable):
81
82
  pytest_directory: Optional[Path]
82
83
  dependencies: Optional[JsonDict]
83
84
 
84
- def __init__(self,
85
- pytest_directory: Optional[Union[str, Path]] = None,
86
- unit_directory: Optional[Union[str, Path]] = None,
87
- dependencies: Optional[Dict[str, List]] = None) -> None:
85
+ def __init__(
86
+ self,
87
+ pytest_directory: Optional[Union[str, Path]] = None,
88
+ unit_directory: Optional[Union[str, Path]] = None,
89
+ dependencies: Optional[Dict[str, List]] = None,
90
+ ) -> None:
88
91
  logger = getLogger()
89
92
  logger.debug("Parsing test dependencies")
90
93
  self.unit_directory = None if unit_directory is None else Path(unit_directory)
@@ -12,8 +12,10 @@ class UseCasesConfig(Jsonable):
12
12
  def __init__(self, **cases: Optional[Dict]) -> None:
13
13
  for key, value in cases.items():
14
14
  if not isinstance(value, str):
15
- raise ValueError(f"Use case '{key} = {value}' should have '{value}' as a string, "
16
- f"not a {type(value)}")
15
+ raise ValueError(
16
+ f"Use case '{key} = {value}' should have '{value}' as a string, "
17
+ f"not a {type(value)}"
18
+ )
17
19
  if key == DEFAULT_USE_CASE:
18
20
  raise ValueError(f"'{key}' use case is reserved and cannot be overridden")
19
21
  self.cases = JsonDict(cases)
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
 
3
3
  __logger__ = None
4
- DEFAULT_FORMAT = '[%(asctime)s][%(levelname)s] %(name)s - %(message)s'
4
+ DEFAULT_FORMAT = "[%(asctime)s][%(levelname)s] %(name)s - %(message)s"
5
5
 
6
6
 
7
7
  def getLogger() -> logging.Logger:
@@ -6,12 +6,11 @@ def to_str_int(value: Any) -> Union[int, str]:
6
6
 
7
7
 
8
8
  class Jsonable:
9
-
10
9
  @property
11
10
  def json(self) -> Union[Dict, List]:
12
11
  output: Dict[Union[str, int], Any] = dict()
13
12
  for key, value in self.__dict__.items():
14
- if key.startswith('_'):
13
+ if key.startswith("_"):
15
14
  # 'hidden' properties are not to be included into the output
16
15
  continue
17
16
  if isinstance(value, Jsonable):
@@ -22,7 +21,6 @@ class Jsonable:
22
21
 
23
22
 
24
23
  class JsonList(list, Jsonable):
25
-
26
24
  @property
27
25
  def json(self) -> List:
28
26
  output: List[Any] = list()
@@ -35,7 +33,6 @@ class JsonList(list, Jsonable):
35
33
 
36
34
 
37
35
  class JsonSet(set, Jsonable):
38
-
39
36
  @property
40
37
  def json(self) -> List:
41
38
  output: List[Any] = list()
@@ -48,7 +45,6 @@ class JsonSet(set, Jsonable):
48
45
 
49
46
 
50
47
  class JsonDict(dict, Jsonable):
51
-
52
48
  @property
53
49
  def json(self) -> Dict:
54
50
  output: Dict[Union[str, int], Any] = dict()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ledgered
3
- Version: 0.7.2.dev4
3
+ Version: 0.7.2.dev8
4
4
  Summary: Python tools, utils, libraries, to be used with Ledger cryptodevices
5
5
  Author-email: Ledger <hello@ledger.fr>
6
6
  License: MIT License
@@ -28,6 +28,7 @@ License: MIT License
28
28
  Project-URL: Home, https://github.com/LedgerHQ/ledgered
29
29
  Classifier: License :: OSI Approved :: MIT License
30
30
  Classifier: Programming Language :: Python :: 3
31
+ Classifier: Programming Language :: Python :: 3.9
31
32
  Classifier: Programming Language :: Python :: 3.10
32
33
  Classifier: Programming Language :: Python :: 3.11
33
34
  Classifier: Programming Language :: Python :: 3.12
@@ -36,7 +37,7 @@ Classifier: Operating System :: POSIX :: Linux
36
37
  Classifier: Operating System :: Microsoft :: Windows
37
38
  Classifier: Operating System :: MacOS :: MacOS X
38
39
  Classifier: Typing :: Typed
39
- Requires-Python: >=3.10
40
+ Requires-Python: >=3.9
40
41
  Description-Content-Type: text/markdown
41
42
  License-File: LICENSE
42
43
  Requires-Dist: toml
@@ -1,4 +1,5 @@
1
1
  .gitignore
2
+ .pre-commit-config.yaml
2
3
  CHANGELOG.md
3
4
  LICENSE
4
5
  README.md
@@ -1,4 +1,4 @@
1
1
  [app]
2
2
  build_directory = "./"
3
3
  sdk = "C"
4
- devices = ["nanos", "nanox"]
4
+ devices = ["nanos", "nanox"]
@@ -6,9 +6,13 @@ from ledgered.github import GitHubLedgerHQ
6
6
 
7
7
 
8
8
  def pytest_addoption(parser):
9
- parser.addoption("--token", required=False, default=None,
10
- help="Provide a GitHub token so that functional test won't trigger API "
11
- "restrictions too fast")
9
+ parser.addoption(
10
+ "--token",
11
+ required=False,
12
+ default=None,
13
+ help="Provide a GitHub token so that functional test won't trigger API "
14
+ "restrictions too fast",
15
+ )
12
16
 
13
17
 
14
18
  @pytest.fixture(scope="session")