str-to-obj 2024.6__py3-none-any.whl → 2024.8__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.
@@ -8,7 +8,7 @@ import dataclasses as d
8
8
  import typing as h
9
9
  from enum import Enum as enum_t
10
10
 
11
- from logger_36.format import FormattedMessage
11
+ from logger_36.content import FormattedMessage
12
12
  from str_to_obj.type.annotation import annotation_t
13
13
  from str_to_obj.type.hint import annotated_hint_t
14
14
 
@@ -7,32 +7,34 @@ SEE COPYRIGHT NOTICE BELOW
7
7
  import dataclasses as d
8
8
  import typing as h
9
9
 
10
- from logger_36 import LOGGER
11
10
  from str_to_obj.type.annotation import annotation_t
12
11
  from str_to_obj.type.hint import annotated_hint_t
13
12
 
14
13
 
15
14
  @d.dataclass(slots=True, repr=False, eq=False)
16
15
  class choices_t(annotation_t):
17
- ACCEPTED_TYPES: h.ClassVar[tuple[type, ...]] = (str,)
16
+ ACCEPTED_TYPES: h.ClassVar[tuple[type, ...]] = (h.Any,)
18
17
 
19
- options: h.Sequence[str]
20
-
21
- def __post_init__(self) -> None:
22
- """"""
23
- with LOGGER.AddedContextLevel("Choices Annotation"):
24
- for option in self.options:
25
- if not isinstance(option, str):
26
- LOGGER.StageIssue(
27
- f'Invalid type of option "{option}"',
28
- actual=type(option).__name__,
29
- expected="str",
30
- )
18
+ options: h.Sequence[h.Any]
31
19
 
32
20
  @classmethod
33
- def NewAnnotatedType(cls, options: h.Sequence[str], /) -> annotated_hint_t:
34
- """"""
35
- return h.Annotated[str, cls(tuple(options))]
21
+ def NewAnnotatedType(cls, options: h.Sequence, /) -> annotated_hint_t:
22
+ """
23
+ Note: options hint cannot be h.Sequence | h.Literal since h.Literal cannot be
24
+ used alone, although a value of type h.Literal[...] can be passed as options.
25
+ """
26
+ if h.get_origin(options) is h.Literal:
27
+ options = h.get_args(options)
28
+ else:
29
+ options = tuple(options)
30
+
31
+ stripes = tuple(set(type(_elm) for _elm in options))
32
+ if stripes.__len__() > 1:
33
+ stripe = h.Union[stripes]
34
+ else:
35
+ stripe = stripes[0]
36
+
37
+ return h.Annotated[stripe, cls(options=options)]
36
38
 
37
39
  def ValueIssues(self, value: str | h.Any, /) -> list[str]:
38
40
  """"""
