Skip to content

Commit df450ae

Browse files
committed
Minor fixes
1 parent a087e88 commit df450ae

File tree

4 files changed

+27
-56
lines changed

4 files changed

+27
-56
lines changed

sde/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
)
1414

1515
from .sde import main
16-
# We intentially import for export here, so it is ok to silence DeepSource test
16+
# We intentionally import for export here, so it is ok to silence DeepSource test
1717
# skipcq: PY-W2000
1818
from .sde import edit_file, normalize_val, read_file
1919

sde/collection.py

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
import six
88
import yaml
9-
from six import add_metaclass, string_types as basestring, iteritems
9+
from six import add_metaclass, string_types, iteritems
10+
1011

1112
# this was only introduced in six 1.13.0, but it's too old in RHEL,
1213
# and we don't want to rebuild its package
@@ -16,7 +17,7 @@
1617
else:
1718
import collections.abc as collections_abc
1819

19-
SPLIT_REGEX = r"(?<!\\)(\.)"
20+
SPLIT_REGEX = re.compile(r"(?<!\\)(\.)")
2021

2122

2223
def is_dotted_key(key):
@@ -25,20 +26,20 @@ def is_dotted_key(key):
2526

2627

2728
def split_key(key, max_keys=0):
28-
"""Splits a key but allows dots in the key name if they're scaped properly.
29+
"""Splits a key but allows dots in the key name if they're escaped properly.
2930
3031
Splitting this complex key:
3132
32-
complex_key = r".dont\.splitme.d\.o\. origen.splitme\.dontsplit.splitme."
33+
complex_key = r'.dont\\\\.splitme.d\\\\.o\\\\. origen.splitme\\\\.dontsplit.splitme.'
3334
split_key(complex_key)
3435
3536
results in:
3637
37-
['', r'dont\.splitme', r'd\.o\. origen', r'splitme\.dontsplit', 'splitme', '']
38+
['', r'dont\\\\.splitme', r'd\\\\.o\\\\. origen', r'splitme\\\\.dontsplit', 'splitme', '']
3839
3940
4041
Args:
41-
key (basestring): The key to be splitted.
42+
key (str): The key to be split.
4243
max_keys (int): The maximum number of keys to be extracted. 0 means no
4344
limits.
4445
@@ -48,7 +49,7 @@ def split_key(key, max_keys=0):
4849
parts = [x for x in re.split(SPLIT_REGEX, key) if x != "."]
4950
result = []
5051
while len(parts) > 0:
51-
if max_keys > 0 and len(result) == max_keys:
52+
if 0 < max_keys == len(result):
5253
break
5354
result.append(parts.pop(0))
5455

@@ -61,7 +62,6 @@ def split_key(key, max_keys=0):
6162
class DottedCollection(object):
6263
"""Abstract Base Class for DottedDict and DottedDict"""
6364

64-
6565
@classmethod
6666
def factory(cls, initial=None):
6767
"""Returns a DottedDict or a DottedList based on the type of the
@@ -74,21 +74,19 @@ def factory(cls, initial=None):
7474
return DottedDict(initial)
7575
return initial
7676

77-
7877
@classmethod
7978
def load_json(cls, json_value):
8079
"""Returns a DottedCollection from a JSON string"""
8180
return cls.factory(json.loads(json_value))
8281

83-
8482
@classmethod
8583
def _factory_by_index(cls, dotted_key):
8684
"""Returns the proper DottedCollection that best suits the next key in
8785
the dotted_key string. First guesses the next key and then analyzes it.
8886
If the next key is numeric then returns a DottedList. In other case a
8987
DottedDict is returned.
9088
"""
91-
if not isinstance(dotted_key, basestring):
89+
if not isinstance(dotted_key, string_types):
9290
next_key = str(dotted_key)
9391
elif not is_dotted_key(dotted_key):
9492
next_key = dotted_key
@@ -97,7 +95,6 @@ def _factory_by_index(cls, dotted_key):
9795

9896
return DottedCollection.factory([] if next_key.isdigit() else {})
9997

100-
10198
def __init__(self, initial):
10299
"""Base constructor. If there are nested dicts or lists they are
103100
transformed into DottedCollection instances.
@@ -120,7 +117,6 @@ def __init__(self, initial):
120117
except ValueError:
121118
pass
122119

