rspec/rules/S3985/python/rule.adoc
2023-08-04 15:34:27 +02:00

60 lines
2.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

include::../summary.adoc[]
== Why is this an issue?
"Private" nested classes that are never used inside the enclosing class are usually dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.
Python has no real private classes. Every class is accessible. There are however two conventions indicating that a class is not meant to be "public":
* classes with a name starting with a single underscore (ex: ``++_MyClass++``) should be seen as non-public and might change without prior notice. They should not be used by third-party libraries or software. It is ok to use those classes inside the library defining them but it should be done with caution.
* "class-private" classes are defined inside another class, and have a name starting with at least two underscores and ending with at most one underscore. These classes' names will be automatically mangled to avoid collision with subclasses' nested classes. For example ``++__MyClass++`` will be renamed as ``++_classname__MyClass++``, where ``++classname++`` is the enclosing class's name without its leading underscore(s). Class-Private classes shouldn't be used outside of their enclosing class.
This rule raises an issue when a private nested class (either with one or two leading underscores) is never used inside its parent class.
=== Code examples
==== Noncompliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
class TopLevel:
class __Nested(): # Noncompliant: __Nested is never used
pass
----
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
class TopLevel:
class __Nested():
pass
def process(self):
return TopLevel.__Nested()
----
== Resources
* https://docs.python.org/3.8/tutorial/classes.html#private-variables[Python documentation Private Variables]
* https://www.python.org/dev/peps/pep-0008/#designing-for-inheritance[PEP 8 Style Guide for Python Code]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::../message.adoc[]
include::../highlighting.adoc[]
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]