@@ -20,17 +20,20 @@ def _merge_options(self, options):
20
20
self ._options = options
21
21
22
22
assert self ._options .get ("separator" , "dot" ) in [
23
- "dot" , "bracket" , "mixed" ]
23
+ "dot" , "bracket" , "mixed" , "mixed-dot" ]
24
24
assert isinstance (self ._options .get ("raise_duplicate" , False ), bool )
25
25
assert isinstance (self ._options .get ("assign_duplicate" , False ), bool )
26
26
27
27
self .__is_dot = False
28
28
self .__is_mixed = False
29
29
self .__is_bracket = False
30
+ self .__is_mixed_dot = False
30
31
if self ._options ["separator" ] == "dot" :
31
32
self .__is_dot = True
32
33
elif self ._options ["separator" ] == "mixed" :
33
34
self .__is_mixed = True
35
+ elif self ._options ["separator" ] == "mixed-dot" :
36
+ self .__is_mixed_dot = True
34
37
else :
35
38
self .__is_bracket = True
36
39
self ._reg = re .compile (r"\[|\]" )
@@ -54,13 +57,9 @@ def span(key, i):
54
57
key = key [idx :]
55
58
56
59
i = 0
60
+ last_is_list = False
57
61
while i < len (key ):
58
- if key [i ] == '.' :
59
- i += 1
60
- idx = span (key , i )
61
- keys .append (key [i : idx ])
62
- i = idx
63
- elif key [i ] == '[' :
62
+ if key [i ] == '[' :
64
63
i += 1
65
64
idx = span (key , i )
66
65
if key [idx ] != ']' :
@@ -72,9 +71,22 @@ def span(key, i):
72
71
f"invalid format key '{ full_keys } ', list key is not a valid number at position { i + pos } " )
73
72
keys .append (int (key [i : idx ]))
74
73
i = idx + 1
74
+ last_is_list = True
75
75
elif key [i ] == ']' :
76
76
raise ValueError (
77
77
f"invalid format key '{ full_keys } ', not start with bracket at position { i + pos } " )
78
+ elif (key [i ] == '.' and self .__is_mixed_dot ) or (
79
+ not self .__is_mixed_dot and (
80
+ (key [i ] != '.' and last_is_list ) or
81
+ (key [i ] == '.' and not last_is_list )
82
+ )
83
+ ):
84
+ if self .__is_mixed_dot or not last_is_list :
85
+ i += 1
86
+ idx = span (key , i )
87
+ keys .append (key [i : idx ])
88
+ i = idx
89
+ last_is_list = False
78
90
else :
79
91
raise ValueError (
80
92
f"invalid format key '{ full_keys } ', invalid char at position { i + pos } " )
@@ -90,7 +102,7 @@ def split_key(self, key):
90
102
# reduce + filter are a hight cost so do manualy with for loop
91
103
92
104
# optimize by split with string func
93
- if self .__is_mixed :
105
+ if self .__is_mixed or self . __is_mixed_dot :
94
106
return self .mixed_split (key )
95
107
if self .__is_dot :
96
108
length = 1
@@ -133,7 +145,7 @@ def set_type(self, dtc, key, value, full_keys, prev=None, last=False):
133
145
return key
134
146
135
147
def get_next_type (self , key ):
136
- if self .__is_mixed :
148
+ if self .__is_mixed or self . __is_mixed_dot :
137
149
return [] if isinstance (key , int ) else {}
138
150
return [] if key .isdigit () else {}
139
151
0 commit comments