PyCQA / PyCQA/flake8-bugbear

Feature request: a rule for detecting calls to mutate all-caps "constants"

Open
#423 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.1k
Forks
123
Avg merge
2d 5h
Merged PRs (30d)
5

Description

In various languages, ALL_CAPS variable names are conventionally used to denote constants. Pre-python 3.8's final property, there is no standard solution for denoting constants, so in some instances the developers' intentions are only conveyed through this naming convention.

However, due to the lack of enforcement of this constant property pre-python 3.8, a class of bugs can occur when mutable objects are used for these "constants", such that mutating functions can be used without warning. The following shows just one such bug possible in this situation:

>>> TEST = {"entry1": [1]} # represents a "CONSTANT"
>>> my_channels1 = TEST.get("entry1", []) # get entry1 reference
>>> print(my_channels1)
[1]
>>> my_channels1.append(2) # adds a channel to the TEST value
>>> my_channels2 = TEST.get("entry1", []) # grabs the same reference
>>> print(my_channels2)
[1, 2]
>>> print(TEST) # TEST was modified! This is the bug we want to catch
{'entry1': [1, 2]}
>>> TEST2 = {"entry1": [1]} # Let's try again
>>> my_channels2 = TEST2.get("entry1", [])
>>> print(my_channels2)
[1]
>>> my_channels = list(set(my_channels2 + [2]))  # Let's make a new local variable
>>> print(my_channels)
[1, 2]
>>> print(TEST2) # TEST2 was NOT modified
{'entry1': [1]}

We'd like to warn developers that if they intend to create a constant, identified by this ALL_CAPS naming convention, they should make the value immutable (e.g. tuple, frozenset, MappingProxyType, Final). This can teach developers to use these tools at the right time (but is not a substitute for onboarding/docs material, as this convention is easy to not adhere to).

Specification proposal

If:

  • a variable is named in all-capital letters (excluding symbols/numbers)
  • AND the variable is assigned to a mutable object type

Then the new rule should:

  • raise an error, suggesting that that the object type should be immutable OR the variable should be renamed to not all-caps

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the repository's existing rule entry points and tests, then compare their handling of all-caps assignments and mutable object types with this specification. Done means the rule detects the stated pattern and reports a suggestion to use an immutable type or rename the variable, with coverage for the proposed cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.