Skip to content

Commit

Permalink
Stop checking minimum name length by default
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls committed Jul 2, 2023
1 parent 32effc5 commit fd5bc7e
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 33 deletions.
9 changes: 8 additions & 1 deletion doc/data/messages/i/invalid-name/details.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Pylint provides predefined naming patterns for some names. These patterns are of
based on a Naming Style but there is no option to choose one of the styles mentioned above.
The pattern can be overwritten with the options discussed below.

The following type of names are checked with a predefined pattern:
The following types of names are checked with a predefined pattern:

+--------------------+-------------------------------------------------------+------------------------------------------------------------+
| Name type | Good names | Bad names |
Expand All @@ -95,6 +95,13 @@ The following type of names are checked with a predefined pattern:
| | ``TopName`` is allowed but ``TTopName`` isn't. | |
+--------------------+-------------------------------------------------------+------------------------------------------------------------+

Before pylint 3.0, most predefined patterns also enforced a minimum length
of three characters. If this behavior is desired in versions 3.0 and following,
it can be had by providing custom regular expressions as described next. (Or,
if the ``disallowed-name`` check is sufficient instead of ``invalid-name``,
providing the single option ``bad-names-rgxs="^..?$"`` will suffice to fail 1-2
character names.

Custom regular expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
20 changes: 20 additions & 0 deletions doc/whatsnew/fragments/2018.user_action
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
The ``invalid-name`` message no longer checks for a minimum length of 3 characters by default.
(This was an unadvertised commingling of concerns between casing
and name length, and users regularly reported this to be surprising.)

If checking for a minimum length is still desired, it can be regained in two ways:

- If you are content with a ``disallowed-name`` message (instead of ``invalid-name``),
then simply add the option ``bad-names-rgxs="^..?$"``, which will fail 1-2
character-long names. (Ensure you enable ``disallowed-name``.)

- If you would prefer an ``invalid-name`` message to be emitted, or would prefer
finer-grained control over the circumstances in which messages are emitted
(classes vs. methods, etc.), then avail yourself of the regex options described
`here <https://pylint.readthedocs.io/en/stable/user_guide/configuration/all-options.html#main-checker>`_.
(In particular, take note of the commented out options in the "example configuration" given at
the bottom of the section.) The prior regexes can be found in the
`pull request <https://github.com/pylint-dev/pylint/pull/8813>`_
that removed the length requirements.

Closes #2018
24 changes: 12 additions & 12 deletions pylint/checkers/base/name_checker/naming_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,47 +47,47 @@ def get_regex(cls, name_type: str) -> Pattern[str]:
class SnakeCaseStyle(NamingStyle):
"""Regex rules for snake_case naming style."""

CLASS_NAME_RGX = re.compile(r"[^\W\dA-Z][^\WA-Z]+$")
CLASS_NAME_RGX = re.compile(r"[^\W\dA-Z][^\WA-Z]*$")
MOD_NAME_RGX = re.compile(r"[^\W\dA-Z][^\WA-Z]*$")
CONST_NAME_RGX = re.compile(r"([^\W\dA-Z][^\WA-Z]*|__.*__)$")
COMP_VAR_RGX = CLASS_NAME_RGX
DEFAULT_NAME_RGX = re.compile(
r"([^\W\dA-Z][^\WA-Z]{2,}|_[^\WA-Z]*|__[^\WA-Z\d_][^\WA-Z]+__)$"
r"([^\W\dA-Z][^\WA-Z]*|_[^\WA-Z]*|__[^\WA-Z\d_][^\WA-Z]+__)$"
)
CLASS_ATTRIBUTE_RGX = re.compile(r"([^\W\dA-Z][^\WA-Z]{2,}|__.*__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"([^\W\dA-Z][^\WA-Z]*|__.*__)$")


class CamelCaseStyle(NamingStyle):
"""Regex rules for camelCase naming style."""

CLASS_NAME_RGX = re.compile(r"[^\W\dA-Z][^\W_]+$")
CLASS_NAME_RGX = re.compile(r"[^\W\dA-Z][^\W_]*$")
MOD_NAME_RGX = re.compile(r"[^\W\dA-Z][^\W_]*$")
CONST_NAME_RGX = re.compile(r"([^\W\dA-Z][^\W_]*|__.*__)$")
COMP_VAR_RGX = MOD_NAME_RGX
DEFAULT_NAME_RGX = re.compile(r"([^\W\dA-Z][^\W_]{2,}|__[^\W\dA-Z_]\w+__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"([^\W\dA-Z][^\W_]{2,}|__.*__)$")
DEFAULT_NAME_RGX = re.compile(r"([^\W\dA-Z][^\W_]*|__[^\W\dA-Z_]\w+__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"([^\W\dA-Z][^\W_]*|__.*__)$")


class PascalCaseStyle(NamingStyle):
"""Regex rules for PascalCase naming style."""

CLASS_NAME_RGX = re.compile(r"[^\W\da-z][^\W_]+$")
CLASS_NAME_RGX = re.compile(r"[^\W\da-z][^\W_]*$")
MOD_NAME_RGX = CLASS_NAME_RGX
CONST_NAME_RGX = re.compile(r"([^\W\da-z][^\W_]*|__.*__)$")
COMP_VAR_RGX = CLASS_NAME_RGX
DEFAULT_NAME_RGX = re.compile(r"([^\W\da-z][^\W_]{2,}|__[^\W\dA-Z_]\w+__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"[^\W\da-z][^\W_]{2,}$")
DEFAULT_NAME_RGX = re.compile(r"([^\W\da-z][^\W_]*|__[^\W\dA-Z_]\w+__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"[^\W\da-z][^\W_]*$")


class UpperCaseStyle(NamingStyle):
"""Regex rules for UPPER_CASE naming style."""

CLASS_NAME_RGX = re.compile(r"[^\W\da-z][^\Wa-z]+$")
CLASS_NAME_RGX = re.compile(r"[^\W\da-z][^\Wa-z]*$")
MOD_NAME_RGX = CLASS_NAME_RGX
CONST_NAME_RGX = re.compile(r"([^\W\da-z][^\Wa-z]*|__.*__)$")
COMP_VAR_RGX = CLASS_NAME_RGX
DEFAULT_NAME_RGX = re.compile(r"([^\W\da-z][^\Wa-z]{2,}|__[^\W\dA-Z_]\w+__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"[^\W\da-z][^\Wa-z]{2,}$")
DEFAULT_NAME_RGX = re.compile(r"([^\W\da-z][^\Wa-z]*|__[^\W\dA-Z_]\w+__)$")
CLASS_ATTRIBUTE_RGX = re.compile(r"[^\W\da-z][^\Wa-z]*$")


class AnyStyle(NamingStyle):
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/d/disable_msg_next_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def function_B(arg1, arg2):

# pylint: disable-next=invalid-name, f-string-without-interpolation
def function_C():
x = "string" # [unused-variable, invalid-name]
X = "string" # [unused-variable, invalid-name]
return f"This should be a normal string" # [f-string-without-interpolation]


Expand Down
4 changes: 2 additions & 2 deletions tests/functional/d/disable_msg_next_line.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
invalid-name:15:4:15:5:function_C:"Variable name ""x"" doesn't conform to snake_case naming style":HIGH
unused-variable:15:4:15:5:function_C:Unused variable 'x':UNDEFINED
invalid-name:15:4:15:5:function_C:"Variable name ""X"" doesn't conform to snake_case naming style":HIGH
unused-variable:15:4:15:5:function_C:Unused variable 'X':UNDEFINED
f-string-without-interpolation:16:11:16:44:function_C:Using an f-string that does not have any interpolated variables:UNDEFINED
invalid-name:19:0:19:14:function_D:"Function name ""function_D"" doesn't conform to snake_case naming style":HIGH
unused-argument:19:21:19:25:function_D:Unused argument 'arg2':HIGH
Expand Down
8 changes: 6 additions & 2 deletions tests/functional/i/invalid/invalid_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ def test():
re = None
return re

def a(): # [invalid-name]
"""yo"""
def a():
"""We no longer fail 1-character names by default."""


def A(): # [invalid-name]
"""But we do check casing."""


def _generate_cmdline_tests():
Expand Down
12 changes: 6 additions & 6 deletions tests/functional/i/invalid/invalid_name.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
invalid-name:12:0:12:3::"Constant name ""aaa"" doesn't conform to UPPER_CASE naming style":HIGH
invalid-name:16:4:16:8::"Constant name ""time"" doesn't conform to UPPER_CASE naming style":HIGH
invalid-name:32:0:32:5:a:"Function name ""a"" doesn't conform to snake_case naming style":HIGH
invalid-name:46:4:46:13::"Constant name ""Foocapfor"" doesn't conform to UPPER_CASE naming style":HIGH
invalid-name:62:0:62:68:a_very_very_very_long_function_name_WithCamelCase_to_make_it_sad:"Function name ""a_very_very_very_long_function_name_WithCamelCase_to_make_it_sad"" doesn't conform to snake_case naming style":HIGH
invalid-name:70:23:70:29:FooBar.__init__:"Argument name ""fooBar"" doesn't conform to snake_case naming style":HIGH
invalid-name:76:8:76:14:FooBar.func1:"Argument name ""fooBar"" doesn't conform to snake_case naming style":HIGH
invalid-name:96:8:96:15:FooBar.test_disable_mixed:"Argument name ""fooBar2"" doesn't conform to snake_case naming style":HIGH
invalid-name:36:0:36:5:A:"Function name ""A"" doesn't conform to snake_case naming style":HIGH
invalid-name:50:4:50:13::"Constant name ""Foocapfor"" doesn't conform to UPPER_CASE naming style":HIGH
invalid-name:66:0:66:68:a_very_very_very_long_function_name_WithCamelCase_to_make_it_sad:"Function name ""a_very_very_very_long_function_name_WithCamelCase_to_make_it_sad"" doesn't conform to snake_case naming style":HIGH
invalid-name:74:23:74:29:FooBar.__init__:"Argument name ""fooBar"" doesn't conform to snake_case naming style":HIGH
invalid-name:80:8:80:14:FooBar.func1:"Argument name ""fooBar"" doesn't conform to snake_case naming style":HIGH
invalid-name:100:8:100:15:FooBar.test_disable_mixed:"Argument name ""fooBar2"" doesn't conform to snake_case naming style":HIGH
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import abc


def custom_prop(f): # [invalid-name]
return property(f)
def custom_prop(F): # [invalid-name]
return property(F)


class FooClass:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
invalid-name:9:16:9:17:custom_prop:"Argument name ""f"" doesn't conform to snake_case naming style":HIGH
invalid-name:9:16:9:17:custom_prop:"Argument name ""F"" doesn't conform to snake_case naming style":HIGH
invalid-name:21:4:21:11:FooClass.bar:"Attribute name ""bar"" doesn't conform to '[A-Z]+' pattern":INFERENCE
invalid-name:37:4:37:11:AnotherFooClass.foo:"Attribute name ""foo"" doesn't conform to '[A-Z]+' pattern":INFERENCE
8 changes: 4 additions & 4 deletions tests/functional/n/name/name_preset_snake_case.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
invalid-name:6:0:6:13::"Constant name ""SOME_CONSTANT"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]*|__.*__)$' pattern)":HIGH
invalid-name:13:0:13:13:MyClass:"Class name ""MyClass"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)":HIGH
invalid-name:25:0:25:12:sayHello:"Function name ""sayHello"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]{2,}|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)":HIGH
invalid-name:29:0:29:13:FooEnum:"Class name ""FooEnum"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)":HIGH
invalid-name:34:0:34:9:Bar:"Class name ""Bar"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]+$' pattern)":HIGH
invalid-name:13:0:13:13:MyClass:"Class name ""MyClass"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]*$' pattern)":HIGH
invalid-name:25:0:25:12:sayHello:"Function name ""sayHello"" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]*|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)":HIGH
invalid-name:29:0:29:13:FooEnum:"Class name ""FooEnum"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]*$' pattern)":HIGH
invalid-name:34:0:34:9:Bar:"Class name ""Bar"" doesn't conform to snake_case naming style ('[^\\W\\dA-Z][^\\WA-Z]*$' pattern)":HIGH
4 changes: 2 additions & 2 deletions tests/functional/n/namePresetCamelCase.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
invalid-name:3:0:3:13::"Constant name ""SOME_CONSTANT"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]*|__.*__)$' pattern)":HIGH
invalid-name:10:0:10:13:MyClass:"Class name ""MyClass"" doesn't conform to camelCase naming style ('[^\\W\\dA-Z][^\\W_]+$' pattern)":HIGH
invalid-name:22:0:22:13:say_hello:"Function name ""say_hello"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]{2,}|__[^\\W\\dA-Z_]\\w+__)$' pattern)":HIGH
invalid-name:10:0:10:13:MyClass:"Class name ""MyClass"" doesn't conform to camelCase naming style ('[^\\W\\dA-Z][^\\W_]*$' pattern)":HIGH
invalid-name:22:0:22:13:say_hello:"Function name ""say_hello"" doesn't conform to camelCase naming style ('([^\\W\\dA-Z][^\\W_]*|__[^\\W\\dA-Z_]\\w+__)$' pattern)":HIGH

0 comments on commit fd5bc7e

Please sign in to comment.