arxpy 1.24.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.
arxpy-1.24.1/PKG-INFO ADDED
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.4
2
+ Name: arxpy
3
+ Version: 1.24.1
4
+ Summary: ArxPy is a Python API layer for the Arx compiler.
5
+ License-Expression: Apache-2.0
6
+ Author: Ivan Ogasawara
7
+ Author-email: ivan.ogasawara@gmail.com
8
+ Requires-Python: >=3.10,<4
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Requires-Dist: arxlang (==1.24.1)
16
+ Description-Content-Type: text/markdown
17
+
18
+ # ArxPy
19
+
20
+ ArxPy is the developing Python-facing API for the Arx compiler.
21
+
22
+ > Status: API foundation only. The package currently provides structured
23
+ > diagnostics and public exception types; it does not yet expose parse, compile,
24
+ > run, or artifact APIs.
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install arxpy
30
+ ```
31
+
32
+ ## Current API
33
+
34
+ ```python
35
+ from arxpy import (
36
+ ArxError,
37
+ CompileError,
38
+ Diagnostic,
39
+ DiagnosticSeverity,
40
+ ExecutionError,
41
+ ParseError,
42
+ )
43
+ ```
44
+
45
+ `Diagnostic` is an immutable external record with severity, message, filename,
46
+ line, column, and optional code. ArxPy adapters translate IRx structured
47
+ diagnostics and Arx parser exceptions without exposing raw compiler nodes.
48
+
49
+ All public failures inherit from `ArxError` and carry a `diagnostics` list.
50
+
51
+ Until the compiler facade lands, use the `arx` CLI for end-to-end compilation or
52
+ the lower-level Arx/IRx APIs for internal integrations.
53
+
54
+ Documentation: <https://arxlang.org/arxpy/>
55
+
56
+ License: Apache-2.0.
57
+
arxpy-1.24.1/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # ArxPy
2
+
3
+ ArxPy is the developing Python-facing API for the Arx compiler.
4
+
5
+ > Status: API foundation only. The package currently provides structured
6
+ > diagnostics and public exception types; it does not yet expose parse, compile,
7
+ > run, or artifact APIs.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pip install arxpy
13
+ ```
14
+
15
+ ## Current API
16
+
17
+ ```python
18
+ from arxpy import (
19
+ ArxError,
20
+ CompileError,
21
+ Diagnostic,
22
+ DiagnosticSeverity,
23
+ ExecutionError,
24
+ ParseError,
25
+ )
26
+ ```
27
+
28
+ `Diagnostic` is an immutable external record with severity, message, filename,
29
+ line, column, and optional code. ArxPy adapters translate IRx structured
30
+ diagnostics and Arx parser exceptions without exposing raw compiler nodes.
31
+
32
+ All public failures inherit from `ArxError` and carry a `diagnostics` list.
33
+
34
+ Until the compiler facade lands, use the `arx` CLI for end-to-end compilation or
35
+ the lower-level Arx/IRx APIs for internal integrations.
36
+
37
+ Documentation: <https://arxlang.org/arxpy/>
38
+
39
+ License: Apache-2.0.
@@ -0,0 +1,104 @@
1
+ [project]
2
+ name = "arxpy"
3
+ version = "1.24.1" # semantic-release
4
+ description = "ArxPy is a Python API layer for the Arx compiler."
5
+ readme = "README.md"
6
+ authors = [
7
+ {name = "Ivan Ogasawara", email = "ivan.ogasawara@gmail.com"}
8
+ ]
9
+ license = "Apache-2.0"
10
+ requires-python = ">=3.10,<4"
11
+ dependencies = [
12
+ "arxlang == 1.24.1", # semantic-release
13
+ ]
14
+
15
+ [build-system]
16
+ requires = ["poetry-core>=2"]
17
+ build-backend = "poetry.core.masonry.api"
18
+
19
+ [tool.poetry]
20
+ exclude = [
21
+ ".git/*",
22
+ ".env*",
23
+ ]
24
+ packages = [
25
+ {include = "arxpy", from="src"},
26
+ ]
27
+ include = ["src/arxpy/py.typed"]
28
+
29
+ [tool.pytest.ini_options]
30
+ testpaths = [
31
+ "tests",
32
+ ]
33
+ filterwarnings = [
34
+ "error::RuntimeWarning",
35
+ ]
36
+
37
+ [tool.bandit]
38
+ exclude_dirs = ["tests"]
39
+ targets = "./"
40
+
41
+ [tool.vulture]
42
+ exclude = ["tests"]
43
+ ignore_decorators = ["abc.abstractmethod"]
44
+ ignore_names = []
45
+ make_whitelist = true
46
+ min_confidence = 80
47
+ paths = ["./"]
48
+ sort_by_size = true
49
+ verbose = false
50
+
51
+ [tool.ruff]
52
+ line-length = 79
53
+ force-exclude = true
54
+ src = ["./"]
55
+ target-version = "py310"
56
+ exclude = [
57
+ 'docs',
58
+ ]
59
+ fix = true
60
+
61
+ [tool.ruff.lint]
62
+ ignore = [
63
+ "F811", # redefined-while-unused
64
+ "PLR2004", # Magic value used in comparison
65
+ "PLR0911", # Too many return statements
66
+ "PLR0912", # Too many branches
67
+ "PLR0913", # Too many arguments in a function definition
68
+ "PLR0917", # Too many positional arguments
69
+ "RUF012", # mutable-class-default
70
+ "PLR0915", # Too many statements
71
+ ]
72
+ select = [
73
+ "E", # pycodestyle
74
+ "F", # pyflakes
75
+ "YTT", # flake8-2020
76
+ "PL", # PL
77
+ "RUF", # Ruff-specific rules
78
+ "I001", # isort
79
+ ]
80
+ extend-select = [
81
+ "UP006", # Prefer builtin generics in annotations
82
+ "UP007", # Prefer | syntax for unions and optionals
83
+ ]
84
+
85
+ [tool.ruff.lint.pydocstyle]
86
+ convention = "numpy"
87
+
88
+ [tool.ruff.lint.isort]
89
+ # Use a single line between direct and from import
90
+ lines-between-types = 1
91
+
92
+ [tool.ruff.format]
93
+ quote-style = "double"
94
+
95
+ [tool.mypy]
96
+ python_version = "3.10"
97
+ check_untyped_defs = true
98
+ strict = true
99
+ ignore_missing_imports = true
100
+ warn_unused_ignores = true
101
+ warn_redundant_casts = true
102
+ warn_unused_configs = true
103
+ show_error_codes = true
104
+ exclude = ["scripts/"]
@@ -0,0 +1,43 @@
1
+ """
2
+ title: Top-level package for ArxPy.
3
+ """
4
+
5
+ from importlib import metadata as importlib_metadata
6
+
7
+ from arxpy.diagnostics import Diagnostic, DiagnosticSeverity
8
+ from arxpy.errors import (
9
+ ArxError,
10
+ CompileError,
11
+ ExecutionError,
12
+ ParseError,
13
+ )
14
+
15
+ _DISTRIBUTION_NAME = "arxpy"
16
+
17
+
18
+ def get_version() -> str:
19
+ """
20
+ title: Return the program version.
21
+ returns:
22
+ type: str
23
+ """
24
+ try:
25
+ return importlib_metadata.version(_DISTRIBUTION_NAME)
26
+ except importlib_metadata.PackageNotFoundError: # pragma: no cover
27
+ return "1.24.1" # semantic-release
28
+
29
+
30
+ __author__: str = "Ivan Ogasawara"
31
+ __email__: str = "ivan.ogasawara@gmail.com"
32
+ __version__: str = get_version()
33
+
34
+ __all__ = [
35
+ "ArxError",
36
+ "CompileError",
37
+ "Diagnostic",
38
+ "DiagnosticSeverity",
39
+ "ExecutionError",
40
+ "ParseError",
41
+ "__version__",
42
+ "get_version",
43
+ ]
@@ -0,0 +1,183 @@
1
+ """
2
+ title: Structured diagnostic records for the ArxPy public API.
3
+ summary: >-
4
+ Define the stable, frozen Diagnostic record and the DiagnosticSeverity enum
5
+ that ArxPy exposes to callers, plus the duck-typed helpers that translate
6
+ upstream irx structured diagnostics and arx parser exceptions into it. The
7
+ Diagnostic type strips the astx.AST node reference that irx records carry, so
8
+ external callers never see raw compiler internals. These modules never import
9
+ arx or irx at module load time, so importing arxpy.diagnostics stays free of
10
+ the LLVM toolchain.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from enum import Enum
17
+
18
+
19
+ class DiagnosticSeverity(Enum):
20
+ """
21
+ title: Severity level of a diagnostic.
22
+ """
23
+
24
+ ERROR = "error"
25
+ WARNING = "warning"
26
+ INFO = "info"
27
+ HINT = "hint"
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class Diagnostic:
32
+ """
33
+ title: One structured diagnostic exposed by the ArxPy API.
34
+ attributes:
35
+ severity:
36
+ type: DiagnosticSeverity
37
+ description: The severity level of the diagnostic.
38
+ message:
39
+ type: str
40
+ description: The human-readable diagnostic message.
41
+ filename:
42
+ type: str
43
+ description: Source attribution, or "<string>" / "<unknown>".
44
+ line:
45
+ type: int | None
46
+ description: One-based source line, when known.
47
+ column:
48
+ type: int | None
49
+ description: One-based source column, when known.
50
+ code:
51
+ type: str | None
52
+ description: Stable diagnostic code, e.g. "S001", when known.
53
+ """
54
+
55
+ severity: DiagnosticSeverity
56
+ message: str
57
+ filename: str
58
+ line: int | None
59
+ column: int | None
60
+ code: str | None = None
61
+
62
+
63
+ def _coerce_severity(value: object) -> DiagnosticSeverity:
64
+ """
65
+ title: Coerce an upstream severity value into a DiagnosticSeverity.
66
+ summary: >-
67
+ Current irx diagnostics expose severity as a plain string such as
68
+ "error"; enum-like values exposing `.value` are also handled.
69
+ Unrecognised values fall back to ERROR.
70
+ parameters:
71
+ value:
72
+ type: object
73
+ returns:
74
+ type: DiagnosticSeverity
75
+ """
76
+ if isinstance(value, DiagnosticSeverity):
77
+ return value
78
+ raw = getattr(value, "value", value)
79
+ try:
80
+ return DiagnosticSeverity(str(raw))
81
+ except ValueError:
82
+ return DiagnosticSeverity.ERROR
83
+
84
+
85
+ def _resolve_source(record: object) -> object | None:
86
+ """
87
+ title: Return the best-effort source location of an irx diagnostic.
88
+ parameters:
89
+ record:
90
+ type: object
91
+ returns:
92
+ type: object | None
93
+ """
94
+ resolver = getattr(record, "resolved_source", None)
95
+ if callable(resolver):
96
+ resolved: object = resolver()
97
+ return resolved
98
+ source: object = getattr(record, "source", None)
99
+ return source
100
+
101
+
102
+ def _resolve_module_key(record: object) -> str | None:
103
+ """
104
+ title: Return the best-effort module attribution of an irx diagnostic.
105
+ parameters:
106
+ record:
107
+ type: object
108
+ returns:
109
+ type: str | None
110
+ """
111
+ resolver = getattr(record, "resolved_module_key", None)
112
+ if callable(resolver):
113
+ module_key = resolver()
114
+ else:
115
+ module_key = getattr(record, "module_key", None)
116
+ return None if module_key is None else str(module_key)
117
+
118
+
119
+ def _from_irx(
120
+ record: object,
121
+ *,
122
+ filename: str | None = None,
123
+ ) -> Diagnostic:
124
+ """
125
+ title: Translate one irx structured diagnostic into an ArxPy Diagnostic.
126
+ summary: >-
127
+ Reads the upstream record by attribute so it accepts any irx.diagnostics
128
+ Diagnostic without importing irx, and discards the astx.AST node
129
+ reference. The current irx SourceLocation carries no filename, so the
130
+ attribution falls back to an explicit filename, then the diagnostic's
131
+ module key, then "<unknown>".
132
+ parameters:
133
+ record:
134
+ type: object
135
+ filename:
136
+ type: str | None
137
+ returns:
138
+ type: Diagnostic
139
+ """
140
+ source = _resolve_source(record)
141
+ code = getattr(record, "code", None)
142
+ attribution = filename or _resolve_module_key(record) or "<unknown>"
143
+ return Diagnostic(
144
+ severity=_coerce_severity(getattr(record, "severity", "error")),
145
+ message=str(getattr(record, "message", record)),
146
+ filename=attribution,
147
+ line=getattr(source, "line", None),
148
+ column=getattr(source, "col", None),
149
+ code=None if code is None else str(code),
150
+ )
151
+
152
+
153
+ def _from_parser_exception(
154
+ exc: object,
155
+ *,
156
+ filename: str = "<string>",
157
+ ) -> Diagnostic:
158
+ """
159
+ title: Translate an arx ParserException into an ArxPy Diagnostic.
160
+ summary: >-
161
+ ParserException.__init__ discards the offending token's location, so line
162
+ and column are None by design rather than fabricated.
163
+ parameters:
164
+ exc:
165
+ type: object
166
+ filename:
167
+ type: str
168
+ returns:
169
+ type: Diagnostic
170
+ """
171
+ return Diagnostic(
172
+ severity=DiagnosticSeverity.ERROR,
173
+ message=str(exc),
174
+ filename=filename,
175
+ line=None,
176
+ column=None,
177
+ )
178
+
179
+
180
+ __all__ = [
181
+ "Diagnostic",
182
+ "DiagnosticSeverity",
183
+ ]
@@ -0,0 +1,93 @@
1
+ """
2
+ title: Public exception hierarchy for the ArxPy API.
3
+ summary: >-
4
+ Define the single error hierarchy ArxPy raises to callers: ArxError as the
5
+ base, with ParseError, CompileError, and ExecutionError for the lex/parse,
6
+ analysis/lowering, and execution stages of the pipeline. Each error carries a
7
+ list of structured Diagnostic records so callers can inspect failures
8
+ programmatically instead of scraping message text. The pipeline modules catch
9
+ upstream arx and irx exceptions and re-raise them as these types, building
10
+ diagnostics via the helpers in arxpy.diagnostics.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from collections.abc import Sequence
16
+
17
+ from arxpy.diagnostics import Diagnostic
18
+
19
+
20
+ class ArxError(Exception):
21
+ """
22
+ title: Base class for every error raised by the ArxPy API.
23
+ attributes:
24
+ diagnostics:
25
+ type: list[Diagnostic]
26
+ description: Structured diagnostics describing the failure.
27
+ """
28
+
29
+ diagnostics: list[Diagnostic]
30
+
31
+ def __init__(
32
+ self,
33
+ message: str,
34
+ *,
35
+ diagnostics: Sequence[Diagnostic] | None = None,
36
+ ) -> None:
37
+ """
38
+ title: Initialize an ArxError.
39
+ parameters:
40
+ message:
41
+ type: str
42
+ diagnostics:
43
+ type: Sequence[Diagnostic] | None
44
+ """
45
+ self.diagnostics = list(diagnostics or ())
46
+ super().__init__(message)
47
+
48
+
49
+ class ParseError(ArxError):
50
+ """
51
+ title: Raised when lexing or parsing Arx source fails.
52
+ summary: >-
53
+ Parser-origin diagnostics have no line or column in v1 because
54
+ ParserException discards token location.
55
+ attributes:
56
+ diagnostics:
57
+ type: list[Diagnostic]
58
+ """
59
+
60
+
61
+ class CompileError(ArxError):
62
+ """
63
+ title: >-
64
+ Raised when semantic analysis, lowering, native compile, or linking
65
+ fails.
66
+ summary: >-
67
+ Carries the structured diagnostics from the irx error family, which
68
+ include source locations for most phases.
69
+ attributes:
70
+ diagnostics:
71
+ type: list[Diagnostic]
72
+ """
73
+
74
+
75
+ class ExecutionError(ArxError):
76
+ """
77
+ title: Raised when running a compiled Arx program fails to execute.
78
+ summary: >-
79
+ Reserved for failures that prevent execution from completing, such as a
80
+ missing binary or a timeout. A program that runs to completion with a
81
+ non-zero exit code is reported as data, not raised.
82
+ attributes:
83
+ diagnostics:
84
+ type: list[Diagnostic]
85
+ """
86
+
87
+
88
+ __all__ = [
89
+ "ArxError",
90
+ "CompileError",
91
+ "ExecutionError",
92
+ "ParseError",
93
+ ]
File without changes