pytecode 0.0.2__tar.gz → 0.0.3__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 (61) hide show
  1. {pytecode-0.0.2/pytecode.egg-info → pytecode-0.0.3}/PKG-INFO +11 -11
  2. {pytecode-0.0.2 → pytecode-0.0.3}/README.md +10 -10
  3. {pytecode-0.0.2 → pytecode-0.0.3}/pyproject.toml +2 -2
  4. {pytecode-0.0.2 → pytecode-0.0.3}/pytecode/__init__.py +5 -5
  5. pytecode-0.0.3/pytecode/_internal/__init__.py +1 -0
  6. pytecode-0.0.2/pytecode/analysis.py → pytecode-0.0.3/pytecode/analysis/__init__.py +14 -14
  7. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/analysis}/hierarchy.py +5 -5
  8. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/analysis}/verify.py +10 -10
  9. pytecode-0.0.2/pytecode/jar.py → pytecode-0.0.3/pytecode/archive/__init__.py +5 -5
  10. pytecode-0.0.3/pytecode/classfile/__init__.py +14 -0
  11. pytecode-0.0.2/pytecode/class_reader.py → pytecode-0.0.3/pytecode/classfile/reader.py +4 -4
  12. pytecode-0.0.2/pytecode/class_writer.py → pytecode-0.0.3/pytecode/classfile/writer.py +1 -1
  13. pytecode-0.0.3/pytecode/edit/__init__.py +12 -0
  14. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/edit}/_attribute_clone.py +1 -1
  15. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/edit}/constant_pool_builder.py +2 -2
  16. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/edit}/debug_info.py +1 -1
  17. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/edit}/labels.py +10 -10
  18. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/edit}/model.py +18 -18
  19. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/edit}/operands.py +1 -1
  20. pytecode-0.0.2/pytecode/transforms.py → pytecode-0.0.3/pytecode/transforms/__init__.py +3 -3
  21. {pytecode-0.0.2 → pytecode-0.0.3/pytecode.egg-info}/PKG-INFO +11 -11
  22. {pytecode-0.0.2 → pytecode-0.0.3}/pytecode.egg-info/SOURCES.txt +24 -21
  23. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_analysis.py +45 -56
  24. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_api_docs.py +6 -6
  25. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_attributes.py +4 -1
  26. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_bytes_utils.py +1 -1
  27. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_cfg_oracle.py +4 -8
  28. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_class_reader.py +7 -4
  29. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_class_writer.py +7 -4
  30. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_constant_pool.py +3 -3
  31. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_constant_pool_builder.py +4 -4
  32. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_debug_info.py +22 -150
  33. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_descriptors.py +2 -2
  34. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_helpers.py +122 -0
  35. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_hierarchy.py +5 -5
  36. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_instructions.py +1 -1
  37. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_jar.py +8 -14
  38. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_labels.py +19 -126
  39. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_model.py +45 -57
  40. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_modified_utf8.py +1 -1
  41. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_operands.py +16 -25
  42. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_transforms.py +3 -3
  43. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_validation.py +2 -2
  44. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_verify.py +31 -31
  45. {pytecode-0.0.2 → pytecode-0.0.3}/LICENSE +0 -0
  46. {pytecode-0.0.2 → pytecode-0.0.3}/MANIFEST.in +0 -0
  47. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/_internal}/bytes_utils.py +0 -0
  48. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/attributes.py +0 -0
  49. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/constant_pool.py +0 -0
  50. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/constants.py +0 -0
  51. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/descriptors.py +0 -0
  52. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/info.py +0 -0
  53. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/instructions.py +0 -0
  54. {pytecode-0.0.2/pytecode → pytecode-0.0.3/pytecode/classfile}/modified_utf8.py +0 -0
  55. {pytecode-0.0.2 → pytecode-0.0.3}/pytecode/py.typed +0 -0
  56. {pytecode-0.0.2 → pytecode-0.0.3}/pytecode.egg-info/dependency_links.txt +0 -0
  57. {pytecode-0.0.2 → pytecode-0.0.3}/pytecode.egg-info/requires.txt +0 -0
  58. {pytecode-0.0.2 → pytecode-0.0.3}/pytecode.egg-info/top_level.txt +0 -0
  59. {pytecode-0.0.2 → pytecode-0.0.3}/setup.cfg +0 -0
  60. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_javap_parser.py +0 -0
  61. {pytecode-0.0.2 → pytecode-0.0.3}/tests/test_validate_release_tag.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytecode
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Python library for parsing, manipulating, and emitting JVM class files
5
5
  Author: Trenton Smith
