pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.26k stars 1.12k forks source link

3.3.x regression treating fstring as a constant: `C0103` in scripts #9963

Closed ColinHarrington closed 4 days ago

ColinHarrington commented 5 days ago

Bug description

It appears that fstrings in the script scope (not in a function anyway) are being identified as constants and linted inconsistently.

These are new findings in our codebases in the 3.3.x line

#!/usr/bin/env python3
"""
    Example of an what looks to be a pylint regression
"""

def greet(name):
    """CS101"""
    greeting = f"Hello {name}"
    print(greeting)

for thing in ["foo", "bar", "baz"]:
    full_name = f"prefix-{thing}"

greet("world")

Configuration

No response

Command used

pylint example

I also ran some combinations in docker to reproduce the issue:

 docker run -it --rm -v $(pwd)/example:/example python:3.10-alpine /bin/ash -x -c "pip install -q pylint==3.3.1 && pylint --version && pylint /example"

And then I tested multiple versions of pylint with this script:

#!/bin/bash -e

PYTHON_VERSION=3.10
for pylint_version in 3.0.* 3.1.* 3.2.* 3.3.0 3.3.1;
do
    docker run \
        --rm \
        -v "$(pwd)/example":/example \
        python:${PYTHON_VERSION}-alpine \
        /bin/ash +x \
        -c "pip install -q pylint==${pylint_version} 2>1 \
        && pylint --version \
        && pylint /example \
        ; echo \"\$(pylint --version | head -1): \$( [ \$? == 0 ] && echo \"✅ \" || echo \"❌ \")
        \""
done

I also has similar results with Several versions of python (3.9, 3.10, 3.11, 3.12, etc)

Pylint output

************* Module example
/example:12:4: C0103: Constant name "full_name" doesn't conform to UPPER_CASE naming style (invalid-name)

I also tested versions 3.0, 3.1, 3.2 3.3.0 and 3.3.1 with this result:

pylint 3.0.4
astroid 3.0.3
Python 3.10.15 (main, Sep 12 2024, 21:11:58) [GCC 13.2.1 20240309]

------------------------------------
Your code has been rated at 10.00/10

pylint 3.0.4: ✅ 

pylint 3.1.1
astroid 3.1.0
Python 3.10.15 (main, Sep 12 2024, 21:11:58) [GCC 13.2.1 20240309]

------------------------------------
Your code has been rated at 10.00/10

pylint 3.1.1: ✅ 

pylint 3.2.7
astroid 3.2.4
Python 3.10.15 (main, Sep 12 2024, 21:11:58) [GCC 13.2.1 20240309]

------------------------------------
Your code has been rated at 10.00/10

pylint 3.2.7: ✅ 

pylint 3.3.0
astroid 3.3.4
Python 3.10.15 (main, Sep 12 2024, 21:11:58) [GCC 13.2.1 20240309]
************* Module example
/example:12:4: C0103: Constant name "full_name" doesn't conform to UPPER_CASE naming style (invalid-name)

-----------------------------------
Your code has been rated at 8.33/10

pylint 3.3.0: ❌ 

pylint 3.3.1
astroid 3.3.4
Python 3.10.15 (main, Sep 12 2024, 21:11:58) [GCC 13.2.1 20240309]
************* Module example
/example:12:4: C0103: Constant name "full_name" doesn't conform to UPPER_CASE naming style (invalid-name)

-----------------------------------
Your code has been rated at 8.33/10

pylint 3.3.1: ❌ 

Expected behavior

I expect that an fstring in the script scope would not result in a pylint error C0103 congruent with the behavior prior to 3.3.0

Pylint version

pylint 3.3.1
astroid 3.3.4
Python 3.9.10 (main, May 31 2022, 12:13:35) 
[Clang 13.1.6 (clang-1316.0.21.2.5)]

Also from docker python alpine image:

pylint 3.3.1
astroid 3.3.4
Python 3.10.15 (main, Sep 12 2024, 21:11:58) [GCC 13.2.1 20240309]

OS / Environment

Darwin(intel x64), reproducible in Docker

Additional dependencies

No response

### Tasks
jacobtylerwalls commented 4 days ago

Thanks for the report, but this was a false negative fixed. Now the f-string behaves the same way as regular strings. They each need to conform to your configured naming style.

ColinHarrington commented 4 days ago

Thanks for the report, but this was a false negative fixed. Now the f-string behaves the same way as regular strings. They each need to conform to your configured naming style.

Then why are the f-strings linted differently within a function vs in the script/global scope in for-loop? Please look at the example for reference.

Am I missing some new configuration here or how do we explain the change in linting behavior?

jacobtylerwalls commented 4 days ago

There are different naming styles for functions versus global/script scope. This has always been the case for strings, f-strings are consistent with that now. The naming style config is explained in detail here.

You may find further behavior differences for type-annotated module constants, but we're addressing that in a future version: #9771.