type-python 0.1.1__py3-none-win_amd64.whl → 0.2.0__py3-none-win_amd64.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: type-python
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: A statically-typed authoring language that compiles to standard Python
5
5
  Author: unadlib
6
6
  License-Expression: MIT
@@ -0,0 +1,11 @@
1
+ type_python-0.2.0.dist-info/licenses/LICENSE,sha256=BMHUZ3id_LOrEdv_GmAbL1ttlKsqjZz14f1_M1tn73k,1089
2
+ typepython/__init__.py,sha256=kCK2IS4kVa6N1RsNikfR1sn_tnZ-v_RkAvNCmqMnYgA,308
3
+ typepython/__main__.py,sha256=m8cggQyLAOSPtb8r-uUv_g53whMoPXtF2NX9yLuPyLg,89
4
+ typepython/_runner.py,sha256=DySWPTud0FIAv2-0xhmwAyt_kk3w3kFJWK8FcYSe858,1777
5
+ typepython/annotation_compat.py,sha256=VKUJEAj9NdDWr1j5cB2OIWlupmDyWVYvQkpJ2Jer2m8,4223
6
+ typepython/bin/typepython.exe,sha256=nVmVjeYOX1bMA_nZbP5M82hlMpsmEaN-G-XnBtQRYKE,11372544
7
+ type_python-0.2.0.dist-info/METADATA,sha256=Qn5P8Hw8w6N-1sX8H__xcIip6rlFRG2DymiaLI-wDnI,3930
8
+ type_python-0.2.0.dist-info/WHEEL,sha256=GjDPPQwEcripVP6P2r3RxLa-h5Lb9ifGB7FYYtbLDT0,98
9
+ type_python-0.2.0.dist-info/entry_points.txt,sha256=B5Yjdi-RWaeRy7YUcni1lU_ya2lVZXM8llSFNSKEq0U,56
10
+ type_python-0.2.0.dist-info/top_level.txt,sha256=JFRFjt3AXvRQ99SKMxUVu9e3TOp2QpspvE-jk85uMjU,11
11
+ type_python-0.2.0.dist-info/RECORD,,
typepython/__init__.py CHANGED
@@ -1,5 +1,13 @@
1
1
  from ._runner import main
2
+ from .annotation_compat import AnnotationFormat, AnnotationSupport, get_annotations, supported_formats
2
3
 
3
- __all__ = ["__version__", "main"]
4
+ __all__ = [
5
+ "__version__",
6
+ "AnnotationFormat",
7
+ "AnnotationSupport",
8
+ "get_annotations",
9
+ "main",
10
+ "supported_formats",
11
+ ]
4
12
 