123-
124120
def _validate_initial(self, initial):
125121
"""Validates data so no unescaped dotted key is present."""
126122
if isinstance(initial, list):
@@ -133,42 +129,33 @@ def _validate_initial(self, initial):
133129
"DottedCollection!".format(key))
134130
self._validate_initial(item)
135131

136-
137132
def __len__(self):
138133
return len(self.store)
139134

140-
141135
def __iter__(self):
142136
return iter(self.store)
143137

144-
145138
def __repr__(self):
146139
return repr(self.store)
147140

148-
149141
def to_json(self):
150142
return json.dumps(self, cls=DottedJSONEncoder, indent=4)
151143

152-
153144
def to_yaml(self):
154145
return yaml.dump(self, Dumper=DottedYAMLDumper)
155146

156-
157147
@abstractmethod
158148
def __getitem__(self, name):
159149
raise NotImplementedError
160150

161-
162151
@abstractmethod
163152
def __setitem__(self, name, value):
164153
raise NotImplementedError
165154

166-
167155
@abstractmethod
168156
def __delitem__(self, name):
169157
raise NotImplementedError
170158

171-
172159
@abstractmethod
173160
def to_python(self):
174161
raise NotImplementedError
@@ -177,23 +164,21 @@ def to_python(self):
177164
class DottedList(DottedCollection, collections_abc.MutableSequence):
178165
"""A list with support for the dotted path syntax"""
179166

180-
181167
def __init__(self, initial=None):
182168
DottedCollection.__init__(
183169
self,
184170
[] if initial is None else list(initial)
185171
)
186172

187-
188173
def __getitem__(self, index):
189174
if isinstance(index, slice):
190175
return self.store[index]
191176

192177
if isinstance(index, int) \
193-
or (isinstance(index, basestring) and index.isdigit()):
178+
or (isinstance(index, string_types) and index.isdigit()):
194179
return self.store[int(index)]
195180

196-
if isinstance(index, basestring) and is_dotted_key(index):
181+
if isinstance(index, string_types) and is_dotted_key(index):
197182
my_index, alt_index = split_key(index, 1)
198183
target = self.store[int(my_index)]
199184

@@ -209,19 +194,18 @@ def __getitem__(self, index):
209194

210195
raise IndexError('cannot get %s in %s' % (index, repr(self.store)))
211196

212-
213197
def __setitem__(self, index, value):
214198
if isinstance(index, int) \
215-
or (isinstance(index, basestring) and index.isdigit()):
216-
# If the index does not exist in the list but it's the same index
199+
or (isinstance(index, string_types) and index.isdigit()):
200+
# If the index does not exist in the list, but it's the same index
217201
# we would obtain by appending the value to the list we actually
218202
# append the value. (***)
219203
if int(index) not in self.store and int(index) == len(self.store):
220204
self.store.append(DottedCollection.factory(value))
221205
else:
222206
self.store[int(index)] = DottedCollection.factory(value)
223207

224-
elif isinstance(index, basestring) and is_dotted_key(index):
208+
elif isinstance(index, string_types) and is_dotted_key(index):
225209
my_index, alt_index = split_key(index, 1)
226210

227211
# (***)
@@ -240,13 +224,12 @@ def __setitem__(self, index, value):
240224
raise IndexError('cannot use %s as index in %s' % (
241225
index, repr(self.store)))
242226

243-
244227
def __delitem__(self, index):
245228
if isinstance(index, int) \
246-
or (isinstance(index, basestring) and index.isdigit()):
229+
or (isinstance(index, string_types) and index.isdigit()):
247230
del self.store[int(index)]
248231

249-
elif isinstance(index, basestring) and is_dotted_key(index):
232+
elif isinstance(index, string_types) and is_dotted_key(index):
250233
my_index, alt_index = split_key(index, 1)
251234
target = self.store[int(my_index)]
252235

@@ -261,7 +244,6 @@ def __delitem__(self, index):
261244
raise IndexError('cannot delete %s in %s' % (
262245
index, repr(self.store)))
263246

