Skip to content

Conversation

@Pierre-Sassoulas
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas commented Nov 1, 2025

Type of Changes

Type
βœ“ πŸ› Bug fix

Description

Closes #10711

@Pierre-Sassoulas Pierre-Sassoulas added this to the 4.0.3 milestone Nov 1, 2025
@Pierre-Sassoulas Pierre-Sassoulas added False Positive 🦟 A message is emitted but nothing is wrong with the code backport maintenance/4.0.x labels Nov 1, 2025
@Pierre-Sassoulas
Copy link
Member Author

Do you have any thoughts on the expected messages Jacob ?


@dataclass
class Class:
class_snake_case_constant: Final[int] = 42 # [invalid-name]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should not raise [invalid-name], because Final attributes can still be re-assigned a new value that is different from the default value in __init__(). Final only protects the value after the instance is created.

Final is like const in C/C++. UPPER_CASE is like the marco which gets expanded during static interpretation of the code.

So UPPER_CASE is more immutable than Final.

So marking a dataclass attribute Final is not the sufficient condition for UPPER_CASE.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss that somewhere else. I don't want to make Final more special than it already is. The only thing we grok about Final is ...

@dataclass
class Class:
class_snake_case_constant: Final[int] = 42 # [invalid-name]
CLASS_UPPER_CASE_CONSTANT: Final[int] = 42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be OK. Stacking them together should not raise any [invalid-name].

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... right here. (I agree with you)

Everything else in this file should be like Final doesn't even exist.

@dataclass
class Class:
class_snake_case_constant: Final[int] = 42 # [invalid-name]
CLASS_UPPER_CASE_CONSTANT: Final[int] = 42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding a just UPPER_CASE attribute test case like:

CLASS_UPPER_CASE_ATTRIBUTE: int = 42

This line should not raise [invalid-name] here, because UPPER_CASE can be used alone to identify a static constant.

But later on if it gets re-assigned new value in the below method, then [invalid-name] should be raised there to ask for snake_case because it is no longer a constant.

CLASS_UPPER_CASE_CONSTANT: Final[int] = 42

def method(self) -> None:
method_snake_case_constant: Final[int] = 42 # [invalid-name]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding a test case for

self.CLASS_UPPER_CASE_ATTRIBUTE = 36 # [invalid-name]

Because this attribute is named with UPPER_CASE letters, it should not be re-assigned a new value by any means. If it is re-assigned a new value, we can safely raise [invalid-name] on the spot and asking for snake_case names instead.

@jacobtylerwalls
Copy link
Member

I'll aim to take a look this week at fixing this.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 7, 2025

πŸ€– According to the primer, this change has no effect on the checked open source code. πŸ€–πŸŽ‰

This comment was generated for commit 5fc003c

@codecov
Copy link

codecov bot commented Nov 7, 2025

Codecov Report

βœ… All modified and coverable lines are covered by tests.
βœ… Project coverage is 95.97%. Comparing base (f8f6ccd) to head (5fc003c).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main   #10712   +/-   ##
=======================================
  Coverage   95.97%   95.97%           
=======================================
  Files         176      176           
  Lines       19537    19537           
=======================================
  Hits        18750    18750           
  Misses        787      787           
Files with missing lines Coverage Ξ”
pylint/checkers/base/name_checker/checker.py 98.76% <100.00%> (ΓΈ)
πŸš€ New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Pierre-Sassoulas Pierre-Sassoulas merged commit 133681e into main Nov 8, 2025
44 checks passed
@Pierre-Sassoulas Pierre-Sassoulas deleted the fix-10711 branch November 8, 2025 08:15
pylint-backport bot pushed a commit that referenced this pull request Nov 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport maintenance/4.0.x C: invalid-name False Positive 🦟 A message is emitted but nothing is wrong with the code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pylint C0103 (invalid-name) contradiction for class-level typing.Final attributes.

4 participants