Wemake-python-styleguide: Enforce `defaultdict` usage

Created on 19 Dec 2019  路  4Comments  路  Source: wemake-services/wemake-python-styleguide

Rule request

Thesis

Currently one can write this code:

d = {}

if "k" not in d:
    d["k"] = 6

d["k"] += 1

print(d["k"])  # 7

It is an anti-pattern.
One should instead use defaultdict:

from collections import defaultdict

d = defaultdict(lambda : 6)
d["k"] += 1

print(d["k"])  # 7

Related: https://docs.quantifiedcode.com/python-anti-patterns/correctness/not_using_defaultdict.html

This belong to refactoring group.

help wanted starter rule request

All 4 comments

Hi,
We (a group of students) would like to work on this issue. Can we take it ?

Sure! Thank you! Make sure to read our contributing guides

I am here to help: ask anything you need.

I'd like to clarify some requirements about what is a violation and what's not. I'm wondering if we should handle complicated cases or just simple ones similar to the above example.
We want to prevent a specific kind of dictionary initialization. Does this mean that there is a violation only when the initial dictionary is empty ? In this case what if the dictionary is intended to hold different types of values ?

Namely, are there any violations in the following code ?

d = {}

# Some code

if 'x' not in d:
    d['x'] = 0

if 'list' not in d:
    d['list'] = []
else:
    d['list'].append(42)

What about:

d = {i: 0 for i in range(10)}

d[0] += 1

if 42 not in d:
    d[42] = 0

d[42] += 1

which could be rewritten :

from collections import defaultdict

d = defaultdict(lambda: 0)

d[0] += 1

d[42] += 1

Ok, I am sorry. After thinking once again about this rule, we will have to close this issue unresolved. Here's why:

if "k" not in d:
    d["k"] = 6

Is a violation, right? But what if it is written as

if 0 not in d:
    d[0] = 6

Is it now a violation? Or do we work with list now? Ok, what about more complex case:

if k not in d:
    d[k] = 6

Can we be sure that d is a dict? Why not some custom object with __setitem__? Or a list? Or anything?

Sorry, but we need to know types to make this work. And we do not assume types in wps. Let's wait for typed-linter to solve this.

Feel free to choose any other issue. This one seems interesting: https://github.com/wemake-services/wemake-python-styleguide/issues/1172

Was this page helpful?
0 / 5 - 0 ratings