6
6
  License-Expression: MIT
@@ -95,8 +95,8 @@ Use `recompute_frames=True` when an edit changes control flow or stack/local lay
95
95
 
96
96
  ```python
97
97
  from pytecode import JarFile
98
- from pytecode.constants import MethodAccessFlag
99
- from pytecode.model import ClassModel, MethodModel
98
+ from pytecode.classfile.constants import MethodAccessFlag
99
+ from pytecode.edit.model import ClassModel, MethodModel
100
100
  from pytecode.transforms import (
101
101
  class_named,
102
102
  method_is_public,
@@ -136,15 +136,15 @@ Top-level exports:
136
136
  Supported submodules:
137
137
 
138
138
  - `pytecode.transforms` for composable class, field, method, and code transforms.
139
- - `pytecode.labels` for label-aware bytecode editing helpers.
140
- - `pytecode.operands` for symbolic operand wrappers.
139
+ - `pytecode.edit.labels` for label-aware bytecode editing helpers.
140
+ - `pytecode.edit.operands` for symbolic operand wrappers.
141
141
  - `pytecode.analysis` for CFG construction, frame simulation, and recomputation helpers.
142
- - `pytecode.verify` for structural validation and diagnostics.
143
- - `pytecode.hierarchy` for type and override resolution helpers.
144
- - `pytecode.descriptors` for JVM descriptors and generic signatures.
145
- - `pytecode.constant_pool_builder` for deterministic constant-pool construction.
146
- - `pytecode.modified_utf8` for JVM Modified UTF-8 encoding and decoding.
147
- - `pytecode.debug_info` for explicit debug-info preservation and stripping policies.
142
+ - `pytecode.analysis.verify` for structural validation and diagnostics.
143
+ - `pytecode.analysis.hierarchy` for type and override resolution helpers.
144
+ - `pytecode.classfile.descriptors` for JVM descriptors and generic signatures.
145
+ - `pytecode.edit.constant_pool_builder` for deterministic constant-pool construction.
146
+ - `pytecode.classfile.modified_utf8` for JVM Modified UTF-8 encoding and decoding.
147
+ - `pytecode.edit.debug_info` for explicit debug-info preservation and stripping policies.
148
148
 
149
149
  ## Documentation
150
150
 
@@ -69,8 +69,8 @@ Use `recompute_frames=True` when an edit changes control flow or stack/local lay
69
69
 
70
70
  ```python
71
71
  from pytecode import JarFile
