@@ -32,10 +32,9 @@ def make_dot_wiz_plus(*args, **kwargs):
32
32
return DotWizPlus (kwargs )
33
33
34
34
35
- def __store_in_dot_wiz__ (self , key : str , value ,
36
- __dict ,
37
- __set = dict .__setitem__ ,
38
- __is_keyword = keyword .iskeyword ):
35
+ def __store_in_object__ (self , __self_dict , key , value ,
36
+ __set = dict .__setitem__ ,
37
+ __is_keyword = keyword .iskeyword ):
39
38
40
39
orig_key = key
41
40
lower_key = key .lower ()
@@ -57,9 +56,10 @@ def __store_in_dot_wiz__(self, key: str, value,
57
56
# transform key to `snake case` and cache the result.
58
57
key = snake (key )
59
58
60
- # I've noticed for keys like ' a.b.c' or a'b'c, the result isn't
59
+ # I've noticed for keys like ` a.b.c` or ` a'b'c` , the result isn't
61
60
# `a_b_c` as we'd want it to be. So for now, do the conversion
62
61
# ourselves.
62
+ # See also: https://github.com/kevinheavey/pyheck/issues/10
63
63
for ch in ('.' , '\' ' ):
64
64
if ch in key :
65
65
key = key .replace (ch , '_' ).replace ('__' , '_' )
@@ -76,14 +76,11 @@ def __store_in_dot_wiz__(self, key: str, value,
76
76
77
77
# note: this logic is the same as `DotWizPlus.__setitem__()`
78
78
__set (self , orig_key , value )
79
- __dict [key ] = value
79
+ __self_dict [key ] = value
80
80
81
81
82
82
# noinspection PyDefaultArgument
83
- def __upsert_into_dot_wiz_plus__ (self , input_dict = {},
84
- __set = dict .__setitem__ ,
85
- __is_keyword = keyword .iskeyword ,
86
- ** kwargs ):
83
+ def __upsert_into_dot_wiz_plus__ (self , input_dict = {}, ** kwargs ):
87
84
"""
88
85
Helper method to generate / update a :class:`DotWizPlus` (dot-access dict)
89
86
from a Python ``dict`` object, and optional *keyword arguments*.
@@ -112,28 +109,27 @@ def __upsert_into_dot_wiz_plus__(self, input_dict={},
112
109
elif t is list :
113
110
value = [__resolve_value__ (e , DotWizPlus ) for e in value ]
114
111
115
- __store_in_dot_wiz__ (self , key , value , __dict )
112
+ __store_in_object__ (self , __dict , key , value )
116
113
117
114
118
- def __setitem_impl__ (self , key , value ,
119
- __set = dict .__setitem__ ,
120
- __is_keyword = keyword .iskeyword ):
115
+ def __setitem_impl__ (self , key , value ):
121
116
"""Implementation of `DotWizPlus.__setitem__` to preserve dot access"""
122
117
value = __resolve_value__ (value , DotWizPlus )
123
- __store_in_dot_wiz__ (self , key , value , self . __dict__ )
118
+ __store_in_object__ (self , self . __dict__ , key , value )
124
119
125
120
126
121
class DotWizPlus (dict , metaclass = __add_repr__ , char = '✪' , use_attr_dict = True ):
122
+ # noinspection PyProtectedMember
127
123
"""
128
124
:class:`DotWizPlus` - a blazing *fast* ``dict`` subclass that also
129
- supports *dot access* notation.exit
130
-
131
- Usage::
125
+ supports *dot access* notation. This implementation enables you to
126
+ turn special-cased keys into valid *snake_case* words in Python,
127
+ as shown below.
132
128
133
129
>>> from dotwiz import DotWizPlus
134
130
>>> dw = DotWizPlus({'Key 1': [{'3D': {'with': 2}}], 'keyTwo': '5', '[email protected] ?': 3.21})
135
131
>>> dw
136
- DotWizPlus (key_1=[DotWizPlus (_3d=DotWizPlus (with_=2))], key_two='5', r_2_d_2=3.21)
132
+ ✪ (key_1=[✪ (_3d=✪ (with_=2))], key_two='5', r_2_d_2=3.21)
137
133
>>> assert dw.key_1[0]._3d.with_ == 2
138
134
>>> assert dw.key_two == '5'
139
135
>>> assert dw.r_2_d_2 == 3.21
@@ -142,6 +138,21 @@ class DotWizPlus(dict, metaclass=__add_repr__, char='✪', use_attr_dict=True):
142
138
>>> dw.to_attr_dict()
143
139
{'key_1': [{'_3d': {'with_': 2}}], 'key_two': '5', 'r_2_d_2': 3.21}
144
140
141
+ Issues with Invalid Characters
142
+ ******************************
143
+
144
+ A key name in the scope of the :class:`DotWizPlus` implementation must be
145
+ a valid, lower-cased *identifier* in python, and also not a reserved
146
+ *keyword* such as ``for`` or ``class``. In the case where your key name
147
+ does not conform, the library will mutate your key to a safe,
148
+ lower-cased format.
149
+
150
+ Spaces and invalid characters are replaced with ``_``. In the case
151
+ of a key beginning with an *int*, a leading ``_`` is added.
152
+ In the case of a *keyword*, a trailing ``_`` is added. Keys that appear
153
+ in different cases, such as ``myKey`` or ``My-Key``, will all be converted
154
+ to a *snake case* variant, ``my_key`` in this example.
155
+
145
156
"""
146
157
__slots__ = ('__dict__' , )
147
158
0 commit comments