Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ <h2>Compliant Solution</h2>
<h2>See</h2>
<ul>
<li> <a href="https://docs.python.org/3.8/tutorial/classes.html#private-variables">Python documentation <del></del> Private Variables</a> </li>
<li> <a href="https://www.python.org/dev/peps/pep-0008/#designing-for-inheritance">PEP 8 <del></del> Style Guide for Python Code</a> </li>
<li> <a href="https://www.python.org/dev/peps/pep-0008/#designing-for-inheritance">PEP8 <del></del> Designing for Inheritance</a> </li>
</ul>

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<li> Removing parameters, even when they have default values. </li>
<li> Adding mandatory parameters, i.e. without a default value. </li>
<li> Removing the default value of a parameter. </li>
<li> Renaming parameters, except when they are positional-only parameters. </li>
<li> Reordering parameters, except when they are keyword-only parameters. </li>
<li> Removing some ways of providing a parameter. If a parameter could be passed as keyword it should still be possible to pass it as keyword, and
the same is true for positional parameters. </li>
Expand All @@ -42,13 +41,8 @@ <h2>Noncompliant Code Example:</h2>
def mymethod(self): # Noncompliant. Add missing parameter "param1".
pass

class ChildClassRenamed(ParentClass):
def mymethod(self, renamed): # Noncompliant. Rename this parameter as "param1".
pass

class ChildClassReordered(ParentClass):
def mymethod(self, inserted, param1): # Noncompliant * 2.
# Move param1 in first position
def mymethod(self, inserted, param1): # Noncompliant
# Remove parameters "inserted" or provide a default value.
pass
</pre>
Expand All @@ -66,16 +60,29 @@ <h2>Compliant Solution:</h2>
def mymethod(self, param1=None):
pass

class ChildClassRenamed(ParentClass):
class ChildClassReordered(ParentClass):
def mymethod(self, param1, inserted=None):
pass
</pre>
<h2>Exceptions</h2>
<p>In theory renaming parameters also breaks Liskov Substitution Principle. Arguments can't be passed via keyword arguments anymore. However, <a
href="https://www.python.org/dev/peps/pep-0570/#consistency-in-subclasses">as PEP-570 says</a>, it is common to rename parameters when it improves
code readability and when arguments are always passed by position.</p>
<p>"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.</p>
<pre>
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
</pre>
<h2>See</h2>
<ul>
<li> <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Wikipedia - Liskov substitution principle</a> </li>
<li> Python Enhancement Proposal (PEP) 3102 - <a href="https://www.python.org/dev/peps/pep-3102/">Keyword-Only Arguments</a> </li>
<li> Python Enhancement Proposal (PEP) 570 - <a href="https://www.python.org/dev/peps/pep-0570/">Python Positional-Only Parameters</a> </li>
</ul>

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p>By convention, the first argument to class methods, i.e. methods decorated with @classmethod, is named <code>cls</code> 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 <code>cls</code> parameter was forgotten, in which case calling the method will most probably fail. This
rule also applies to methods <code>__init_subclass__</code>, <code>__class_getitem__</code> and <code>__new__</code> as their first argument is always
the class instead of "self".</p>
<p>By convention, the first argument to class methods, i.e. methods decorated with <code>@classmethod</code>, is named <code>cls</code> 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 <code>cls</code> parameter was forgotten, in which case calling the method will
most probably fail. This rule also applies to methods <code>__init_subclass__</code>, <code>__class_getitem__</code> and <code>__new__</code> as their
first argument is always the class instead of "self".</p>
<p>By default this rule accepts <code>cls</code> and <code>mcs</code>, which is sometime used in metaclasses, as valid names for class parameters. You
can set your own list of accepted names via the parameter <code>classParameterNames</code>.</p>
<p>This rule raises an issue when the first parameter of a class method is not an accepted name.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<h2>Noncompliant Code Example</h2>
<pre>
class Noncompliant:
class __MyClas1s(): # Noncompliant
class __MyClass1(): # Noncompliant
pass

