asnkit-gen-python 1.0.1__tar.gz → 1.1.0__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.
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/PKG-INFO +13 -3
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/README.rst +11 -1
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/pyproject.toml +2 -2
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/pyproject.toml.orig +2 -2
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/src/asnkit_gen_python/cli.py +13 -4
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/src/asnkit_gen_python/generate.py +84 -17
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/src/asnkit_gen_python/version.py +1 -1
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/LICENSE-COMPILER +0 -0
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/src/asnkit_gen_python/__init__.py +0 -0
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/src/asnkit_gen_python/__main__.py +0 -0
- {asnkit_gen_python-1.0.1 → asnkit_gen_python-1.1.0}/src/asnkit_gen_python/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: asnkit-gen-python
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: asnkit plugin that makes Python code with data classes from ASN.1
|
|
5
5
|
Author: xadaemon
|
|
6
6
|
Author-email: xadaemon <mxavier@boxtheta.com>
|
|
@@ -10,7 +10,7 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Topic :: Software Development :: Code Generators
|
|
13
|
-
Requires-Dist: asnkitrt==1.0
|
|
13
|
+
Requires-Dist: asnkitrt==1.1.0
|
|
14
14
|
Requires-Python: >=3.13
|
|
15
15
|
Project-URL: source, https://github.com/boxtheta/asnkit
|
|
16
16
|
Description-Content-Type: text/x-rst
|
|
@@ -19,7 +19,7 @@ asnkit-gen-python
|
|
|
19
19
|
=================
|
|
20
20
|
|
|
21
21
|
A plugin for `asnkitcc`_ that generates Python code from ASN.1. The
|
|
22
|
-
generated module imports `asnkitrt`_ and embeds the compiled
|
|
22
|
+
generated module imports `asnkitrt`_ and, by default, embeds the compiled
|
|
23
23
|
specification as bytes. It has a data class for each ``SEQUENCE`` and
|
|
24
24
|
``SET``, an enumeration for each ``ENUMERATED`` and a class for each
|
|
25
25
|
alternative of a ``CHOICE``, all with methods to encode and decode.
|
|
@@ -45,6 +45,16 @@ Options, given with ``--plugin-opt KEY=VALUE``:
|
|
|
45
45
|
``codec``
|
|
46
46
|
The codec used when none is given. Default: ``ber``.
|
|
47
47
|
|
|
48
|
+
``embed``
|
|
49
|
+
``false`` to leave the compiled specification out of the module, as
|
|
50
|
+
for one sent signed or encrypted. The module then has
|
|
51
|
+
``use_asni(data, ...)``, which takes the contents of the ``.asni``
|
|
52
|
+
file with the options of ``asnkitrt.load_asni()`` (``nonce``,
|
|
53
|
+
``bound_to``, ``verification_keys``, ``decryption_keys`` and those
|
|
54
|
+
to accept any), checks it once and uses it for every codec. Until it
|
|
55
|
+
is called, encoding and decoding raise ``RuntimeError``. The file has
|
|
56
|
+
to be compiled from the same specification. Default: ``true``.
|
|
57
|
+
|
|
48
58
|
Names are converted to Python style: ``fooBar`` becomes ``foo_bar`` and
|
|
49
59
|
a type ``Foo-Bar`` becomes ``FooBar``. If two names end up the same in
|
|
50
60
|
Python, generation fails with an error.
|
|
@@ -2,7 +2,7 @@ asnkit-gen-python
|
|
|
2
2
|
=================
|
|
3
3
|
|
|
4
4
|
A plugin for `asnkitcc`_ that generates Python code from ASN.1. The
|
|
5
|
-
generated module imports `asnkitrt`_ and embeds the compiled
|
|
5
|
+
generated module imports `asnkitrt`_ and, by default, embeds the compiled
|
|
6
6
|
specification as bytes. It has a data class for each ``SEQUENCE`` and
|
|
7
7
|
``SET``, an enumeration for each ``ENUMERATED`` and a class for each
|
|
8
8
|
alternative of a ``CHOICE``, all with methods to encode and decode.
|
|
@@ -28,6 +28,16 @@ Options, given with ``--plugin-opt KEY=VALUE``:
|
|
|
28
28
|
``codec``
|
|
29
29
|
The codec used when none is given. Default: ``ber``.
|
|
30
30
|
|
|
31
|
+
``embed``
|
|
32
|
+
``false`` to leave the compiled specification out of the module, as
|
|
33
|
+
for one sent signed or encrypted. The module then has
|
|
34
|
+
``use_asni(data, ...)``, which takes the contents of the ``.asni``
|
|
35
|
+
file with the options of ``asnkitrt.load_asni()`` (``nonce``,
|
|
36
|
+
``bound_to``, ``verification_keys``, ``decryption_keys`` and those
|
|
37
|
+
to accept any), checks it once and uses it for every codec. Until it
|
|
38
|
+
is called, encoding and decoding raise ``RuntimeError``. The file has
|
|
39
|
+
to be compiled from the same specification. Default: ``true``.
|
|
40
|
+
|
|
31
41
|
Names are converted to Python style: ``fooBar`` becomes ``foo_bar`` and
|
|
32
42
|
a type ``Foo-Bar`` becomes ``FooBar``. If two names end up the same in
|
|
33
43
|
Python, generation fails with an error.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "asnkit-gen-python"
|
|
3
|
-
version = "1.0
|
|
3
|
+
version = "1.1.0"
|
|
4
4
|
description = "asnkit plugin that makes Python code with data classes from ASN.1"
|
|
5
5
|
readme = "README.rst"
|
|
6
6
|
requires-python = ">=3.13"
|
|
7
|
-
dependencies = ["asnkitrt==1.0
|
|
7
|
+
dependencies = ["asnkitrt==1.1.0"]
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
license-files = ["LICENSE-COMPILER"]
|
|
10
10
|
classifiers = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "asnkit-gen-python"
|
|
3
|
-
version = "1.0
|
|
3
|
+
version = "1.1.0"
|
|
4
4
|
description = "asnkit plugin that makes Python code with data classes from ASN.1"
|
|
5
5
|
readme = "README.rst"
|
|
6
6
|
authors = [
|
|
@@ -8,7 +8,7 @@ authors = [
|
|
|
8
8
|
]
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
10
|
dependencies = [
|
|
11
|
-
"asnkitrt==1.0
|
|
11
|
+
"asnkitrt==1.1.0",
|
|
12
12
|
]
|
|
13
13
|
license = "Apache-2.0"
|
|
14
14
|
license-files = ["LICENSE-COMPILER"]
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
|
|
11
11
|
It writes one Python module to the folder. The options are ``name``,
|
|
12
12
|
which is the name of the module without ``.py`` (default: that of
|
|
13
|
-
the first file the specification is from),
|
|
13
|
+
the first file the specification is from), ``codec``, which is
|
|
14
14
|
what the module encodes and decodes with if not told otherwise
|
|
15
|
-
(default: ``ber``)
|
|
15
|
+
(default: ``ber``), and ``embed``, which is ``false`` for a module that
|
|
16
|
+
does not have the compiled specification in it, and is given it with
|
|
17
|
+
its ``use_asni()`` (default: ``true``).
|
|
16
18
|
|
|
17
19
|
"""
|
|
18
20
|
|
|
@@ -26,7 +28,7 @@ from asnkitrt.errors import Error
|
|
|
26
28
|
from .generate import DEFAULT_CODEC, GenerateError, generate
|
|
27
29
|
from .version import __version__
|
|
28
30
|
|
|
29
|
-
OPTIONS = {"name", "codec"}
|
|
31
|
+
OPTIONS = {"name", "codec", "embed"}
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
def read_options(items: list[str]) -> dict[str, str]:
|
|
@@ -71,7 +73,14 @@ def run(args: argparse.Namespace) -> str:
|
|
|
71
73
|
if not name.isidentifier():
|
|
72
74
|
raise GenerateError("Expected a name of a module, but got '{}'.".format(name))
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
embed = options.get("embed", "true")
|
|
77
|
+
|
|
78
|
+
if embed not in ("true", "false"):
|
|
79
|
+
raise GenerateError(
|
|
80
|
+
"Expected embed=true or embed=false, but got '{}'.".format(embed)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
text = generate(asni, sources, options.get("codec", DEFAULT_CODEC), embed == "true")
|
|
75
84
|
os.makedirs(args.out, exist_ok=True)
|
|
76
85
|
path = os.path.join(args.out, name + ".py")
|
|
77
86
|
|
|
@@ -69,6 +69,7 @@ TAKEN = {
|
|
|
69
69
|
"enum",
|
|
70
70
|
"functools",
|
|
71
71
|
"spec",
|
|
72
|
+
"use_asni",
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
# Names of what the methods of the classes are called, which a member
|
|
@@ -136,17 +137,7 @@ from asnkitrt.runtime import CodecType
|
|
|
136
137
|
|
|
137
138
|
DEFAULT_CODEC: CodecType = "{codec}"
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
_ASNI = (
|
|
141
|
-
{asni}
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@functools.cache
|
|
146
|
-
def spec(codec: CodecType = DEFAULT_CODEC) -> asnkitrt.Specification:
|
|
147
|
-
"""The specification, loaded for the given codec."""
|
|
148
|
-
|
|
149
|
-
return asnkitrt.load_asni(_ASNI, codec)
|
|
140
|
+
{load}
|
|
150
141
|
|
|
151
142
|
|
|
152
143
|
def _type(codec: CodecType, asn1_type: tuple[str, str]) -> Any:
|
|
@@ -338,6 +329,7 @@ class Generator:
|
|
|
338
329
|
asni: bytes,
|
|
339
330
|
sources: list[str],
|
|
340
331
|
codec: str,
|
|
332
|
+
embed: bool = True,
|
|
341
333
|
) -> None:
|
|
342
334
|
from asnkitrt.version import __version__ as asnkit_version # noqa: F401
|
|
343
335
|
|
|
@@ -347,11 +339,15 @@ class Generator:
|
|
|
347
339
|
self.asni = asni
|
|
348
340
|
self.sources = sources
|
|
349
341
|
self.codec = codec
|
|
342
|
+
self.embed = embed
|
|
350
343
|
self.modules: dict[str, Any] = syntax.compiled_to_dict(compiled)
|
|
351
344
|
self.blocks: list[str] = []
|
|
352
345
|
self.registrations: list[str] = []
|
|
353
346
|
self.functions: list[str] = []
|
|
354
347
|
self.exported: list[str] = ["DEFAULT_CODEC", "spec"]
|
|
348
|
+
|
|
349
|
+
if not embed:
|
|
350
|
+
self.exported.append("use_asni")
|
|
355
351
|
self.taken: dict[str, str] = {name: "the code of the module" for name in TAKEN}
|
|
356
352
|
self.names: dict[tuple[str, str], str] = {}
|
|
357
353
|
self.aliases: dict[tuple[str, str], tuple[str, str]] = {}
|
|
@@ -728,7 +724,11 @@ class Generator:
|
|
|
728
724
|
version=self.version,
|
|
729
725
|
sources=", ".join(self.sources) or "a specification",
|
|
730
726
|
codec=self.codec,
|
|
731
|
-
|
|
727
|
+
load=(
|
|
728
|
+
EMBEDDED.format(asni=format_bytes(self.asni))
|
|
729
|
+
if self.embed
|
|
730
|
+
else NOT_EMBEDDED
|
|
731
|
+
).strip("\n"),
|
|
732
732
|
)
|
|
733
733
|
parts = [
|
|
734
734
|
header,
|
|
@@ -745,6 +745,70 @@ class Generator:
|
|
|
745
745
|
return "\n\n\n".join(part.strip("\n") for part in parts if part.strip()) + "\n"
|
|
746
746
|
|
|
747
747
|
|
|
748
|
+
# How a module loads its specification when it is in it.
|
|
749
|
+
EMBEDDED = """\
|
|
750
|
+
# The compiled specification, as the contents of an .asni file.
|
|
751
|
+
_ASNI = (
|
|
752
|
+
{asni}
|
|
753
|
+
)
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
@functools.cache
|
|
757
|
+
def spec(codec: CodecType = DEFAULT_CODEC) -> asnkitrt.Specification:
|
|
758
|
+
\"\"\"The specification, loaded for the given codec.\"\"\"
|
|
759
|
+
|
|
760
|
+
return asnkitrt.load_asni(_ASNI, codec)
|
|
761
|
+
"""
|
|
762
|
+
|
|
763
|
+
# How a module loads its specification when it is not in it, but given
|
|
764
|
+
# by the code that uses it.
|
|
765
|
+
NOT_EMBEDDED = """\
|
|
766
|
+
# The compiled specification is not in this module: give it with use_asni().
|
|
767
|
+
_SPECIFICATION: asnkitrt.syntax.CompiledSpecification | None = None
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
def use_asni(
|
|
771
|
+
data: bytes | bytearray,
|
|
772
|
+
nonce: asnkitrt.syntax.NonceCheck = None,
|
|
773
|
+
accept_any_nonce: bool = False,
|
|
774
|
+
bound_to: str | None = None,
|
|
775
|
+
accept_any_binding: bool = False,
|
|
776
|
+
verification_keys: asnkitrt.syntax.Keys | None = None,
|
|
777
|
+
accept_any_signature: bool = False,
|
|
778
|
+
decryption_keys: asnkitrt.syntax.Keys | None = None,
|
|
779
|
+
) -> None:
|
|
780
|
+
\"\"\"Uses the contents of an .asni file, made from the specification this
|
|
781
|
+
module is made from, for all codecs. It is checked once, here, with the
|
|
782
|
+
options of asnkitrt.load_asni().
|
|
783
|
+
|
|
784
|
+
\"\"\"
|
|
785
|
+
|
|
786
|
+
global _SPECIFICATION
|
|
787
|
+
|
|
788
|
+
_SPECIFICATION = asnkitrt.syntax.from_asni(
|
|
789
|
+
data,
|
|
790
|
+
nonce,
|
|
791
|
+
accept_any_nonce,
|
|
792
|
+
bound_to,
|
|
793
|
+
accept_any_binding,
|
|
794
|
+
verification_keys,
|
|
795
|
+
accept_any_signature,
|
|
796
|
+
decryption_keys,
|
|
797
|
+
)
|
|
798
|
+
spec.cache_clear()
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
@functools.cache
|
|
802
|
+
def spec(codec: CodecType = DEFAULT_CODEC) -> asnkitrt.Specification:
|
|
803
|
+
\"\"\"The specification given with use_asni(), loaded for the given codec.\"\"\"
|
|
804
|
+
|
|
805
|
+
if _SPECIFICATION is None:
|
|
806
|
+
raise RuntimeError("No specification: give it with use_asni().")
|
|
807
|
+
|
|
808
|
+
return asnkitrt.load(_SPECIFICATION, codec)
|
|
809
|
+
"""
|
|
810
|
+
|
|
811
|
+
|
|
748
812
|
REGISTER = """\
|
|
749
813
|
def _register(
|
|
750
814
|
class_: Any, asn1_type: tuple[str, str], shape: Any
|
|
@@ -769,13 +833,16 @@ def generate(
|
|
|
769
833
|
asni: bytes,
|
|
770
834
|
sources: list[str] | None = None,
|
|
771
835
|
codec: str = DEFAULT_CODEC,
|
|
836
|
+
embed: bool = True,
|
|
772
837
|
) -> str:
|
|
773
838
|
"""Returns the text of a Python module for given contents of an
|
|
774
839
|
``.asni`` file, which must not be signed, encrypted, bound to
|
|
775
|
-
something or have a nonce to check, as it
|
|
776
|
-
and loaded without any of those. `sources` are the names of
|
|
777
|
-
files it was made from, and `codec` is what the module encodes
|
|
778
|
-
decodes with if not told otherwise.
|
|
840
|
+
something or have a nonce to check, as it may be embedded in the
|
|
841
|
+
module and loaded without any of those. `sources` are the names of
|
|
842
|
+
the files it was made from, and `codec` is what the module encodes
|
|
843
|
+
and decodes with if not told otherwise. Without `embed`, the module
|
|
844
|
+
does not have the specification in it, and is given it with its
|
|
845
|
+
``use_asni()``, as from a file that is signed or encrypted.
|
|
779
846
|
|
|
780
847
|
"""
|
|
781
848
|
|
|
@@ -787,4 +854,4 @@ def generate(
|
|
|
787
854
|
"bound to something or has a nonce, but: {}".format(error)
|
|
788
855
|
)
|
|
789
856
|
|
|
790
|
-
return Generator(compiled, asni, sources or [], codec).run()
|
|
857
|
+
return Generator(compiled, asni, sources or [], codec, embed).run()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|