temparse 0.0.1__tar.gz → 0.0.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: temparse
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: temparse is template + parse
5
5
  Author: jiang-zhexin
6
6
  Author-email: jiang-zhexin <162887873+jiang-zhexin@users.noreply.github.com>
@@ -52,18 +52,23 @@ The return type is `tuple[str, int]`.
52
52
 
53
53
  ## Supported Types
54
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` |
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
+ | `{list}` | `'[1,2,3]'` | `[1, 2, 3]` |
64
+ | `{dict}` | `'{"a":1}'` | `{"a": 1}` |
65
+ | `{json}` | `'{"a":1}'` | `{"a": 1}` |
66
+ | `{datetime.datetime:%d/%m/%y %H:%M:%S}` | `"31/01/22 23:59:59"` | `datetime` |
67
+ | `{datetime.date:%Y-%m-%d}` | `"2024-03-15"` | `date` |
68
+ | `{datetime.time:%H:%M:%S}` | `"13:23:27"` | `time` |
69
+
70
+ > [!IMPORTANT]
71
+ > list and dict are just aliases for json.
67
72
 
68
73
  ## Custom Conversions
69
74
 
@@ -74,12 +79,12 @@ from temparse import Conversion, parse
74
79
 
75
80
 
76
81
  @Conversion
77
- def upper(s: str) -> str:
78
- return s.upper()
82
+ def percent(s: str) -> float:
83
+ return float(s.rstrip("%")) / 100
79
84
 
80
85
 
81
- (result,) = parse[str](t"{upper}", "hello")
82
- assert result == "HELLO"
86
+ (result,) = parse[float](t"x = {percent}", "x = 30%")
87
+ assert result == 0.3
83
88
  ```
84
89
 
85
90
  When your converter needs the format spec as well, use `FormatConversion`:
@@ -36,18 +36,23 @@ The return type is `tuple[str, int]`.
36
36
 
37
37
  ## Supported Types
38
38
 
39
- | Interpolation | Example | Output |
40
- | --------------------------------------- | ------------------------ | -------------------- |
41
- | `{str}` | `"hello"` | `"hello"` |
42
- | `{int}` | `"42"` | `42` |
43
- | `{int}` | `"0xff"` | `255` |
44
- | `{int:16}` | `"ff"` | `255` |
45
- | `{float}` | `"3.14"` | `3.14` |
46
- | `{complex}` | `"-1.23+4.5j"` | `-1.23+4.5j` |
47
- | `{json}` | `'[1,2,3]'`, `'{"a":1}'` | `[1,2,3]`, `{"a":1}` |
48
- | `{datetime.datetime:%d/%m/%y %H:%M:%S}` | `"31/01/22 23:59:59"` | `datetime` |
49
- | `{datetime.date:%Y-%m-%d}` | `"2024-03-15"` | `date` |
50
- | `{datetime.time:%H:%M:%S}` | `"13:23:27"` | `time` |
39
+ | Interpolation | Example | Output |
40
+ | --------------------------------------- | --------------------- | ------------ |
41
+ | `{str}` | `"hello"` | `"hello"` |
42
+ | `{int}` | `"42"` | `42` |
43
+ | `{int}` | `"0xff"` | `255` |
44
+ | `{int:16}` | `"ff"` | `255` |
45
+ | `{float}` | `"3.14"` | `3.14` |
46
+ | `{complex}` | `"-1.23+4.5j"` | `-1.23+4.5j` |
47
+ | `{list}` | `'[1,2,3]'` | `[1, 2, 3]` |
48
+ | `{dict}` | `'{"a":1}'` | `{"a": 1}` |
49
+ | `{json}` | `'{"a":1}'` | `{"a": 1}` |
50
+ | `{datetime.datetime:%d/%m/%y %H:%M:%S}` | `"31/01/22 23:59:59"` | `datetime` |
51
+ | `{datetime.date:%Y-%m-%d}` | `"2024-03-15"` | `date` |
52
+ | `{datetime.time:%H:%M:%S}` | `"13:23:27"` | `time` |
53
+
54
+ > [!IMPORTANT]
55
+ > list and dict are just aliases for json.
51
56
 
52
57
  ## Custom Conversions
53
58
 
@@ -58,12 +63,12 @@ from temparse import Conversion, parse
58
63
 
59
64
 
60
65
  @Conversion
61
- def upper(s: str) -> str:
62
- return s.upper()
66
+ def percent(s: str) -> float:
67
+ return float(s.rstrip("%")) / 100
63
68
 
64
69
 