72
- from pytecode.constants import MethodAccessFlag
73
- from pytecode.model import ClassModel, MethodModel
72
+ from pytecode.classfile.constants import MethodAccessFlag
73
+ from pytecode.edit.model import ClassModel, MethodModel
74
74
  from pytecode.transforms import (
75
75
  class_named,
76
76
  method_is_public,
@@ -110,15 +110,15 @@ Top-level exports:
110
110
  Supported submodules:
111
111
 
112
112
  - `pytecode.transforms` for composable class, field, method, and code transforms.
113
- - `pytecode.labels` for label-aware bytecode editing helpers.
114
- - `pytecode.operands` for symbolic operand wrappers.
113
+ - `pytecode.edit.labels` for label-aware bytecode editing helpers.
114
+ - `pytecode.edit.operands` for symbolic operand wrappers.
115
115
  - `pytecode.analysis` for CFG construction, frame simulation, and recomputation helpers.
116
- - `pytecode.verify` for structural validation and diagnostics.
117
- - `pytecode.hierarchy` for type and override resolution helpers.
118
- - `pytecode.descriptors` for JVM descriptors and generic signatures.
119
- - `pytecode.constant_pool_builder` for deterministic constant-pool construction.
120
- - `pytecode.modified_utf8` for JVM Modified UTF-8 encoding and decoding.
121
- - `pytecode.debug_info` for explicit debug-info preservation and stripping policies.
116
+ - `pytecode.analysis.verify` for structural validation and diagnostics.
117
+ - `pytecode.analysis.hierarchy` for type and override resolution helpers.
118
+ - `pytecode.classfile.descriptors` for JVM descriptors and generic signatures.
119
+ - `pytecode.edit.constant_pool_builder` for deterministic constant-pool construction.
120
+ - `pytecode.classfile.modified_utf8` for JVM Modified UTF-8 encoding and decoding.
121
+ - `pytecode.edit.debug_info` for explicit debug-info preservation and stripping policies.
122
122
 
123
123
  ## Documentation
124
124
 
@@ -6,14 +6,14 @@ build-backend = "setuptools.build_meta"
6
6
  include-package-data = true
7
7
 
8
8
  [tool.setuptools.packages.find]
9
- include = ["pytecode"]
9
+ include = ["pytecode*"]
10
10
 
11
11
  [tool.setuptools.package-data]
12
12
  pytecode = ["py.typed"]
13
13
 
14
14
  [project]
15
15
  name = "pytecode"
16
- version = "0.0.2"
16
+ version = "0.0.3"
17
17
  description = "Python library for parsing, manipulating, and emitting JVM class files"
18
18
  readme = "README.md"
19
19
  authors = [{ name = "Trenton Smith" }]
@@ -11,12 +11,12 @@ Provides four top-level entry points:
11
11
  Additional submodules expose transforms, descriptors, analysis, hierarchy
12
12
  resolution, validation, operands, labels, debug-info helpers, and the
13
13
  underlying data types. See ``pytecode.transforms``, ``pytecode.analysis``,
14
- ``pytecode.verify``, and the other documented submodules for details.
14
+ ``pytecode.analysis.verify``, and the other documented submodules for details.
15
15
  """
16
16
 
17
- from .class_reader import ClassReader
18
- from .class_writer import ClassWriter
19
- from .jar import JarFile
20
- from .model import ClassModel
17
+ from .archive import JarFile
18
+ from .classfile.reader import ClassReader
19
+ from .classfile.writer import ClassWriter
20
+ from .edit.model import ClassModel
21
21
 
22
22
  __all__ = ["ClassModel", "ClassReader", "ClassWriter", "JarFile"]
@@ -0,0 +1 @@
1
+ """Internal implementation helpers for pytecode."""
@@ -27,7 +27,7 @@ from collections.abc import Sequence
27
27
  from dataclasses import dataclass
28
28
  from typing import TYPE_CHECKING
29
29
 
30
- from .attributes import (
30
+ from ..classfile.attributes import (
31
31
  AppendFrameInfo,
32
32
  ChopFrameInfo,
33
33
  DoubleVariableInfo,
@@ -48,11 +48,11 @@ from .attributes import (
48
48
  UninitializedVariableInfo,
49
49
  VerificationTypeInfo,
50
50
  )
51
- from .constants import VerificationType
52
- from .descriptors import (
51
+ from ..classfile.constants import VerificationType
52
+ from ..classfile.descriptors import (
53
53
  ArrayType as DescArrayType,
54
54
  )
55
- from .descriptors import (
55
+ from ..classfile.descriptors import (
56
56
  BaseType,
57
57
  FieldDescriptor,
58
58
  ObjectType,
@@ -60,15 +60,14 @@ from .descriptors import (
60
60
  parse_field_descriptor,
61
61
  parse_method_descriptor,
62
62
  )
63
- from .hierarchy import JAVA_LANG_OBJECT, common_superclass
64
- from .instructions import (
63
+ from ..classfile.instructions import (
65
64
  ArrayType as InsnArrayType,
66
65
  )
67
- from .instructions import (
66
+ from ..classfile.instructions import (
68
67
  InsnInfo,
69
68
  InsnInfoType,
70
69
  )
71
- from .labels import (
70
+ from ..edit.labels import (
72
71
  BranchInsn,
73
72
  CodeItem,
74
73
  ExceptionHandler,
@@ -76,7 +75,7 @@ from .labels import (
76
75
  LookupSwitchInsn,
77
76
  TableSwitchInsn,
78
77
  )
79
- from .operands import (
78
+ from ..edit.operands import (
80
79
  FieldInsn,
81
80
  IIncInsn,
82
81
  InterfaceMethodInsn,
@@ -95,11 +94,12 @@ from .operands import (
95
94
  TypeInsn,
96
95
  VarInsn,
97
96
  )
97
+ from .hierarchy import JAVA_LANG_OBJECT, common_superclass
98
98
 
99
99
  if TYPE_CHECKING:
100
- from .constant_pool_builder import ConstantPoolBuilder
100
+ from ..edit.constant_pool_builder import ConstantPoolBuilder
101
+ from ..edit.model import CodeModel, MethodModel
101
102
  from .hierarchy import ClassResolver
102
- from .model import CodeModel, MethodModel
103
103
 
104
104
  # ===================================================================
105
105
  # Analysis errors
@@ -435,7 +435,7 @@ def initial_frame(method: MethodModel, class_name: str) -> FrameState:
435
435
  Returns:
436
436
  A ``FrameState`` representing the method entry point.
437
437
  """
438
- from .constants import MethodAccessFlag
438
+ from ..classfile.constants import MethodAccessFlag
439
439
 
440
440
  md = parse_method_descriptor(method.descriptor)
441
441
  locals_list: list[VType] = []
@@ -1936,7 +1936,7 @@ def _simulate_raw_insn(insn: InsnInfo, state: FrameState) -> FrameState:
1936
1936
  # --- NEWARRAY ---
1937
1937
  if opcode == _T.NEWARRAY:
1938
1938
  state, _ = state.pop(1) # pop count
1939
- from .instructions import NewArray as NewArrayInsn
1939
+ from ..classfile.instructions import NewArray as NewArrayInsn
1940
1940
 
1941
1941
  if isinstance(insn, NewArrayInsn):
1942
1942
  array_desc = _NEWARRAY_TYPE_MAP.get(insn.atype, "[I")
@@ -2279,7 +2279,7 @@ def compute_frames(
2279
2279
  analysis_code = _prepare_analysis_code(code)
2280
2280
  analysis_label_offsets = label_offsets
2281
2281
  if analysis_code is not code:
2282
- from .labels import resolve_labels
2282
+ from ..edit.labels import resolve_labels
2283
2283
 
2284
2284
  analysis_label_offsets = resolve_labels(list(analysis_code.instructions), cp).label_offsets
2285
2285
 
@@ -13,13 +13,13 @@ from collections.abc import Iterable, Iterator
13
13
  from dataclasses import dataclass
14
14
  from typing import TYPE_CHECKING, Protocol
15
15
 
16
- from .constant_pool import ClassInfo
17
- from .constant_pool_builder import ConstantPoolBuilder
18
- from .constants import ClassAccessFlag, MethodAccessFlag
19
- from .info import ClassFile
16
+ from ..classfile.constant_pool import ClassInfo
17
+ from ..classfile.constants import ClassAccessFlag, MethodAccessFlag
18
+ from ..classfile.info import ClassFile
19
+ from ..edit.constant_pool_builder import ConstantPoolBuilder
20
20
 
21
21
  if TYPE_CHECKING:
22
- from .model import ClassModel
22
+ from ..edit.model import ClassModel
23
23
 
24
24
  JAVA_LANG_OBJECT = "java/lang/Object"
25
25
 
@@ -15,7 +15,7 @@ from __future__ import annotations
15
15
  from dataclasses import dataclass, field
16
16
  from enum import Enum
17
17
 
18
- from .attributes import (
18
+ from ..classfile.attributes import (
19
19
  AnnotationDefaultAttr,
20
20
  AttributeInfo,
21
21
  BootstrapMethodsAttr,
@@ -41,7 +41,7 @@ from .attributes import (
41
41
  SourceDebugExtensionAttr,
42
42
  StackMapTableAttr,
43
43
  )
44
- from .constant_pool import (
44
+ from ..classfile.constant_pool import (
45
45
  ClassInfo,
46
46
  ConstantPoolInfo,
47
47
  DoubleInfo,
@@ -61,11 +61,10 @@ from .constant_pool import (
61
61
  StringInfo,
62
62
  Utf8Info,
63
63
  )
64
- from .constants import MAGIC, ClassAccessFlag, FieldAccessFlag, MethodAccessFlag
65
- from .debug_info import is_class_debug_info_stale, is_code_debug_info_stale
66
- from .descriptors import is_valid_field_descriptor, is_valid_method_descriptor
67
- from .info import ClassFile, FieldInfo, MethodInfo
68
- from .instructions import (
64
+ from ..classfile.constants import MAGIC, ClassAccessFlag, FieldAccessFlag, MethodAccessFlag
65
+ from ..classfile.descriptors import is_valid_field_descriptor, is_valid_method_descriptor
66
+ from ..classfile.info import ClassFile, FieldInfo, MethodInfo
67
+ from ..classfile.instructions import (
69
68
  Branch,
70
69
  BranchW,
71
70
  ConstPoolIndex,
@@ -77,14 +76,15 @@ from .instructions import (
77
76
  MultiANewArray,
78
77
  TableSwitch,
79
78
  )
80
- from .labels import (
79
+ from ..classfile.modified_utf8 import decode_modified_utf8
80
+ from ..edit.debug_info import is_class_debug_info_stale, is_code_debug_info_stale
81
+ from ..edit.labels import (
81
82
  BranchInsn,
82
83
  Label,
83
84
  LookupSwitchInsn,
84
85
  TableSwitchInsn,
85
86
  )
86
- from .model import ClassModel, CodeModel, FieldModel, MethodModel
87
- from .modified_utf8 import decode_modified_utf8
87
+ from ..edit.model import ClassModel, CodeModel, FieldModel, MethodModel
88
88
 
89
89
  __all__ = [
90
90
  "Category",
@@ -9,11 +9,11 @@ import zipfile
9
9
  from dataclasses import dataclass
10
10
  from pathlib import Path, PurePosixPath
11
11
 
12
- from .class_reader import ClassReader
13
- from .debug_info import DebugInfoPolicy, normalize_debug_info_policy
14
- from .hierarchy import ClassResolver
15
- from .model import ClassModel
16
- from .transforms import ClassTransform
12
+ from ..analysis.hierarchy import ClassResolver
13
+ from ..classfile.reader import ClassReader
14
+ from ..edit.debug_info import DebugInfoPolicy, normalize_debug_info_policy
15
+ from ..edit.model import ClassModel
16
+ from ..transforms import ClassTransform
17
17
 
18
18
  __all__ = ["JarFile", "JarInfo"]
19
19
 
@@ -0,0 +1,14 @@
1
+ """Parsed JVM classfile structures, parsing, and emission."""
2
+
3
+ from .info import ClassFile, FieldInfo, MethodInfo
4
+ from .reader import ClassReader, MalformedClassException
5
+ from .writer import ClassWriter
6
+
7
+ __all__ = [
8
+ "ClassFile",
9
+ "ClassReader",
10
+ "ClassWriter",
11
+ "FieldInfo",
12
+ "MalformedClassException",
13
+ "MethodInfo",
14
+ ]
@@ -2,15 +2,15 @@
2
2
 
3
3
  This module implements a single-pass reader that deserialises the binary
4
4
  class-file format defined in *The Java Virtual Machine Specification* (JVMS §4)
5
- into the in-memory ``ClassFile`` structure exposed by :mod:`pytecode.info`.
5
+ into the in-memory ``ClassFile`` structure exposed by :mod:`pytecode.classfile.info`.
6
6
  """
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
10
  import os
11
11
 
12
+ from .._internal.bytes_utils import BytesReader
12
13
  from . import attributes, constant_pool, constants, info, instructions
13
- from .bytes_utils import BytesReader
14
14
  from .modified_utf8 import decode_modified_utf8
15
15
 
16
16
  __all__ = ["ClassReader", "MalformedClassException"]
@@ -21,7 +21,7 @@ class MalformedClassException(Exception):
21
21
 
22
22
 
23
23
  class ClassReader(BytesReader):
24
- """Single-pass parser that converts ``.class`` file bytes into a :class:`~pytecode.info.ClassFile` tree.
24
+ """Single-pass parser that converts ``.class`` file bytes into a :class:`~pytecode.classfile.info.ClassFile` tree.
25
25
 
26
26
  The reader walks the binary layout defined in JVMS §4.1, populating the
27
27
  constant pool first (§4.4) and then deserialising fields, methods, and
@@ -379,7 +379,7 @@ class ClassReader(BytesReader):
379
379
  """Read a single ``attribute_info`` structure (JVMS §4.7).
380
380
 
381
381
  Recognised attribute names are decoded into their specific subtypes;
382
- unknown attributes are returned as :class:`~pytecode.attributes.UnimplementedAttr`.
382
+ unknown attributes are returned as :class:`~pytecode.classfile.attributes.UnimplementedAttr`.
383
383
 
384
384
  Returns:
385
385
  The decoded attribute info.
@@ -2,8 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from .._internal.bytes_utils import BytesWriter
5
6
  from . import attributes, constant_pool, instructions
6
- from .bytes_utils import BytesWriter
7
7
  from .info import ClassFile, FieldInfo, MethodInfo
8
8
 
9
9
  __all__ = ["ClassWriter"]
@@ -0,0 +1,12 @@
1
+ """Mutable editing models and lowering helpers for JVM class files."""
2
+
3
+ from .constant_pool_builder import ConstantPoolBuilder
4
+ from .model import ClassModel, CodeModel, FieldModel, MethodModel
5
+
6
+ __all__ = [
7
+ "ClassModel",
8
+ "CodeModel",
9
+ "ConstantPoolBuilder",
10
+ "FieldModel",
11
+ "MethodModel",
12
+ ]
@@ -6,7 +6,7 @@ from dataclasses import fields, is_dataclass
6
6
  from functools import cache
7
7
  from typing import Any, cast
8
8
 
9
- from .attributes import (
9
+ from ..classfile.attributes import (
10
10
  AnnotationInfo,
11
11
  AppendFrameInfo,
12
12
  ArrayValueInfo,
@@ -11,7 +11,7 @@ from typing import TYPE_CHECKING, cast
11
11
 
12
12
  __all__ = ["ConstantPoolBuilder"]
13
13
 
14
- from .constant_pool import (
14
+ from ..classfile.constant_pool import (
15
15
  ClassInfo,
16
16
  ConstantPoolInfo,
17
17
  DoubleInfo,
@@ -31,7 +31,7 @@ from .constant_pool import (
31
31
  StringInfo,
32
32
  Utf8Info,
33
33
  )
34
- from .modified_utf8 import decode_modified_utf8, encode_modified_utf8
34
+ from ..classfile.modified_utf8 import decode_modified_utf8, encode_modified_utf8
35
35
 
36
36
  if TYPE_CHECKING:
37
37
  pass
@@ -10,7 +10,7 @@ from __future__ import annotations
10
10
  from enum import Enum
11
11
  from typing import TYPE_CHECKING, overload
12
12
 
13
- from .attributes import AttributeInfo, MethodParametersAttr, SourceDebugExtensionAttr, SourceFileAttr
13
+ from ..classfile.attributes import AttributeInfo, MethodParametersAttr, SourceDebugExtensionAttr, SourceFileAttr
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from .model import ClassModel, CodeModel, MethodModel
@@ -13,8 +13,7 @@ import copy
13
13
  from dataclasses import dataclass
14
14
  from typing import TYPE_CHECKING, cast
15
15
 
16
- from ._attribute_clone import clone_attribute
17
- from .attributes import (
16
+ from ..classfile.attributes import (
18
17
  AttributeInfo,
19
18
  CodeAttr,
20
19
  ExceptionInfo,
@@ -25,11 +24,9 @@ from .attributes import (
25
24
  LocalVariableTypeInfo,
26
25
  LocalVariableTypeTableAttr,
27
26
  )
28
- from .constant_pool import ClassInfo
29
- from .constant_pool_builder import ConstantPoolBuilder
30
- from .debug_info import DebugInfoPolicy, is_code_debug_info_stale, normalize_debug_info_policy
31
- from .descriptors import parameter_slot_count, parse_method_descriptor
32
- from .instructions import (
27
+ from ..classfile.constant_pool import ClassInfo
28
+ from ..classfile.descriptors import parameter_slot_count, parse_method_descriptor
29
+ from ..classfile.instructions import (
33
30
  Branch,
34
31
  BranchW,
35
32
  ByteValue,
@@ -49,6 +46,9 @@ from .instructions import (
49
46
  ShortValue,
50
47
  TableSwitch,
51
48
  )
49
+ from ._attribute_clone import clone_attribute
50
+ from .constant_pool_builder import ConstantPoolBuilder
51
+ from .debug_info import DebugInfoPolicy, is_code_debug_info_stale, normalize_debug_info_policy
52
52
  from .operands import (
53
53
  _BASE_TO_WIDE,
54
54
  _VAR_SHORTCUTS,
@@ -76,7 +76,7 @@ from .operands import (
76
76
  )
77
77
 
78
78
  if TYPE_CHECKING:
79
- from .hierarchy import ClassResolver
79
+ from ..analysis.hierarchy import ClassResolver
80
80
  from .model import CodeModel, MethodModel
81
81
 
82
82
 
@@ -1093,8 +1093,8 @@ def lower_code(
1093
1093
 
1094
1094
  if recompute_frames:
1095
1095
  assert method is not None and class_name is not None
1096
- from .analysis import compute_frames
1097
- from .attributes import StackMapTableAttr
1096
+ from ..analysis import compute_frames
1097
+ from ..classfile.attributes import StackMapTableAttr
1098
1098
 
1099
1099
  frame_result = compute_frames(
1100
1100
  code,
@@ -13,17 +13,14 @@ from typing import TYPE_CHECKING, cast
13
13
 
14
14
  __all__ = ["ClassModel", "CodeModel", "FieldModel", "MethodModel"]
15
15
 
16
- from ._attribute_clone import clone_attribute, clone_attributes
17
- from .attributes import (
16
+ from ..classfile.attributes import (
18
17
  AttributeInfo,
19
18
  CodeAttr,
20
19
  LineNumberTableAttr,
21
20
  LocalVariableTableAttr,
22
21
  LocalVariableTypeTableAttr,
23
22
  )
24
- from .class_reader import ClassReader
25
- from .class_writer import ClassWriter
26
- from .constant_pool import (
23
+ from ..classfile.constant_pool import (
27
24
  ClassInfo,
28
25
  DoubleInfo,
29
26
  DynamicInfo,
@@ -39,18 +36,9 @@ from .constant_pool import (
39
36
  NameAndTypeInfo,
40
37
  StringInfo,
41
38
  )
42
- from .constant_pool_builder import ConstantPoolBuilder
43
- from .constants import MAGIC, ClassAccessFlag, FieldAccessFlag, MethodAccessFlag
44
- from .debug_info import (
45
- DebugInfoPolicy,
46
- DebugInfoState,
47
- is_class_debug_info_stale,
48
- normalize_debug_info_policy,
49
- skip_debug_method_attributes,
50
- strip_class_debug_attributes,
51
- )
52
- from .info import ClassFile, FieldInfo, MethodInfo
53
- from .instructions import (
39
+ from ..classfile.constants import MAGIC, ClassAccessFlag, FieldAccessFlag, MethodAccessFlag
40
+ from ..classfile.info import ClassFile, FieldInfo, MethodInfo
41
+ from ..classfile.instructions import (
54
42
  Branch,
55
43
  BranchW,
56
44
  ConstPoolIndex,
@@ -66,6 +54,18 @@ from .instructions import (
66
54
  MultiANewArray,
67
55
  TableSwitch,
68
56
  )
57
+ from ..classfile.reader import ClassReader
58
+ from ..classfile.writer import ClassWriter
59
+ from ._attribute_clone import clone_attribute, clone_attributes
60
+ from .constant_pool_builder import ConstantPoolBuilder
61
+ from .debug_info import (
62
+ DebugInfoPolicy,
63
+ DebugInfoState,
64
+ is_class_debug_info_stale,
65
+ normalize_debug_info_policy,
66
+ skip_debug_method_attributes,
67
+ strip_class_debug_attributes,
68
+ )
69
69
  from .labels import (
70
70
  BranchInsn,
71
71
  CodeItem,
@@ -105,7 +105,7 @@ from .operands import (
105
105
  )
106
106
 
107
107
  if TYPE_CHECKING:
108
- from .hierarchy import ClassResolver
108
+ from ..analysis.hierarchy import ClassResolver
109
109
 
110
110
 
111
111
  @dataclass
@@ -30,7 +30,7 @@ from __future__ import annotations
30
30
  from dataclasses import dataclass
31
31
  from typing import TYPE_CHECKING
32
32
 
33
- from .instructions import (
33
+ from ..classfile.instructions import (
34
34
  InsnInfo,
35
35
  InsnInfoType,
36
36
  )
@@ -16,9 +16,9 @@ from dataclasses import dataclass
16
16
  from enum import IntFlag
17
17
  from typing import Protocol, cast
18
18
 
19
- from .constants import ClassAccessFlag, FieldAccessFlag, MethodAccessFlag
20
- from .descriptors import VoidType, parse_method_descriptor, to_descriptor
21
- from .model import ClassModel, CodeModel, FieldModel, MethodModel
19
+ from ..classfile.constants import ClassAccessFlag, FieldAccessFlag, MethodAccessFlag
20
+ from ..classfile.descriptors import VoidType, parse_method_descriptor, to_descriptor
21
+ from ..edit.model import ClassModel, CodeModel, FieldModel, MethodModel
22
22
 
23
23
  type Predicate[T] = Callable[[T], bool]
24
24
  type ClassPredicate = Predicate[ClassModel]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytecode
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Python library for parsing, manipulating, and emitting JVM class files
5
5
  Author: Trenton Smith
6
6
  License-Expression: MIT
@@ -95,8 +95,8 @@ Use `recompute_frames=True` when an edit changes control flow or stack/local lay
95
95
 
96
96
  ```python
97
97
  from pytecode import JarFile
98
- from pytecode.constants import MethodAccessFlag
99
- from pytecode.model import ClassModel, MethodModel
98
+ from pytecode.classfile.constants import MethodAccessFlag
99
+ from pytecode.edit.model import ClassModel, MethodModel
100
100
  from pytecode.transforms import (
101
101
  class_named,
102
102
  method_is_public,
@@ -136,15 +136,15 @@ Top-level exports:
136
136
  Supported submodules:
137
137
 
138
138
  - `pytecode.transforms` for composable class, field, method, and code transforms.
139
- - `pytecode.labels` for label-aware bytecode editing helpers.
140
- - `pytecode.operands` for symbolic operand wrappers.
139
+ - `pytecode.edit.labels` for label-aware bytecode editing helpers.
140
+ - `pytecode.edit.operands` for symbolic operand wrappers.
141
141
  - `pytecode.analysis` for CFG construction, frame simulation, and recomputation helpers.
142
- - `pytecode.verify` for structural validation and diagnostics.
143
- - `pytecode.hierarchy` for type and override resolution helpers.
144
- - `pytecode.descriptors` for JVM descriptors and generic signatures.
145
- - `pytecode.constant_pool_builder` for deterministic constant-pool construction.
146
- - `pytecode.modified_utf8` for JVM Modified UTF-8 encoding and decoding.
147
- - `pytecode.debug_info` for explicit debug-info preservation and stripping policies.
142
+ - `pytecode.analysis.verify` for structural validation and diagnostics.
143
+ - `pytecode.analysis.hierarchy` for type and override resolution helpers.
144
+ - `pytecode.classfile.descriptors` for JVM descriptors and generic signatures.
145
+ - `pytecode.edit.constant_pool_builder` for deterministic constant-pool construction.
146
+ - `pytecode.classfile.modified_utf8` for JVM Modified UTF-8 encoding and decoding.
147
+ - `pytecode.edit.debug_info` for explicit debug-info preservation and stripping policies.
148
148
 
149
149
  ## Documentation
150
150
 
@@ -3,33 +3,36 @@ MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
5
  pytecode/__init__.py
6
- pytecode/_attribute_clone.py
7
- pytecode/analysis.py
8
- pytecode/attributes.py
9
- pytecode/bytes_utils.py
10
- pytecode/class_reader.py
11
- pytecode/class_writer.py
12
- pytecode/constant_pool.py
13
- pytecode/constant_pool_builder.py
14
- pytecode/constants.py
15
- pytecode/debug_info.py
16
- pytecode/descriptors.py
17
- pytecode/hierarchy.py
18
- pytecode/info.py
19
- pytecode/instructions.py
20
- pytecode/jar.py
21
- pytecode/labels.py
22
- pytecode/model.py
23
- pytecode/modified_utf8.py
24
- pytecode/operands.py
25
6
  pytecode/py.typed
26
- pytecode/transforms.py
27
- pytecode/verify.py
28
7
  pytecode.egg-info/PKG-INFO
29
8
  pytecode.egg-info/SOURCES.txt
30
9
  pytecode.egg-info/dependency_links.txt
31
10
  pytecode.egg-info/requires.txt
32
11
  pytecode.egg-info/top_level.txt
12
+ pytecode/_internal/__init__.py
13
+ pytecode/_internal/bytes_utils.py
14
+ pytecode/analysis/__init__.py
15
+ pytecode/analysis/hierarchy.py
16
+ pytecode/analysis/verify.py
17
+ pytecode/archive/__init__.py
18
+ pytecode/classfile/__init__.py
19
+ pytecode/classfile/attributes.py
20
+ pytecode/classfile/constant_pool.py
21
+ pytecode/classfile/constants.py
22
+ pytecode/classfile/descriptors.py
23
+ pytecode/classfile/info.py
24
+ pytecode/classfile/instructions.py
25
+ pytecode/classfile/modified_utf8.py
26
+ pytecode/classfile/reader.py
27
+ pytecode/classfile/writer.py
28
+ pytecode/edit/__init__.py
29
+ pytecode/edit/_attribute_clone.py
30
+ pytecode/edit/constant_pool_builder.py
31
+ pytecode/edit/debug_info.py
32
+ pytecode/edit/labels.py
33
+ pytecode/edit/model.py
34
+ pytecode/edit/operands.py
35
+ pytecode/transforms/__init__.py
33
36
  tests/test_analysis.py
34
37
  tests/test_api_docs.py
35
38
  tests/test_attributes.py