264-
265247
def to_python(self):
266248
"""Returns a plain python list and converts to plain python objects all
267249
this object's descendants.
@@ -274,26 +256,23 @@ def to_python(self):
274256

275257
return result
276258

277-
278259
def insert(self, index, value):
279260
self.store.insert(index, value)
280261

281262

282263
class DottedDict(DottedCollection, collections_abc.MutableMapping):
283264
"""A dict with support for the dotted path syntax"""
284265

285-
286266
def __init__(self, initial=None):
287267
DottedCollection.__init__(
288268
self,
289269
{} if initial is None else dict(initial)
290270
)
291271

292-
293272
def __getitem__(self, k):
294273
key = self.__keytransform__(k)
295274

296-
if not isinstance(k, basestring) or not is_dotted_key(key):
275+
if not isinstance(k, string_types) or not is_dotted_key(key):
297276
return self.store[key]
298277

299278
my_key, alt_key = split_key(key, 1)
@@ -309,11 +288,10 @@ def __getitem__(self, k):
309288

310289
return target[alt_key]
311290

312-
313291
def __setitem__(self, k, value):
314292
key = self.__keytransform__(k)
315293

316-
if not isinstance(k, basestring):
294+
if not isinstance(k, string_types):
317295
raise KeyError('DottedDict keys must be str or unicode')
318296
if not is_dotted_key(key):
319297
self.store[key] = DottedCollection.factory(value)
@@ -325,11 +303,10 @@ def __setitem__(self, k, value):
325303

326304
self.store[my_key][alt_key] = value
327305

328-
329306
def __delitem__(self, k):
330307
key = self.__keytransform__(k)
331308

332-
if not isinstance(k, basestring) or not is_dotted_key(key):
309+
if not isinstance(k, string_types) or not is_dotted_key(key):
333310
del self.store[key]
334311

335312
else:
@@ -345,7 +322,6 @@ def __delitem__(self, k):
345322

346323
del target[alt_key]
347324

348-
349325
def to_python(self):
350326
"""Returns a plain python dict and converts to plain python objects all
351327
this object's descendants.
@@ -358,10 +334,8 @@ def to_python(self):
358334

359335
return result
360336

361-
362337
__getattr__ = __getitem__
363338

364-
365339
# self.store does not exist before __init__() initializes it
366340

367341
def __setattr__(self, key, value):
@@ -370,18 +344,16 @@ def __setattr__(self, key, value):
370344
else:
371345
self.__setitem__(key, value)
372346

373-
374347
def __delattr__(self, key):
375348
if key in self.__dict__ or key == 'store':
376349
object.__delattr__(self, key)
377350
else:
378351
self.__delitem__(key)
379352

380-
381353
def __contains__(self, k):
382354
key = self.__keytransform__(k)
383355

384-
if not isinstance(k, basestring) or not is_dotted_key(key):
356+
if not isinstance(k, string_types) or not is_dotted_key(key):
385357
return self.store.__contains__(key)
386358

387359
my_key, alt_key = split_key(key, 1)
@@ -392,8 +364,8 @@ def __contains__(self, k):
392364

393365
return alt_key in target
394366

395-
396-
def __keytransform__(self, key):
367+
@staticmethod
368+
def __keytransform__(key):
397369
return key
398370

399371

@@ -420,9 +392,9 @@ class DottedYAMLDumper(yaml.Dumper):
420392
421393
dumper.add_representer(DottedDict, lambda dumper, data: data.store)
422394
423-
but we'd have to do it for each type.
395+
But we'd have to do it for each type.
424396
425-
This suggests making a custom dumper for a hiearchy of types:
397+
This suggests making a custom dumper for a hierarchy of types:
426398
https://github.com/yaml/pyyaml/issues/51
427399
"""
428400

sde/sde.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
def edit_file(key, value, file, fmt, must_exist=False):
2626
data = DottedDict(read_file(file, fmt))
2727
try:
28-
# this is the way I found it works for array vals too
28+
# This is the way I found it works for array vals too
2929
# e.g. fruits.0.name
3030
if data[key] == value and type(data[key]) == type(value):
3131
# prevents writing to the file is value is matching already

tests/test_sde.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ def test_yaml_edit():
4242
edit_file('age', normalize_val('31'), file, 'YAML')
4343
edit_file('balance', normalize_val('0'), file, 'YAML')
4444

45-
4645
with open(file) as yaml_file:
4746
data = yaml.safe_load(yaml_file)
4847
assert data['age'] == 31
@@ -114,4 +113,4 @@ def test_cli_json():
114113

115114
data = read_file(file, 'JSON')
116115

117-
assert data['extra']['registered'] == 'true'
116+
assert data['extra']['registered'] == 'true'

0 commit comments

Comments
 (0)