Skip to content

Conversation

@joao-faria-dev
Copy link

Description

Fixes a false positive where module-level constants were incorrectly classified as variables when a class-level attribute with the same name exists. I added a scope check so now when we check for reassignments, we make sure we only look at nodes within the same scope

Closes #10719

@joao-faria-dev joao-faria-dev force-pushed the fix-c0103-module-class-name-conflict branch 2 times, most recently from 1a5cff6 to 178bdc8 Compare November 6, 2025 17:52
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

Great first PR, thank you. Could you add a functional test in tests/functional to check it automatically, please ?

@joao-faria-dev
Copy link
Author

joao-faria-dev commented Nov 6, 2025

Thanks for the review @Pierre-Sassoulas, just added it!

@github-actions

This comment has been minimized.

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

Made a suggestion to match the example from the issue, let me know what you think. Changed Input to input, maybe it was the reason for the second invalid-name (shouldn't have been pascal case ?)

@@ -0,0 +1,8 @@
"""Test module-level constants with class attribute same name"""
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"""Test module-level constants with class attribute same name"""
"""Test module-level constants with class attribute same name
Regression test for #10719.
"""

Comment on lines 7 to 8
class MyClass:
MY_CONST = 10
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
class MyClass:
MY_CONST = 10
class MyClass:
MY_CONST = 10
class Theme:
INPUT = ">>> "
INPUT = Theme()
input = Theme()
OUTPUT = Theme()
output = Theme()

@@ -0,0 +1,3 @@
Fixed false positive for ``invalid-name`` (C0103) where module-level constants were incorrectly classified as variables when a class-level attribute with the same name exists.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Fixed false positive for ``invalid-name`` (C0103) where module-level constants were incorrectly classified as variables when a class-level attribute with the same name exists.
Fixed false positive for ``invalid-name`` where module-level constants were incorrectly classified as variables when a class-level attribute with the same name exists.

(The reason is that we're going to change this to ``:ref: ìnvalid-name``` when we can handle it automatically in the changelog later, and this will print the (C0103) automatically, so less work later on.)

Copy link
Author

@joao-faria-dev joao-faria-dev Nov 6, 2025

Choose a reason for hiding this comment

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

Thanks! Comments applied

…ames

- Add scope comparision to avoid module-level constants to be incorrectly
classified as variables when a class-level attribute with the same name exists

Closes pylint-dev#10719
@joao-faria-dev joao-faria-dev force-pushed the fix-c0103-module-class-name-conflict branch from 8f658a3 to 6459607 Compare November 6, 2025 19:48
@github-actions
Copy link
Contributor

github-actions bot commented Nov 8, 2025

🤖 Effect of this PR on checked open source code: 🤖

Effect on ansible:
The following messages are now emitted:

  1. invalid-name:
    Constant name "current_worker" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/executor/process/worker.py#L52
  2. invalid-name:
    Constant name "cur_id" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/utils/vars.py#L39
  3. invalid-name:
    Constant name "UnixHTTPSHandler" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/module_utils/urls.py#L222
  4. invalid-name:
    Constant name "UnixHTTPSConnection" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/module_utils/urls.py#L223
  5. invalid-name:
    Constant name "_module_tracebacks_enabled_events" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/module_utils/_internal/_traceback.py#L68
  6. invalid-name:
    Constant name "module" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/modules/file.py#L244
  7. invalid-name:
    Constant name "apt_key_bin" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/modules/apt_key.py#L181
  8. invalid-name:
    Constant name "gpg_bin" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/modules/apt_key.py#L182
  9. invalid-name:
    Constant name "locale" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/modules/apt_key.py#L183
  10. invalid-name:
    Constant name "job_path" doesn't conform to UPPER_CASE naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/modules/async_wrapper.py#L29

The following messages are no longer emitted:

  1. invalid-name:
    Variable name "CLIARGS" doesn't conform to snake_case naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/context.py#L25
  2. invalid-name:
    Variable name "UnixHTTPSHandler" doesn't conform to snake_case naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/module_utils/urls.py#L222
  3. invalid-name:
    Variable name "UnixHTTPSConnection" doesn't conform to snake_case naming style
    https://github.com/ansible/ansible/blob/6a4b199054903f220d42b0db9f7e76240d101ee5/lib/ansible/module_utils/urls.py#L223

Effect on django:
The following messages are now emitted:

  1. invalid-name:
    Constant name "_exception" doesn't conform to UPPER_CASE naming style
    https://github.com/django/django/blob/c4e07f94ebc1f9eaa3dae7b3dc6a2b9832182a10/django/utils/autoreload.py#L35
  2. invalid-name:
    Constant name "_default" doesn't conform to UPPER_CASE naming style
    https://github.com/django/django/blob/c4e07f94ebc1f9eaa3dae7b3dc6a2b9832182a10/django/utils/translation/trans_real.py#L29
  3. invalid-name:
    Constant name "EndToken" doesn't conform to UPPER_CASE naming style
    https://github.com/django/django/blob/c4e07f94ebc1f9eaa3dae7b3dc6a2b9832182a10/django/template/smartif.py#L153
  4. invalid-name:
    Constant name "_worker_id" doesn't conform to UPPER_CASE naming style
    https://github.com/django/django/blob/c4e07f94ebc1f9eaa3dae7b3dc6a2b9832182a10/django/test/runner.py#L430

The following messages are no longer emitted:

  1. invalid-name:
    Variable name "SITE_CACHE" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/c4e07f94ebc1f9eaa3dae7b3dc6a2b9832182a10/django/contrib/sites/models.py#L9
  2. invalid-name:
    Variable name "EndToken" doesn't conform to snake_case naming style
    https://github.com/django/django/blob/c4e07f94ebc1f9eaa3dae7b3dc6a2b9832182a10/django/template/smartif.py#L153

Effect on poetry-core:
The following messages are now emitted:

  1. invalid-name:
    Constant name "_executable" doesn't conform to UPPER_CASE naming style
    https://github.com/python-poetry/poetry-core/blob/acc1bc9dda925ee47311c951e69d7993e81cae62/src/poetry/core/vcs/git.py#L147

Effect on sentry:
The following messages are now emitted:

  1. invalid-name:
    Constant name "_local_cache_generation" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/db/models/manager/base.py#L29
  2. invalid-name:
    Constant name "_local_cache_enabled" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/db/models/manager/base.py#L30
  3. invalid-name:
    Constant name "_global_regions" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/types/region.py#L203
  4. invalid-name:
    Constant name "rust_geoip" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/utils/geo.py#L17
  5. invalid-name:
    Constant name "outcomes_publisher" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/utils/outcomes.py#L159
  6. invalid-name:
    Constant name "billing_publisher" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/utils/outcomes.py#L160
  7. invalid-name:
    Constant name "_from_email_domain_cache" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/utils/email/address.py#L14
  8. invalid-name:
    Constant name "__installed" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/runner/settings.py#L136
  9. invalid-name:
    Constant name "_accountant_backend" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/usage_accountant/accountant.py#L21
  10. invalid-name:
    Constant name "_attachments_client" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/objectstore/__init__.py#L10
  11. invalid-name:
    Constant name "_last_validation_log" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/buffer/redis.py#L36
  12. invalid-name:
    Constant name "__rrweb_id" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/replays/testutils.py#L471
  13. invalid-name:
    Constant name "sync_publisher" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/replays/lib/kafka.py#L59
  14. invalid-name:
    Constant name "async_publisher" doesn't conform to UPPER_CASE naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/replays/lib/kafka.py#L60

The following messages are no longer emitted:

  1. invalid-name:
    Variable name "_LOGIN_URL" doesn't conform to snake_case naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/utils/auth.py#L36
  2. invalid-name:
    Variable name "AUTOFIX_POST_RESPONSE" doesn't conform to snake_case naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/apidocs/examples/autofix_examples.py#L3
  3. invalid-name:
    Variable name "AUTOFIX_GET_RESPONSE" doesn't conform to snake_case naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/apidocs/examples/autofix_examples.py#L12
  4. invalid-name:
    Variable name "_CONCURRENT_RATE_LIMITER" doesn't conform to snake_case naming style
    https://github.com/getsentry/sentry/blob/bc84efe97a1b02de2853fc03ab1454334b8b94b0/src/sentry/ratelimits/utils.py#L40

Effect on flask:
The following messages are now emitted:

  1. invalid-name:
    Constant name "_werkzeug_version" doesn't conform to UPPER_CASE naming style
    https://github.com/pallets/flask/blob/88a65bb374e87a18816a780dbd4ae69d307aa85c/src/flask/testing.py#L97

Effect on pygame:
The following messages are now emitted:

  1. invalid-name:
    Constant name "_ft_init" doesn't conform to UPPER_CASE naming style
    https://github.com/pygame/pygame/blob/85fda3f719d437cf27106afae8c890e6b88ba5f5/src_py/fastevent.py#L13
  2. invalid-name:
    Constant name "is_init" doesn't conform to UPPER_CASE naming style
    https://github.com/pygame/pygame/blob/85fda3f719d437cf27106afae8c890e6b88ba5f5/src_py/sysfont.py#L39
  3. invalid-name:
    Constant name "_is_init" doesn't conform to UPPER_CASE naming style
    https://github.com/pygame/pygame/blob/85fda3f719d437cf27106afae8c890e6b88ba5f5/src_py/camera.py#L9
  4. invalid-name:
    Constant name "_wq" doesn't conform to UPPER_CASE naming style
    https://github.com/pygame/pygame/blob/85fda3f719d437cf27106afae8c890e6b88ba5f5/src_py/threads/__init__.py#L28
  5. invalid-name:
    Constant name "_use_workers" doesn't conform to UPPER_CASE naming style
    https://github.com/pygame/pygame/blob/85fda3f719d437cf27106afae8c890e6b88ba5f5/src_py/threads/__init__.py#L31

Effect on coverage:
The following messages are no longer emitted:

  1. invalid-name:
    Variable name "CANONICAL_FILENAME_CACHE" doesn't conform to snake_case naming style
    https://github.com/nedbat/coveragepy/blob/6497e145451a504a445d2994aa8114d7a6669c71/coverage/files.py#L26

Effect on pandas:
The following messages are now emitted:

  1. invalid-name:
    Constant name "_evaluate" doesn't conform to UPPER_CASE naming style
    https://github.com/pandas-dev/pandas/blob/0d06ac85bbb64d30ad37b1139dcf08ae37a21270/pandas/core/computation/expressions.py#L33
  2. invalid-name:
    Constant name "_where" doesn't conform to UPPER_CASE naming style
    https://github.com/pandas-dev/pandas/blob/0d06ac85bbb64d30ad37b1139dcf08ae37a21270/pandas/core/computation/expressions.py#L34
  3. invalid-name:
    Constant name "_is_scipy_sparse" doesn't conform to UPPER_CASE naming style
    https://github.com/pandas-dev/pandas/blob/0d06ac85bbb64d30ad37b1139dcf08ae37a21270/pandas/core/dtypes/common.py#L73

The following messages are no longer emitted:

  1. invalid-name:
    Variable name "_TEST_RESULT" doesn't conform to snake_case naming style
    https://github.com/pandas-dev/pandas/blob/0d06ac85bbb64d30ad37b1139dcf08ae37a21270/pandas/core/computation/expressions.py#L31

Effect on pytest:
The following messages are no longer emitted:

  1. invalid-name:
    Variable name "RUNNER_CLASS" doesn't conform to snake_case naming style
    https://github.com/pytest-dev/pytest/blob/5ae9e4761b42a7c84d53486733d6ea8567dedccb/src/_pytest/doctest.py#L65
  2. invalid-name:
    Variable name "CHECKER_CLASS" doesn't conform to snake_case naming style
    https://github.com/pytest-dev/pytest/blob/5ae9e4761b42a7c84d53486733d6ea8567dedccb/src/_pytest/doctest.py#L67

This comment was generated for commit 6459607

@Pierre-Sassoulas
Copy link
Member

There's lot of changes from the primer which is worrying. Also the tests are not passing you can launch them with pytest locally, see https://pylint.readthedocs.io/en/stable/development_guide/contributor_guide/tests/launching_test.html#pytest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pylint C0103 (invalid-name) contradiction when module level names matches will class level names

2 participants