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

Check that a name exists inside enum.Enum class' __members__. #8905

Merged
merged 4 commits into from
Sep 26, 2023

Conversation

mbyrnepr2
Copy link
Member

Type of Changes

Type
βœ“ πŸ› Bug fix
✨ New feature
πŸ”¨ Refactoring
πŸ“œ Docs

Description

Check that a name exists inside an enum.Enum class' __members__ container before doing the invalid-name check.

Refs #7402

@codecov
Copy link

codecov bot commented Jul 31, 2023

Codecov Report

Merging #8905 (03329f1) into main (6dac300) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #8905    /-   ##
=======================================
  Coverage   95.75%   95.75%           
=======================================
  Files         173      173           
  Lines       18652    18655     3     
=======================================
  Hits        17860    17863     3     
  Misses        792      792           
Files Changed Coverage Ξ”
pylint/checkers/base/name_checker/checker.py 98.59% <100.00%> (-0.02%) ⬇️
pylint/checkers/utils.py 95.93% <100.00%> ( 0.02%) ⬆️

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@@ -486,12 486,10 @@ def visit_assignname( # pylint: disable=too-many-branches
# Check names defined in class scopes
elif isinstance(frame, nodes.ClassDef):
if not list(frame.local_attr_ancestors(node.name)):
Copy link
Member Author

Choose a reason for hiding this comment

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

Wondering if this line can be removed πŸ€”

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately, removing this line caused #9765

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@mbyrnepr2 mbyrnepr2 marked this pull request as ready for review August 3, 2023 12:09
@mbyrnepr2
Copy link
Member Author

There’s 2 warnings in the readthedocs output that are failing the ci but unsure which file it’s coming from exactly. Seems to be 3.0/index

@Pierre-Sassoulas Pierre-Sassoulas added False Positive 🦟 A message is emitted but nothing is wrong with the code backport maintenance/3.3.x labels Aug 4, 2023
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.17.6 milestone Aug 4, 2023
@Pierre-Sassoulas
Copy link
Member

I'm going to try to fix the readthedoc pipeline on main.

@Pierre-Sassoulas
Copy link
Member

Well it was due to,

/home/docs/checkouts/readthedocs.org/user_builds/pylint/checkouts/8905/doc/whatsnew/3/3.0/index.rst:107: WARNING: Bullet list ends without a blank line; unexpected unindent.

/home/docs/checkouts/readthedocs.org/user_builds/pylint/checkouts/8905/doc/whatsnew/3/3.0/index.rst:112: WARNING: Bullet list ends without a blank line; unexpected unindent.

It was fixed by @jacobtylerwalls in #8921, so rebasing should work, thank you Jacob :)

@github-actions

This comment has been minimized.

@mbyrnepr2
Copy link
Member Author

mbyrnepr2 commented Aug 4, 2023

πŸ€– Effect of this PR on checked open source code: πŸ€–

Effect on music21: The following messages are now emitted:

  1. invalid-name:
    Class attribute name "registerOutputSubformatExtensions" doesn't conform to '([A-Za-z][A-Za-z0-9_]{2,30}|(._))$' pattern*
    https://github.com/cuthbertLab/music21/blob/8baa27339109895cc4c55dd99cb0290e111fb02a/music21/converter/subConverters.py#L355
  2. invalid-name:
    Class attribute name "registerOutputSubformatExtensions" doesn't conform to '([A-Za-z][A-Za-z0-9_]{2,30}|(._))$' pattern*
    https://github.com/cuthbertLab/music21/blob/8baa27339109895cc4c55dd99cb0290e111fb02a/music21/converter/subConverters.py#L411
  3. invalid-name:
    Class attribute name "registerOutputSubformatExtensions" doesn't conform to '([A-Za-z][A-Za-z0-9_]{2,30}|(._))$' pattern*
    https://github.com/cuthbertLab/music21/blob/8baa27339109895cc4c55dd99cb0290e111fb02a/music21/converter/subConverters.py#L834

This comment was generated for commit 83a3503

These seem valid because the names are too long for the regex defined in that project's pylintrc:

import re
>>> re.match("([A-Za-z_][A-Za-z0-9_]{2,30}|(__.__))$", "registerOutputSubformatExtensions")
>>> 
>>> re.match("([A-Za-z_][A-Za-z0-9_]{2,30}|(__.__))$", "registerOutputSubformatExtensio")
<re.Match object; span=(0, 31), match='registerOutputSubformatExtensio'>
>>> 

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.

It would mean we never raise on an enum ? In the example with color and rgb the color is a three ints tuple and red/green/blue is simply an int maybe it's something to explore ?

@mbyrnepr2
Copy link
Member Author

mbyrnepr2 commented Aug 4, 2023

@Pierre-Sassoulas in the context of the example you refer to, the message doesn't raise and that is the expected outcome since the members satisfy the checker and the attributes are not assigned values (hence they don't appear in the __members__ container). However, you need to also checkout the astroid branch pylint-dev/astroid#2263 to see it working correctly.

from enum import Enum

class AnEnum(Enum):
    apple: int
    PEAR: int = 42


print(AnEnum.__members__)
{'PEAR': <AnEnum.PEAR: 42>}

Let's add a lower-cased purple member to the example:

from enum import Enum

