Leverage dict comprehension in PEP-0274
PEP-0274 introduced dict comprehensions to replace dict constructor
with a sequence of key-pairs[1], these are two benefits:
- First, it makes the code look neater.
- Second, it gains a micro-optimization.
Glance dropped python 2.6 support in Kilo, we can leverage this now.
Note: This commit doesn't handle dict constructor with kwargs.
This commit also adds a hacking rule.
[1]http://legacy.python.org/dev/peps/pep-0274/
Co-Authored-By: ChangBo Guo(gcb) <eric.guo@easystack.cn>
Co-Authored-By: Kamil Rykowski <kamil.rykowski@intel.com>
Change-Id: I0ba408f9c616dcdb09618f6256db76b9facc0c1d
ChangBo Guo(gcb) authored 9 years ago
ChangBo Guo(gcb) committed 8 years ago
21 | 21 | - [G324] Validate that LOG.error messages use _LE. |
22 | 22 | - [G325] Validate that LOG.critical messages use _LC. |
23 | 23 | - [G326] Validate that LOG.warning messages use _LW. |
24 | - [G327] Prevent use of deprecated contextlib.nested⏎ | |
24 | - [G327] Prevent use of deprecated contextlib.nested | |
25 | - [G328] Must use a dict comprehension instead of a dict constructor with a sequence of key-value pairs |
412 | 412 | names and values |
413 | 413 | """ |
414 | 414 | to_str = encodeutils.safe_encode |
415 | return dict([(to_str(h), to_str(v)) for h, v in | |
416 | six.iteritems(headers)]) | |
415 | return {to_str(h): to_str(v) for h, v in six.iteritems(headers)} | |
417 | 416 | |
418 | 417 | @handle_redirects |
419 | 418 | def _do_request(self, method, url, body, headers): |
453 | 453 | tag_filters.extend([models.ImageTag.value == tag]) |
454 | 454 | tag_conditions.append(tag_filters) |
455 | 455 | |
456 | filters = dict([(k, v) for k, v in filters.items() if v is not None]) | |
456 | filters = {k: v for k, v in filters.items() if v is not None} | |
457 | 457 | |
458 | 458 | for (k, v) in filters.items(): |
459 | 459 | key = k |
54 | 54 | r"(.)*LOG\.(critical)\(\s*(_\(|'|\")") |
55 | 55 | log_translation_warning = re.compile( |
56 | 56 | r"(.)*LOG\.(warning)\(\s*(_\(|'|\")") |
57 | dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?(\(|\[)") | |
57 | 58 | |
58 | 59 | |
59 | 60 | def assert_true_instance(logical_line): |
147 | 148 | yield(0, msg) |
148 | 149 | |
149 | 150 | |
151 | def dict_constructor_with_list_copy(logical_line): | |
152 | msg = ("G328: Must use a dict comprehension instead of a dict constructor " | |
153 | "with a sequence of key-value pairs.") | |
154 | if dict_constructor_with_list_copy_re.match(logical_line): | |
155 | yield (0, msg) | |
156 | ||
157 | ||
150 | 158 | def factory(register): |
151 | 159 | register(assert_true_instance) |
152 | 160 | register(assert_equal_type) |
155 | 163 | register(no_direct_use_of_unicode_function) |
156 | 164 | register(validate_log_translations) |
157 | 165 | register(check_no_contextlib_nested) |
166 | register(dict_constructor_with_list_copy) |
82 | 82 | |
83 | 83 | |
84 | 84 | def dict_factory(cur, row): |
85 | return dict( | |
86 | ((col[0], row[idx]) for idx, col in enumerate(cur.description))) | |
85 | return {col[0]: row[idx] for idx, col in enumerate(cur.description)} | |
87 | 86 | |
88 | 87 | |
89 | 88 | class Driver(base.Driver): |
465 | 465 | try: |
466 | 466 | LOG.debug("Updating image %(id)s with metadata: %(image_data)r", |
467 | 467 | {'id': id, |
468 | 'image_data': dict((k, v) for k, v in image_data.items() | |
469 | if k != 'locations')}) | |
468 | 'image_data': {k: v for k, v in image_data.items() | |
469 | if k != 'locations'}}) | |
470 | 470 | image_data = _normalize_image_location_for_db(image_data) |
471 | 471 | if purge_props == "true": |
472 | 472 | purge_props = True |
531 | 531 | """ |
532 | 532 | |
533 | 533 | def _fetch_attrs(d, attrs): |
534 | return dict([(a, d[a]) for a in attrs | |
535 | if a in d.keys()]) | |
534 | return {a: d[a] for a in attrs if a in d.keys()} | |
536 | 535 | |
537 | 536 | # TODO(sirp): should this be a dict, or a list of dicts? |
538 | 537 | # A plain dict is more convenient, but list of dicts would provide |
539 | 538 | # access to created_at, etc |
540 | properties = dict((p['name'], p['value']) | |
541 | for p in image['properties'] if not p['deleted']) | |
539 | properties = {p['name']: p['value'] for p in image['properties'] | |
540 | if not p['deleted']} | |
542 | 541 | |
543 | 542 | image_dict = _fetch_attrs(image, glance.db.IMAGE_ATTRS) |
544 | 543 | image_dict['properties'] = properties |
355 | 355 | """ |
356 | 356 | |
357 | 357 | def _fetch_memb(memb, attr_map): |
358 | return dict([(k, memb[v]) | |
359 | for k, v in attr_map.items() if v in memb.keys()]) | |
358 | return {k: memb[v] for k, v in attr_map.items() if v in memb.keys()} | |
360 | 359 | |
361 | 360 | # Return the list of members with the given attribute mapping |
362 | 361 | return [_fetch_memb(memb, attr_map) for memb in members] |
286 | 286 | fixture = {'properties': {'ping': 'pong'}} |
287 | 287 | image = self.db_api.image_update(self.adm_context, UUID1, fixture) |
288 | 288 | expected = {'ping': 'pong', 'foo': 'bar', 'far': 'boo'} |
289 | actual = dict((p['name'], p['value']) for p in image['properties']) | |
289 | actual = {p['name']: p['value'] for p in image['properties']} | |
290 | 290 | self.assertEqual(expected, actual) |
291 | 291 | self.assertNotEqual(image['created_at'], image['updated_at']) |
292 | 292 | |
294 | 294 | fixture = {'properties': {'ping': 'pong'}} |
295 | 295 | image = self.db_api.image_update(self.adm_context, UUID1, |
296 | 296 | fixture, purge_props=True) |
297 | properties = dict((p['name'], p) for p in image['properties']) | |
297 | properties = {p['name']: p for p in image['properties']} | |
298 | 298 | |
299 | 299 | # New properties are set |
300 | 300 | self.assertTrue('ping' in properties) |
71 | 71 | |
72 | 72 | self.assertEqual(0, len(list(checks.check_no_contextlib_nested( |
73 | 73 | "with foo as bar")))) |
74 | ||
75 | def test_dict_constructor_with_list_copy(self): | |
76 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
77 | " dict([(i, connect_info[i])")))) | |
78 | ||
79 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
80 | " attrs = dict([(k, _from_json(v))")))) | |
81 | ||
82 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
83 | " type_names = dict((value, key) for key, value in")))) | |
84 | ||
85 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
86 | " dict((value, key) for key, value in")))) | |
87 | ||
88 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
89 | "foo(param=dict((k, v) for k, v in bar.items()))")))) | |
90 | ||
91 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
92 | " dict([[i,i] for i in range(3)])")))) | |
93 | ||
94 | self.assertEqual(1, len(list(checks.dict_constructor_with_list_copy( | |
95 | " dd = dict([i,i] for i in range(3))")))) | |
96 | ||
97 | self.assertEqual(0, len(list(checks.dict_constructor_with_list_copy( | |
98 | " create_kwargs = dict(snapshot=snapshot,")))) | |
99 | ||
100 | self.assertEqual(0, len(list(checks.dict_constructor_with_list_copy( | |
101 | " self._render_dict(xml, data_el, data.__dict__)")))) |
275 | 275 | return initial_values |
276 | 276 | |
277 | 277 | def _check_010(self, engine, data): |
278 | values = dict((c, u) for c, u in data) | |
278 | values = {c: u for c, u in data} | |
279 | 279 | |
280 | 280 | images = db_utils.get_table(engine, 'images') |
281 | 281 | for row in images.select().execute(): |
645 | 645 | def _check_019(self, engine, data): |
646 | 646 | image_locations = db_utils.get_table(engine, 'image_locations') |
647 | 647 | records = image_locations.select().execute().fetchall() |
648 | locations = dict([(il.image_id, il.value) for il in records]) | |
648 | locations = {il.image_id: il.value for il in records} | |
649 | 649 | self.assertEqual('http://glance.example.com', |
650 | 650 | locations.get('fake-19-1')) |
651 | 651 | |
936 | 936 | records = tasks_table.select().execute().fetchall() |
937 | 937 | self.assertEqual(2, len(records)) |
938 | 938 | |
939 | tasks = dict([(t.id, t) for t in records]) | |
939 | tasks = {t.id: t for t in records} | |
940 | 940 | |
941 | 941 | task_1 = tasks.get('task-1') |
942 | 942 | self.assertEqual('some input', task_1.input) |