Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce defaultdict usage #1084

Closed
sobolevn opened this issue Dec 19, 2019 · 4 comments
Closed

Enforce defaultdict usage #1084

sobolevn opened this issue Dec 19, 2019 · 4 comments
Assignees
Labels
help wanted Extra attention is needed level:starter Good for newcomers rule request Adding a new rule

Comments

@sobolevn
Copy link
Member

sobolevn commented Dec 19, 2019

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.

@sobolevn sobolevn added help wanted Extra attention is needed level:starter Good for newcomers rule request Adding a new rule labels Dec 19, 2019
@sobolevn sobolevn added this to the Version 0.15 milestone Dec 19, 2019
@adambenali
Copy link
Contributor

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

@sobolevn
Copy link
Member Author

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

I am here to help: ask anything you need.

@adambenali
Copy link
Contributor

adambenali commented Feb 25, 2020

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

@sobolevn
Copy link
Member Author

sobolevn commented Feb 26, 2020

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: #1172

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed level:starter Good for newcomers rule request Adding a new rule
Projects
None yet
Development

No branches or pull requests

2 participants