65
- (result,) = parse[str](t"{upper}", "hello")
66
- assert result == "HELLO"
70
+ (result,) = parse[float](t"x = {percent}", "x = 30%")
71
+ assert result == 0.3
67
72
  ```
68
73
 
69
74
  When your converter needs the format spec as well, use `FormatConversion`:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "temparse"
3
- version = "0.0.1"
3
+ version = "0.0.2"
4
4
  license = "MIT"
5
5
  requires-python = ">=3.14"
6
6
  readme = "README.md"
@@ -5,7 +5,7 @@ import logging
5
5
  import re
6
6
  from collections.abc import Callable
7
7
  from string.templatelib import Interpolation, Template
8
- from typing import Any
8
+ from typing import Any, get_origin, is_typeddict
9
9
 
10
10
  __all__ = ["Conversion", "FormatConversion", "Parser", "parse"]
11
11
 
@@ -13,7 +13,18 @@ log = logging.getLogger(__name__)
13
13
 
14
14
 
15
15
  class Parser[*T]:
16
- def __init__(self, template: Template):
16
+ """
17
+ A compiled template parser that can be reused to parse multiple strings.
18
+
19
+ example:
20
+ ```python
21
+ parser = Parser[str, int, float](t"{str} + {int} = {float}")
22
+
23
+ parser.parse("foo + 3 = 3.14")
24
+ ```
25
+ """
26
+
27
+ def __init__(self, template: Template) -> None:
17
28
  self.template = template
18
29
  self.expression = f"^{
19
30
  ''.join(
@@ -38,19 +49,46 @@ class Parser[*T]:
38
49
 
39
50
  class parse[*T]:
40
51
  """
41
- Used to replace this function until [PEP 718](https://peps.python.org/pep-0718/) is accepted.
52
+ Parse string by template.
42
53
 
54
+ example:
43
55
  ```python
44
- def parse[*T](t: Template, s: str) -> tuple[*T]:
45
- return Parser(t).parse(s)
56
+ city, year = parse[str, int](
57
+ t"I live in {str}, since {int}", "I live in Tokyo, since 2010"
58
+ )
59
+ assert city == "Tokyo"
60
+ assert year == 2010
46
61
  ```
47
62
  """
48
63
 
49
64
  def __new__(cls, t: Template, s: str) -> tuple[*T]:
65
+ """
66
+ Used to replace this function until [PEP 718](https://peps.python.org/pep-0718/) is accepted.
67
+
68
+ ```python
69
+ def parse[*T](t: Template, s: str) -> tuple[*T]:
70
+ return Parser(t).parse(s)
71
+ ```
72
+ """
50
73
  return Parser(t).parse(s)
51
74
 
52
75
 
53
76
  class Conversion[T]:
77
+ """
78
+ Convert the string to your object.
79
+
80
+ example:
81
+ ```python
82
+ @Conversion
83
+ def percent(s: str) -> float:
84
+ return float(s.rstrip("%")) / 100
85
+
86
+
87
+ (result,) = parse[float](t"x = {percent}", "x = 30%")
88
+ assert result == 0.3
89
+ ```
90
+ """
91
+
54
92
  __name__: str
55
93
  __qualname__: str
56
94
 
@@ -63,6 +101,21 @@ class Conversion[T]:
63
101
 
64
102
 
65
103
  class FormatConversion[T]:
104
+ """
105
+ Convert the string to your object with format.
106
+
107
+ example:
108
+ ```python
109
+ @FormatConversion
110
+ def between(s: str, spec: str) -> str:
111
+ lo, hi = spec.split(",")
112
+ return s[int(lo) : int(hi)]
113
+
114
+ (result,) = parse[str](t"{between:2,5}", "abcdefg")
115
+ assert result == "cde"
116
+ ```
117
+ """
118
+
66
119
  __name__: str
67
120
  __qualname__: str
68
121
 
@@ -75,7 +128,8 @@ class FormatConversion[T]:
75
128
 
76
129
 
77
130
  def _convert(s: str, i: Interpolation[Any]) -> Any:
78
- match i.value:
131
+ origin = get_origin(i.value) or i.value
132
+ match origin:
79
133
  case Conversion():
80
134
  return i.value(s)
81
135
 
@@ -91,19 +145,21 @@ def _convert(s: str, i: Interpolation[Any]) -> Any:
91
145
  case datetime.time:
92
146
  return datetime.time.strptime(s, i.format_spec)
93
147
 
94
- case _ if i.value is int:
148
+ case _ if origin is int:
95
149
  return int(s, base=int(i.format_spec) if i.format_spec else 0)
96
150
 
97
- case _ if i.value is float:
151
+ case _ if origin is float:
98
152
  return float(s)
99
153
 
100
- case _ if i.value is complex:
154
+ case _ if origin is complex:
101
155
  return complex(s)
102
156
 
103
- case _ if i.value is str:
157
+ case _ if origin is str:
104
158
  return s
105
159
 
106
- case _ if i.value is json:
160
+ case _ if (
161
+ origin is list or origin is dict or origin is json or is_typeddict(origin)
162
+ ):
107
163
  return json.loads(s)
108
164
 
109
165
  case _:
File without changes