diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1144.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1144.html index 9057643c32..e8552dfb10 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1144.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1144.html @@ -52,6 +52,6 @@
In theory renaming parameters also breaks Liskov Substitution Principle. Arguments can't be passed via keyword arguments anymore. However, as PEP-570 says, it is common to rename parameters when it improves +code readability and when arguments are always passed by position.
+"Positional-Only Parameters" were introduced in python 3.8 to solve this problem. As most programs will need to support older versions of python, +this rule won't raise an issue on renamed parameters.
+
+class ParentClass(object):
def mymethod(self, param1):
pass
-class ChildClassReordered(ParentClass):
- def mymethod(self, param1, inserted=None):
+class ChildClassRenamed(ParentClass):
+ def mymethod(self, renamed): # No issue but this is suspicious. Rename this parameter as "param1" or use positional only arguments if possible.
pass
By convention, the first argument to class methods, i.e. methods decorated with @classmethod, is named cls as a representation and a
-reminder that the argument is the class itself. Name the argument something else, and you stand a good chance of confusing both users and maintainers
-of the code. It might also indicate that the cls parameter was forgotten, in which case calling the method will most probably fail. This
-rule also applies to methods __init_subclass__, __class_getitem__ and __new__ as their first argument is always
-the class instead of "self".
By convention, the first argument to class methods, i.e. methods decorated with @classmethod, is named cls as a
+representation and a reminder that the argument is the class itself. Name the argument something else, and you stand a good chance of confusing both
+users and maintainers of the code. It might also indicate that the cls parameter was forgotten, in which case calling the method will
+most probably fail. This rule also applies to methods __init_subclass__, __class_getitem__ and __new__ as their
+first argument is always the class instead of "self".
By default this rule accepts cls and mcs, which is sometime used in metaclasses, as valid names for class parameters. You
can set your own list of accepted names via the parameter classParameterNames.
This rule raises an issue when the first parameter of a class method is not an accepted name.
diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3985.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3985.html index 5f76943ff0..4fd5d78281 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3985.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3985.html @@ -16,7 +16,7 @@
class Noncompliant:
- class __MyClas1s(): # Noncompliant
+ class __MyClass1(): # Noncompliant
pass
class _MyClass2(): # Noncompliant
diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5685.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5685.html
index 09d891da18..9c50c46ad3 100644
--- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5685.html
+++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5685.html
@@ -1,7 +1,8 @@
The walrus operator := (also known as "assignment expression") should be used
with caution as it can easily make code more difficult to understand and thus maintain. In such case it is advised to refactor the code and use an
assignment statement (i.e. =) instead.
-This rule raises an issue raises an issue when the walrus operator is used in a way which makes the code confusing.
+This rule raises an issue raises an issue when the walrus operator is used in a way which makes the code confusing, as described in PEP 572.
Noncompliant Code Example
# using an assignment expression (:=) as an assignment statement (=) is more explicit
diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5706.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5706.html
index 4e39825eed..8a4a6f844a 100644
--- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5706.html
+++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5706.html
@@ -4,8 +4,10 @@
Raising this exception will make the stack trace difficult to understand.
The __exit__ method can filter passed-in exceptions by simply returning True or False.
This rule raises an issue when:
- * an __exit__ method has a bare raise outside of an except block.
- * an __exit__ method raises the exception provided as parameter.
+
__exit__ method has a bare raise outside of an except block. __exit__ method raises the exception provided as parameter. class MyContextManager: @@ -42,7 +44,9 @@Compliant Solution
raise MemoryError("No more memory") # This is ok too.
* Python documentation – The
-__exit__ special method
* PEP 343 – The "with" Statement
+__exit__ special method The only two possible types for an except's expression are a class deriving from BaseException, or a tuple composed of
-such classes.
This rule raises an issue when the expression used in an except block is a boolean expression of exceptions. The result of such
expression is a single exception class, which is valid but not what the developer intended.
__new__ and
__init_subclass__ take a class as first argument even thought they are not decorated with @classmethod.
This rule raises an issue when an instance of class method does not have at least one positional parameter.
+
+class MyClass:
+ def instance_method(): # Noncompliant. "self" parameter is missing.
+ print("instance_method")
+
+ @classmethod
+ def class_method(): # Noncompliant. "cls" parameter is missing.
+ print("class_method")
+
class MyClass: @@ -21,5 +31,7 @@Compliant Solution
print("static_method")
* Python documentation - Method Objects
+Naming the "self" parameter differently is confusing. It might also indicate that the "self" parameter was forgotten, in which case calling the method will most probably fail.
+Note also that creating methods which are used as static methods without the @staticmethod decorator is a bad practice because calling
+these methods on an instance will raise a `TypeError`. Either move the method out of the class or decorate it with @staticmethod.
This rule raises an issue when the first parameter of an instance method is not called "self".
class MyClass:
def send_request(request): # Noncompliant. "self" was probably forgotten
print("send_request")
+
+class ClassWithStaticMethod:
+ def static_method(param): # Noncompliant
+ print(param)
+ClassWithStaticMethod().static_method(42) # Method is available on the instance but calling it will raise a TypeError
class MyClass:
def send_request(self, request):
print("send_request")
+
+class ClassWithStaticMethod:
+ @staticmethod
+ def static_method(param):
+ print(param)
+ClassWithStaticMethod().static_method(42)
This rule will also accept "cls" or "mcs" as first parameter's name for metaclasses' methods.
No issue will be raised for methods called __init_subclass__, __class_getitem__ or __new__ as these methods'
first parameter is a class.
You can also disable issues on methods decorated with a specific decorator. Add these decorators to this rule's "ignoreDecorators" parameter.
+With "ignoredDecorators" set to "abstractmethod"
++from abc import abstractmethod, ABC + +class MyClass(ABC): + @abstractmethod + def method(): # No issue, even if it is better in this case to also decorate with @staticmethod + pass +
class A:
@property
- def foo(self, unexpected): # Noncompliant. Too many parameters.
+ def foo(self, unexpected, unexpected2): # Noncompliant. Too many parameters.
return self._foo
@foo.setter
def foo(self, value, unexpected): # Noncompliant. Too many parameters.
self._foo = value
- @foo.setter
- def foo(self): # Noncompliant. missing value
- self._foo = 42
-
@foo.deleter
def foo(self, unexpected): # Noncompliant. Too many parameters.
del self._foo
@@ -35,14 +31,10 @@ Noncompliant Code Example
def set_foo(self, value, unexpected): # Noncompliant. Too many parameters.
self._foo = value
- def set_foo2(self): # Noncompliant. missing value
- self._foo = 42
-
def del_foo(self, unexpected): # Noncompliant. Too many parameters.
del self._foo
foo = property(get_foo, set_foo, del_foo, "'foo' property.")
- foo2 = property(get_foo, set_foo2, del_foo, "'foo2' property.")
diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/Sonar_way_profile.json b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/Sonar_way_profile.json
index 6f7b70fdd8..4ba9efc7ca 100644
--- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/Sonar_way_profile.json
+++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/Sonar_way_profile.json
@@ -48,7 +48,6 @@
"S2638",
"S2710",
"S2711",
- "S2733",
"S2734",
"S2737",
"S2757",
diff --git a/sonarpedia.json b/sonarpedia.json
index 22f94f8329..6c06175087 100644
--- a/sonarpedia.json
+++ b/sonarpedia.json
@@ -3,7 +3,7 @@
"languages": [
"PY"
],
- "latest-update": "2020-03-09T13:24:26.631386Z",
+ "latest-update": "2020-03-24T08:46:39.066Z",
"options": {
"no-language-in-filenames": true,
"preserve-filenames": true