class Color(Enum):
    """Represents colors as (red, green, blue) tuples."""

    YELLOW      = 250, 250,   0
    KHAKI       = 250, 250, 125
    MAGENTA     = 250,   0, 250
    VIOLET      = 250, 125, 250
    CYAN        =   0, 250, 250
    AQUAMARINE  = 125, 250, 250
    purple      = 1, 2, 3

    # Class constant name "red" doesn't conform to UPPER_CASE naming style (invalid-name)
    # Class constant name "green" doesn't conform to UPPER_CASE naming style (invalid-name)
    # Class constant name "blue" doesn't conform to UPPER_CASE naming style (invalid-name)
    red: int
    green: int
    blue: int

    def __init__(self, red: int, green: int, blue: int) -> None:
        self.red   = red
        self.green = green
        self.blue  = blue

    @property
    def as_hex(self) -> str:
        """Get hex 'abcdef' representation for a color."""
        return f'{self.red:0{2}x}{self.green:0{2}x}{self.blue:0{2}x}'

example.py: 12:4: C0103: Class constant name "purple" doesn't conform to UPPER_CASE naming style (invalid-name)

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.

Right my bad didn't see that the functional test was actually raising here. Could you add the rgb example as a functional test ? LGTM otherwise.

@mbyrnepr2
Copy link
Member Author

Unittests will fail now until pylint-dev/astroid#2263 is released.
About that - I currently have the astroid change set for 3.0 release but would you prefer that to be changed to 2.15.7 instead?

@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.

I liked your own functional test too, we can have both :) otherwise LGTM

@Pierre-Sassoulas
Copy link
Member

Is it a bug fix il astroid ? If so we can backport it. If not let's release this in 3.0

@mbyrnepr2
Copy link
Member Author

Is it a bug fix il astroid ? If so we can backport it. If not let's release this in 3.0

It's a bug-fix in both astroid and Pylint (if I've understood you correctly :))
astroid fix: exclude non-members from __members__ (i.e: tomato: int)
pylint fix: check that the AssignName belongs to the __members__ of it's class (and not only check that the class is a subtype of enum.Enum.)

@mbyrnepr2
Copy link
Member Author

I liked your own functional test too, we can have both :) otherwise LGTM

No worries - less is more :)

@Pierre-Sassoulas Pierre-Sassoulas added the Blocked 🚧 Blocked by a particular issue label Aug 7, 2023
@Pierre-Sassoulas
Copy link
Member

Blocked by the releease of astroid 2.15.7 then ?

@mbyrnepr2
Copy link
Member Author

mbyrnepr2 commented Aug 7, 2023

It's also blocked by #8897 since the code in that example when run with the Pylint code of the current MR crashes 😒

@mbyrnepr2
Copy link
Member Author

It's also blocked by #8897 since the code in that example when run with the Pylint code of the current MR crashes 😒

But I may have a fix for that shortly :)

@github-actions
Copy link
Contributor

πŸ€– Effect of this PR on checked open source code: πŸ€–

Effect on home-assistant:
The following messages are no longer emitted:

  1. invalid-name:
    Class constant name "_recoverable" doesn't conform to UPPER_CASE naming style
    https://github.com/home-assistant/core/blob/6383cafeb9643266d7a7f6dc1ec4519b3775b58b/homeassistant/config_entries.py#L110

Effect on music21:
The following messages are now emitted:

  1. invalid-name:
    Class attribute name "registerOutputSubformatExtensions" doesn't conform to '([A-Za-z_][A-Za-z0-9_]{2,30}|(__.__))$' pattern*
    https://github.com/cuthbertLab/music21/blob/f457a2ba52ea3f978d805cd52fa101dfb0dd8577/music21/converter/subConverters.py#L355
  2. invalid-name:
    Class attribute name "registerOutputSubformatExtensions" doesn't conform to '([A-Za-z_][A-Za-z0-9_]{2,30}|(__.__))$' pattern*
    https://github.com/cuthbertLab/music21/blob/f457a2ba52ea3f978d805cd52fa101dfb0dd8577/music21/converter/subConverters.py#L411
  3. invalid-name:
    Class attribute name "registerOutputSubformatExtensions" doesn't conform to '([A-Za-z_][A-Za-z0-9_]{2,30}|(__.__))$' pattern*
    https://github.com/cuthbertLab/music21/blob/f457a2ba52ea3f978d805cd52fa101dfb0dd8577/music21/converter/subConverters.py#L834

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

  1. invalid-name:
    Class constant name "do_not_call_in_templates" doesn't conform to UPPER_CASE naming style
    https://github.com/django/django/blob/574ee4023e15cfb195833edfbaed353f8021c62f/django/db/models/enums.py#L85

This comment was generated for commit 03329f1

@jacobtylerwalls jacobtylerwalls removed the Blocked 🚧 Blocked by a particular issue label Sep 23, 2023
@jacobtylerwalls
Copy link
Member

jacobtylerwalls commented Sep 23, 2023

@mbyrnepr2 do you know why tests are passing without your astroid changes here? πŸ™

@mbyrnepr2
Copy link
Member Author

I think the changes from astroid were pulled in from latest push? 2.15.7 astroid went out last month I think. There’s been a couple of different enum changes.

@jacobtylerwalls
Copy link
Member

jacobtylerwalls commented Sep 24, 2023

2.15.7 went out yesterday, and we haven't updated pylint to that or created a new astroid pre-release (but hoping to do so soon)

@jacobtylerwalls
Copy link
Member

Ooh, Pierre is doing the pre-release right now!

@Pierre-Sassoulas
Copy link
Member

We have both 2.15.7 and 3.0.0b0 released now, so it should be possible to merge on main then backport.

@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.17.6, 2.17.7, 3.0.0 Sep 24, 2023
@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 3.0.0, 3.0.1 Sep 25, 2023
@mbyrnepr2 mbyrnepr2 merged commit a4aff97 into pylint-dev:main Sep 26, 2023
44 checks passed
@mbyrnepr2 mbyrnepr2 deleted the 7402_type_hinted_enum_class branch September 26, 2023 19:57
@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 3.0.1, 3.0.0b0 Sep 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.

3 participants