5
- __version__ = "0.1.1"
13
+ __version__ = "0.2.0"
@@ -0,0 +1,142 @@
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ import sys
5
+ from dataclasses import dataclass
6
+ from enum import Enum
7
+ from types import ModuleType
8
+ from typing import Any
9
+
10
+ try:
11
+ import annotationlib as _annotationlib
12
+ except ImportError: # pragma: no cover - exercised on pre-3.14 hosts
13
+ _annotationlib = None
14
+
15
+ HAS_ANNOTATIONLIB = _annotationlib is not None
16
+
17
+
18
+ class AnnotationFormat(str, Enum):
19
+ VALUE = "value"
20
+ FORWARDREF = "forwardref"
21
+ STRING = "string"
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class AnnotationSupport:
26
+ value: bool
27
+ forwardref: bool
28
+ string: bool
29
+
30
+
31
+ def supported_formats() -> AnnotationSupport:
32
+ if HAS_ANNOTATIONLIB:
33
+ return AnnotationSupport(value=True, forwardref=True, string=True)
34
+ return AnnotationSupport(value=True, forwardref=False, string=False)
35
+
36
+
37
+ def get_annotations(
38
+ obj: Any,
39
+ *,
40
+ globals: dict[str, Any] | None = None,
41
+ locals: dict[str, Any] | None = None,
42
+ eval_str: bool = False,
43
+ format: AnnotationFormat | str = AnnotationFormat.VALUE,
44
+ ) -> dict[str, Any]:
45
+ normalized = _normalize_format(format)
46
+ if HAS_ANNOTATIONLIB:
47
+ return _annotationlib.get_annotations(
48
+ obj,
49
+ globals=globals,
50
+ locals=locals,
51
+ eval_str=eval_str,
52
+ format=_annotationlib_format(normalized),
53
+ )
54
+ if normalized is not AnnotationFormat.VALUE:
55
+ raise NotImplementedError(
56
+ "annotation formats other than VALUE require Python 3.14+ annotationlib"
57
+ )
58
+ return _fallback_get_annotations(
59
+ obj,
60
+ globals=globals,
61
+ locals=locals,
62
+ eval_str=eval_str,
63
+ )
64
+
65
+
66
+ def _normalize_format(format: AnnotationFormat | str) -> AnnotationFormat:
67
+ if isinstance(format, AnnotationFormat):
68
+ return format
69
+ return AnnotationFormat(format)
70
+
71
+
72
+ def _annotationlib_format(format: AnnotationFormat) -> Any:
73
+ assert _annotationlib is not None
74
+ if format is AnnotationFormat.VALUE:
75
+ return _annotationlib.Format.VALUE
76
+ if format is AnnotationFormat.FORWARDREF:
77
+ return _annotationlib.Format.FORWARDREF
78
+ return _annotationlib.Format.STRING
79
+
80
+
81
+ def _fallback_get_annotations(
82
+ obj: Any,
83
+ *,
84
+ globals: dict[str, Any] | None,
85
+ locals: dict[str, Any] | None,
86
+ eval_str: bool,
87
+ ) -> dict[str, Any]:
88
+ if hasattr(inspect, "get_annotations"):
89
+ return inspect.get_annotations(
90
+ obj,
91
+ globals=globals,
92
+ locals=locals,
93
+ eval_str=eval_str,
94
+ )
95
+
96
+ raw = _legacy_raw_annotations(obj)
97
+ if raw is None:
98
+ return {}
99
+ annotations = dict(raw)
100
+ if not eval_str:
101
+ return annotations
102
+
103
+ globalns, localns = _legacy_eval_namespaces(obj, globals, locals)
104
+ evaluated: dict[str, Any] = {}
105
+ for name, value in annotations.items():
106
+ if isinstance(value, str):
107
+ evaluated[name] = eval(value, globalns, localns)
108
+ else:
109
+ evaluated[name] = value
110
+ return evaluated
111
+
112
+
113
+ def _legacy_raw_annotations(obj: Any) -> dict[str, Any] | None:
114
+ if isinstance(obj, type):
115
+ return obj.__dict__.get("__annotations__")
116
+ if isinstance(obj, ModuleType):
117
+ return getattr(obj, "__annotations__", None)
118
+ return getattr(obj, "__annotations__", None)
119
+
120
+
121
+ def _legacy_eval_namespaces(
122
+ obj: Any,
123
+ globals: dict[str, Any] | None,
124
+ locals: dict[str, Any] | None,
125
+ ) -> tuple[dict[str, Any], dict[str, Any]]:
126
+ if globals is not None or locals is not None:
127
+ return globals or {}, locals or globals or {}
128
+
129
+ if isinstance(obj, ModuleType):
130
+ namespace = vars(obj)
131
+ return namespace, namespace
132
+ if isinstance(obj, type):
133
+ module = sys.modules.get(getattr(obj, "__module__", ""))
134
+ globalns = vars(module) if module is not None else {}
135
+ return globalns, dict(vars(obj))
136
+
137
+ globalns = getattr(obj, "__globals__", None)
138
+ if globalns is not None:
139
+ return globalns, globalns
140
+ module = sys.modules.get(getattr(obj, "__module__", ""))
141
+ namespace = vars(module) if module is not None else {}
142
+ return namespace, namespace
Binary file
@@ -1,10 +0,0 @@
1
- type_python-0.1.1.dist-info/licenses/LICENSE,sha256=BMHUZ3id_LOrEdv_GmAbL1ttlKsqjZz14f1_M1tn73k,1089
2
- typepython/__init__.py,sha256=NUOU0aHfeQ0sJOQ9yDxz7NUqrOUpkzSNOMvQWFWRgtg,89
3
- typepython/__main__.py,sha256=m8cggQyLAOSPtb8r-uUv_g53whMoPXtF2NX9yLuPyLg,89
4
- typepython/_runner.py,sha256=DySWPTud0FIAv2-0xhmwAyt_kk3w3kFJWK8FcYSe858,1777
5
- typepython/bin/typepython.exe,sha256=iAUB49_o9uEKjhnfZuxiu5BeZghI8VVMDAcysevnOh0,11033088
6
- type_python-0.1.1.dist-info/METADATA,sha256=EtMZV3WeDxhBZtB5ydwyn1xm3MtYMZ7iSmnWlwFtAo4,3930
7
- type_python-0.1.1.dist-info/WHEEL,sha256=GjDPPQwEcripVP6P2r3RxLa-h5Lb9ifGB7FYYtbLDT0,98
8
- type_python-0.1.1.dist-info/entry_points.txt,sha256=B5Yjdi-RWaeRy7YUcni1lU_ya2lVZXM8llSFNSKEq0U,56
9
- type_python-0.1.1.dist-info/top_level.txt,sha256=JFRFjt3AXvRQ99SKMxUVu9e3TOp2QpspvE-jk85uMjU,11
10
- type_python-0.1.1.dist-info/RECORD,,