temparse 0.0.1__py3-none-any.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.
temparse/__init__.py ADDED
@@ -0,0 +1,110 @@
1
+ import datetime
2
+ import functools
3
+ import json
4
+ import logging
5
+ import re
6
+ from collections.abc import Callable
7
+ from string.templatelib import Interpolation, Template
8
+ from typing import Any
9
+
10
+ __all__ = ["Conversion", "FormatConversion", "Parser", "parse"]
11
+
12
+ log = logging.getLogger(__name__)
13
+
14
+
15
+ class Parser[*T]:
16
+ def __init__(self, template: Template):
17
+ self.template = template
18
+ self.expression = f"^{
19
+ ''.join(
20
+ re.escape(item) if isinstance(item, str) else r'(.+?)'
21
+ for item in template
22
+ )
23
+ }$"
24
+ log.debug(f"match expression: {self.expression!r}")
25
+
26
+ self._match_re = re.compile(self.expression)
27
+
28
+ def parse(self, s: str) -> tuple[*T]:
29
+ m = self._match_re.match(s)
30
+ if m is None:
31
+ raise ValueError(f"Invalid format: {s!r}")
32
+
33
+ return tuple(
34
+ _convert(text, interpolation)
35
+ for text, interpolation in zip(m.groups(), self.template.interpolations)
36
+ )
37
+
38
+
39
+ class parse[*T]:
40
+ """
41
+ Used to replace this function until [PEP 718](https://peps.python.org/pep-0718/) is accepted.
42
+
43
+ ```python
44
+ def parse[*T](t: Template, s: str) -> tuple[*T]:
45
+ return Parser(t).parse(s)
46
+ ```
47
+ """
48
+
49
+ def __new__(cls, t: Template, s: str) -> tuple[*T]:
50
+ return Parser(t).parse(s)
51
+
52
+
53
+ class Conversion[T]:
54
+ __name__: str
55
+ __qualname__: str
56
+
57
+ def __init__(self, func: Callable[[str], T]) -> None:
58
+ self._convert = func
59
+ functools.update_wrapper(self, func)
60
+
61
+ def __call__(self, s: str) -> T:
62
+ return self._convert(s)
63
+
64
+
65
+ class FormatConversion[T]:
66
+ __name__: str
67
+ __qualname__: str
68
+
69
+ def __init__(self, func: Callable[[str, str], T]) -> None:
70
+ self._convert = func
71
+ functools.update_wrapper(self, func)
72
+
73
+ def __call__(self, s: str, format: str) -> T:
74
+ return self._convert(s, format)
75
+
76
+
77
+ def _convert(s: str, i: Interpolation[Any]) -> Any:
78
+ match i.value:
79
+ case Conversion():
80
+ return i.value(s)
81
+
82
+ case FormatConversion():
83
+ return i.value(s, i.format_spec)
84
+
85
+ case datetime.datetime:
86
+ return datetime.datetime.strptime(s, i.format_spec).astimezone(datetime.UTC)
87
+
88
+ case datetime.date:
89
+ return datetime.date.strptime(s, i.format_spec)
90
+
91
+ case datetime.time:
92
+ return datetime.time.strptime(s, i.format_spec)
93
+
94
+ case _ if i.value is int:
95
+ return int(s, base=int(i.format_spec) if i.format_spec else 0)
96
+
97
+ case _ if i.value is float:
98
+ return float(s)
99
+
100
+ case _ if i.value is complex:
101
+ return complex(s)
102
+
103
+ case _ if i.value is str:
104
+ return s
105
+
106
+ case _ if i.value is json:
107
+ return json.loads(s)
108
+
109
+ case _:
110
+ raise TypeError(f"unkown object: {i.value}")
temparse/py.typed ADDED
File without changes
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: temparse
3
+ Version: 0.0.1
4
+ Summary: temparse is template + parse
5
+ Author: jiang-zhexin
6
+ Author-email: jiang-zhexin <162887873+jiang-zhexin@users.noreply.github.com>
7
+ License-Expression: MIT
8
+ Classifier: Environment :: Web Environment
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Topic :: Software Development :: Code Generators
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Requires-Python: >=3.14
14
+ Project-URL: homepage, https://github.com/jiang-zhexin/temparse
15
+ Description-Content-Type: text/markdown
16
+
17
+ # temparse
18
+
19
+ **temparse = template + parse**, parse strings using t-string templates.
20
+
21
+ Inspired by [parse](https://github.com/r1chardj0n3s/parse), but built on Python
22
+ 3.14's [t-strings](https://peps.python.org/pep-0750/), with better type hints.
23
+
24
+ ## Installation
25
+
26
+ ### uv
27
+
28
+ ```bash
29
+ uv add temparse
30
+ ```
31
+
32
+ ### pip
33
+
34
+ ```bash
35
+ # Requires Python >= 3.14.
36
+ pip install temparse
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ```python
42
+ from temparse import parse
43
+
44
+ city, year = parse[str, int](
45
+ t"I live in {str}, since {int}", "I live in Tokyo, since 2010"
46
+ )
47
+ assert city == "Tokyo"
48
+ assert year == 2010
49
+ ```
50
+
51
+ The return type is `tuple[str, int]`.
52
+
53
+ ## Supported Types
54
+
55
+ | Interpolation | Example | Output |
56
+ | --------------------------------------- | ------------------------ | -------------------- |
57
+ | `{str}` | `"hello"` | `"hello"` |
58
+ | `{int}` | `"42"` | `42` |
59
+ | `{int}` | `"0xff"` | `255` |
60
+ | `{int:16}` | `"ff"` | `255` |
61
+ | `{float}` | `"3.14"` | `3.14` |
62
+ | `{complex}` | `"-1.23+4.5j"` | `-1.23+4.5j` |
63
+ | `{json}` | `'[1,2,3]'`, `'{"a":1}'` | `[1,2,3]`, `{"a":1}` |
64
+ | `{datetime.datetime:%d/%m/%y %H:%M:%S}` | `"31/01/22 23:59:59"` | `datetime` |
65
+ | `{datetime.date:%Y-%m-%d}` | `"2024-03-15"` | `date` |
66
+ | `{datetime.time:%H:%M:%S}` | `"13:23:27"` | `time` |
67
+
68
+ ## Custom Conversions
69
+
70
+ Decorate a function with `@Conversion` to use it directly in a template:
71
+
72
+ ```python
73
+ from temparse import Conversion, parse
74
+
75
+
76
+ @Conversion
77
+ def upper(s: str) -> str:
78
+ return s.upper()
79
+
80
+
81
+ (result,) = parse[str](t"{upper}", "hello")
82
+ assert result == "HELLO"
83
+ ```
84
+
85
+ When your converter needs the format spec as well, use `FormatConversion`:
86
+
87
+ ```python
88
+ from temparse import FormatConversion, parse
89
+
90
+
91
+ @FormatConversion
92
+ def between(s: str, spec: str) -> str:
93
+ lo, hi = spec.split(",")
94
+ return s[int(lo) : int(hi)]
95
+
96
+
97
+ (result,) = parse[str](t"{between:2,5}", "abcdefg")
98
+ assert result == "cde"
99
+ ```
100
+
101
+ ## `Parser` (Compiled Templates)
102
+
103
+ Build a parser once and reuse it:
104
+
105
+ ```python
106
+ from temparse import Parser
107
+
108
+ parser = Parser[str, int, float](t"{str} + {int} = {float}")
109
+
110
+ assert parser.parse("foo + 3 = 3.14") == ("foo", 3, 3.14)
111
+ assert parser.parse("bar + 7 = 2.72") == ("bar", 7, 2.72)
112
+ ```
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,5 @@
1
+ temparse/__init__.py,sha256=CjLr0CIDsQAQlvswMT41KlX0IPhCLCLQXEzx_WFGDks,2958
2
+ temparse/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ temparse-0.0.1.dist-info/WHEEL,sha256=Q9FtwzuR2QE37l-JIkuyklGnJJiCBHKnsPVQ9vzCMzQ,81
4
+ temparse-0.0.1.dist-info/METADATA,sha256=kQaH9M5WkFX0eBYDz2EH8xop_w9bQBJDh-uiR_NnLQA,3292
5
+ temparse-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.11.17
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any