class _MyClass2(): # Noncompliant
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<p>The <a href="https://www.python.org/dev/peps/pep-0572">walrus operator</a> <code>:=</code> (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. <code>=</code>) instead.</p>
<p>This rule raises an issue raises an issue when the walrus operator is used in a way which makes the code confusing.</p>
<p>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 <a
href="https://www.python.org/dev/peps/pep-0572/#exceptional-cases">PEP 572</a>.</p>
<h2>Noncompliant Code Example</h2>
<pre>
# using an assignment expression (:=) as an assignment statement (=) is more explicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
<p> Raising this exception will make the stack trace difficult to understand.</p>
<p>The <code>__exit__</code> method can filter passed-in exceptions by simply returning True or False.</p>
<p>This rule raises an issue when:</p>
<p> * an <code>__exit__</code> method has a bare <code>raise</code> outside of an <code>except</code> block.</p>
<p> * an <code>__exit__</code> method raises the exception provided as parameter.</p>
<ul>
<li> an <code>__exit__</code> method has a bare <code>raise</code> outside of an <code>except</code> block. </li>
<li> an <code>__exit__</code> method raises the exception provided as parameter. </li>
</ul>
<h2>Noncompliant Code Example</h2>
<pre>
class MyContextManager:
Expand Down Expand Up @@ -42,7 +44,9 @@ <h2>Compliant Solution</h2>
raise MemoryError("No more memory") # This is ok too.
</pre>
<h2>See</h2>
<p> * Python documentation – <a href="https://docs.python.org/3/reference/datamodel.html?highlight=__exit__%20special#object.__exit__">The
<code>__exit__</code> special method</a></p>
<p> * PEP 343 – <a href="https://www.python.org/dev/peps/pep-0343/">The "with" Statement</a></p>
<ul>
<li> Python documentation – <a href="https://docs.python.org/3/reference/datamodel.html?highlight=__exit__%20special#object.__exit__">The
<code>__exit__</code> special method</a> </li>
<li> PEP 343 – <a href="https://www.python.org/dev/peps/pep-0343/">The "with" Statement</a> </li>
</ul>

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p>The only two possible types for an <code>except</code>'s expression are a class deriving from <code>BaseException</code>, or a tuple composed of
such classes.</p>
such classes (or an old style class if you are using python 2, but this has been removed in python 3).</p>
<p>This rule raises an issue when the expression used in an <code>except</code> 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.</p>
<h2>Noncompliant Code Example</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ <h2>Exceptions</h2>
<h2>See</h2>
<ul>
<li> <a href="https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments">The Hitchhiker's Guide to Python - Common Gotchas</a> </li>
<li> [effbot.org - Default Parameter Values in Python | http://effbot.org/zone/default-values.htm] </li>
<li> <a href="http://effbot.org/zone/default-values.htm">effbot.org - Default Parameter Values in Python</a> </li>
<li> <a href="https://docs.python.org/3/reference/compound_stmts.html#function-definitions">Python documentation - Function definitions</a> </li>
</ul>

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
receive the class itself instead of a class instance. By convention, this first parameter is usually named "cls". Note that <code>__new__</code> and
<code>__init_subclass__</code> take a class as first argument even thought they are not decorated with <code>@classmethod</code>.</p>
<p>This rule raises an issue when an instance of class method does not have at least one positional parameter.</p>
<h2>Noncompliant Code Example</h2>
<pre>
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")
</pre>
<h2>Compliant Solution</h2>
<pre>
class MyClass:
Expand All @@ -21,5 +31,7 @@ <h2>Compliant Solution</h2>
print("static_method")
</pre>
<h2>See</h2>
<p> * Python documentation - <a href="https://docs.python.org/3.8/tutorial/classes.html#method-objects">Method Objects</a></p>
<ul>
<li> Python documentation - <a href="https://docs.python.org/3.8/tutorial/classes.html#method-objects">Method Objects</a> </li>
</ul>

Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,46 @@
parameter. This parameter will reference the object instance on which the method is called. By convention, this first parameter is named "self".</p>
<p>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.</p>
<p>Note also that creating methods which are used as static methods without the <code>@staticmethod</code> 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 <code>@staticmethod</code>.</p>
<p>This rule raises an issue when the first parameter of an instance method is not called "self".</p>
<h2>Noncompliant Code Example</h2>
<pre>
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
</pre>
<h2>Compliant Solution</h2>
<pre>
class MyClass:
def send_request(self, request):
print("send_request")

class ClassWithStaticMethod:
@staticmethod
def static_method(param):
print(param)
ClassWithStaticMethod().static_method(42)
</pre>
<h2>Exceptions</h2>
<p>This rule will also accept "cls" or "mcs" as first parameter's name for metaclasses' methods.</p>
<p>No issue will be raised for methods called <code>__init_subclass__</code>, <code>__class_getitem__</code> or <code>__new__</code> as these methods'
first parameter is a class.</p>
<p>You can also disable issues on methods decorated with a specific decorator. Add these decorators to this rule's "ignoreDecorators" parameter.</p>
<p>With "ignoredDecorators" set to "abstractmethod"</p>
<pre>
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
</pre>
<h2>See</h2>
<ul>
<li> Python documentation - <a href="https://docs.python.org/3.8/tutorial/classes.html#method-objects">Method Objects</a> </li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"status": "ready",
"tags": [
"convention",
"confusing"
"confusing",
"suspicious"
],
"defaultSeverity": "Critical",
"ruleSpecification": "RSPEC-5720",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ <h2>Compliant Solution</h2>
<h2>See</h2>
<ul>
<li> Python Documentation - <a href="https://docs.python.org/3/reference/datamodel.html#special-method-names">Special method names</a> </li>
<li> Python Documentation - <a href="https://docs.python.org/3/library/copy.html">copy module</a> </li>
</ul>

Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,13 @@ <h2>Noncompliant Code Example</h2>
<pre>
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
Expand All @@ -35,14 +31,10 @@ <h2>Noncompliant Code Example</h2>
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.")
</pre>
<h2>Compliant Solution</h2>
<pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"S2638",
"S2710",
"S2711",
"S2733",
"S2734",
"S2737",
"S2757",
Expand Down
2 changes: 1 addition & 1 deletion 2 sonarpedia.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.