str_to_obj/main.py CHANGED
@@ -29,15 +29,26 @@ def ObjectFromStr(
29
29
  issues = [f'{string}: Invalid value; Expected="NONE" or "None" or "none".']
30
30
  return None, issues
31
31
 
32
+ value = _ObjectFromStr(string)
33
+
34
+ if expected_type is None:
35
+ return value, []
36
+
37
+ return CastValue(value, expected_type)
38
+
39
+
40
+ def _ObjectFromStr(string:str, /)-> h.Any:
41
+ """"""
32
42
  try:
33
43
  value = bstr.literal_eval(string)
34
44
  except (SyntaxError, ValueError):
35
45
  value = string
36
46
 
37
- if expected_type is None:
38
- return value, []
47
+ if isinstance(value, h.Sequence) and not isinstance(value, str):
48
+ stripe = type(value)
49
+ value = stripe(_ObjectFromStr(_elm) for _elm in value)
39
50
 
40
- return CastValue(value, expected_type)
51
+ return value
41
52
 
42
53
 
43
54
  """
@@ -9,7 +9,8 @@ import re as regx
9
9
  import types as t
10
10
  import typing as h
11
11
 
12
- from logger_36.format import FormattedMessage
12
+ from logger_36.content import FormattedMessage
13
+ from str_to_obj.catalog.choices import choices_t
13
14
  from str_to_obj.task.inspection import HintComponents
14
15
  from str_to_obj.type.annotation import annotation_t
15
16
  from str_to_obj.type.hint import (
@@ -24,15 +25,22 @@ from str_to_obj.type.hint import (
24
25
  class _hint_node_t:
25
26
  """
26
27
  Leave elements to the tree.
28
+ literal_s: the accepted (literal) values if the hint is a typing.Literal, None
29
+ otherwise.
27
30
  """
28
31
 
29
32
  type: non_complex_hint_h | t.UnionType | t.EllipsisType | type[t.NoneType]
30
33
  annotations: tuple[annotation_t, ...] = d.field(default_factory=tuple)
34
+ literal_s: tuple[h.Any, ...] | None = None
31
35
 
32
36
 
33
37
  @d.dataclass(slots=True, repr=False, eq=False)
34
38
  class hint_t(_hint_node_t):
35
- elements: tuple[h.Self, ...] = None
39
+ """
40
+ elements: tuple if the hint is a container, None otherwise. In terms of tree
41
+ structure, it plays the role of the (hint) node children.
42
+ """
43
+ elements: tuple[h.Self, ...] | None = None
36
44
 
37
45
  @classmethod
38
46
  def NewForHint(cls, hint: any_hint_h | complex_hint_additions_h, /) -> h.Self:
@@ -51,7 +59,7 @@ class hint_t(_hint_node_t):
51
59
  )
52
60
  )
53
61
 
54
- # Dealing with complex_hint_additions_h first
62
+ # Dealing with complex_hint_additions_h first.
55
63
  if hint is Ellipsis:
56
64
  return cls(type=t.EllipsisType)
57
65
  if (hint is None) or (hint is t.NoneType):
@@ -67,6 +75,25 @@ class hint_t(_hint_node_t):
67
75
  if origin is dict:
68
76
  raise TypeError(f"Unhandled type: {origin.__name__}.")
69
77
 
78
+ if origin is h.Literal:
79
+ literal_s = h.get_args(raw_hint)
80
+ if any(isinstance(_elm, choices_t) for _elm in nnts):
81
+ raise ValueError(
82
+ f"Literal hint with values {literal_s} "
83
+ f"must not be annotated with {choices_t.__name__} as it leads to "
84
+ f"either redundancy or mismatch."
85
+ )
86
+ stripes = tuple(set(type(_elm) for _elm in literal_s))
87
+ if stripes.__len__() > 1:
88
+ origin = t.UnionType
89
+ elements = tuple(cls.NewForHint(_elm) for _elm in stripes)
90
+ else:
91
+ origin = stripes[0]
92
+ elements = None
93
+ return cls(
94
+ type=origin, annotations=nnts, elements=elements, literal_s=literal_s
95
+ )
96
+
70
97
  if origin is h.Union:
71
98
  origin = t.UnionType
72
99
  # get_args returns NoneType for None. This must be taken into account above.
str_to_obj/version.py CHANGED
@@ -4,7 +4,7 @@ Contributor(s): Eric Debreuve (eric.debreuve@cnrs.fr) since 2023
4
4
  SEE COPYRIGHT NOTICE BELOW
5
5
  """
6
6
 
7
- __version__ = "2024.6"
7
+ __version__ = "2024.8"
8
8
 
9
9
 
10
10
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: str-to-obj
3
- Version: 2024.6
3
+ Version: 2024.8
4
4
  Summary: Convert strings to Python objects guided by (potentially annotated) type hints
5
5
  Home-page: https://src.koda.cnrs.fr/eric.debreuve/str-to-obj/
6
6
  Author: Eric Debreuve
@@ -1,11 +1,11 @@
1
1
  str_to_obj/__init__.py,sha256=PCxTXaZiI5pN2HqQPeS4q6r-QgwBrDGwGplHCWACQzA,2318
2
- str_to_obj/main.py,sha256=ebOat0qc3CQPGXC6RCOLGswDrGuobAziwSCawv6rSK4,3102
3
- str_to_obj/version.py,sha256=LBCw-ZZUoX13xuS_ZDbgVb5pOKJrbeI-M12p4irxEbU,2206
2
+ str_to_obj/main.py,sha256=07IFp92qZnSnrcFEq0nNWlo8V45mSQDB6YMvQEMko9k,3373
3
+ str_to_obj/version.py,sha256=xwo0Wv924lKKmKIvZH1FxskJ5o1fdTg-Dkcb0mGGY6Y,2206
4
4
  str_to_obj/api/catalog.py,sha256=6ka6JciGdHFP93lg0yq2LO3iZBHfq0upZfXxQSg1izk,2521
5
5
  str_to_obj/api/type.py,sha256=yxD5wTtnh_h8Wa9_k1eex-nrkjtfh4ZJI6Db6hJHI9w,2468
6
- str_to_obj/catalog/boolean.py,sha256=7F0E36wQGkOxMMolqN5JF4zWOBJHLU9NDwOPt-LiFjQ,3489
6
+ str_to_obj/catalog/boolean.py,sha256=mcVR7KIZbHdtDCo3CZsVenurf8_EweKOoiiA9RR-jUI,3490
7
7
  str_to_obj/catalog/callable.py,sha256=NCoogYzVBUSqiYEj_DoG-szqQdnYhvSj0xdyvg1W7Jw,3626
8
- str_to_obj/catalog/choices.py,sha256=YvRkgThmUhGVOl-SeNXrVC5Gwg9shCDdU0-dJ9Zk_zw,3798
8
+ str_to_obj/catalog/choices.py,sha256=eZp_id2gWxgnzw7_RVEgy01s86c0Ci4MbRFZsRJMjJ8,3855
9
9
  str_to_obj/catalog/collection.py,sha256=OkwsgiMFrdvIvLqp1e_bgjBix677knrCSo-vOes86pQ,6767
10
10
  str_to_obj/catalog/number.py,sha256=U__ZF9TYMuIlIyY1QHIK2f89cPPCvmrNMhK3sCA7n0E,5461
11
11
  str_to_obj/catalog/path.py,sha256=xBrQJ-RMH-y_oaWP-uUTSpIKcL2vrtXoqrSaaS4HRpg,3857
@@ -17,10 +17,10 @@ str_to_obj/task/comparison.py,sha256=HBzv7gBtOnROsC6Sq-FYpgd_MKzVJreboNiqkza3vJ8
17
17
  str_to_obj/task/inspection.py,sha256=M8YnYq4A_Zz7rC2kgTYSSSawTnG2dCug5FBoCOBJ5g8,3127
18
18
  str_to_obj/type/annotation.py,sha256=xXShME2Q344N3QlsqKtU6ttne54tTVC3b62CHU1TGUM,3838
19
19
  str_to_obj/type/hint.py,sha256=w-yos8eD4CHQsXPfnqeqAc-ozyDWqzw46FOWDtAh7dM,2810
20
- str_to_obj/type/hint_tree.py,sha256=hm0JbEXc5lPl0djiBj0tksmfmZaeFtpo_qtZv1uXe7s,6690
20
+ str_to_obj/type/hint_tree.py,sha256=rvd2VgjdBIs-Cu6QPCR5ZhTsjZRYsXwA1skBSwybcxQ,7877
21
21
  str_to_obj/type/type.py,sha256=ywc7GpzM1BsoQ3F0qk4wZ2DG1KZllw-PNv_umIGt8hA,4147
22
22
  str_to_obj/type/value.py,sha256=r9Ko5HHant1JGbsO7vH1unRBr9guc61Jz2piuJT0BjM,2533
23
- str_to_obj-2024.6.dist-info/METADATA,sha256=uHOtXMI95EtKqHF57ML92wyg_GC6P_pepvKWKCYqWsE,6464
24
- str_to_obj-2024.6.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
25
- str_to_obj-2024.6.dist-info/top_level.txt,sha256=h-6bR_TAnXRGVSLTeNPlivlaG64xYM3E__Xg7sCgeug,11
26
- str_to_obj-2024.6.dist-info/RECORD,,
23
+ str_to_obj-2024.8.dist-info/METADATA,sha256=21-QD-PAqlAZ_OY2WuaG5wiVIIuws6LtMXMhza5pWkg,6464
24
+ str_to_obj-2024.8.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
25
+ str_to_obj-2024.8.dist-info/top_level.txt,sha256=h-6bR_TAnXRGVSLTeNPlivlaG64xYM3E__Xg7sCgeug,11
26
+ str_to_obj-2024.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.2.0)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5