Accessing attributes on `None` is almost always a logical error and will raise an `AttributeError`. To fix this issue, make sure not to access an attribute or method on a value that can be `None`. == Why is this an issue? `None` is a built-in object that represents the absence of a value. It is often used as a placeholder value for variables that only sometimes hold a value or as a return value for method calls that have no result. Attributes and methods of symbols that sometimes can be `None` should only be accessed in circumstances where it is certain that they are not set to `None`. Otherwise, an `AttributeError` is raised, and the program is interrupted. Hence, this issue indicates a logical error as it results from incorrect assumptions about the state of variables or the results of computations. === What is the potential impact? include::../../../shared_content/layc/exception-impact.adoc[] If a `None` value can be induced by user input, this issue may even be exploited by attackers to disrupt your application or gain information from stack traces. === Exceptions `None` does support a fixed set of special attributes like `++__class__++` or `++__bool__++`, and this issue is not raised when accessing these attributes. == How to fix it If your code contains `if-else` statements or similar constructs where some branches potentially assign the `None` value to a variable, you must ensure that this variable is handled safely afterwards. I.e., its attributes should not be accessed at all or only after explicitly confirming that it is not `None`. Similarly, for any function calls that can return `None` under certain conditions, carefully confirm that your code avoids these conditions. Again, the safest approach is to check for a `None` return value explicitly. === Code examples ==== Noncompliant code example [source,python,diff-id=1,diff-type=noncompliant] ---- def render(file_path): if os.path.isfile(file_path): data = interpret_csv(file_path) else: data = None # ... data.plot_graph() # Noncompliant ---- ==== Compliant solution [source,python,diff-id=1,diff-type=compliant] ---- def render(file_path): if os.path.isfile(file_path): data = interpret_csv(file_path) else: data = None # ... if data is not None: data.plot_graph() else: print("No data available.") ---- === How does this work? In the given example, the function `render` tries to load information into a variable `data`, depending on whether `file_path` is a path to a file. If this is not the case, `None` is assigned to `data`. At the end of the function, a method `plot_graph()` is called on `data`. The call is sure to fail if `data` was assigned to `None`. This is prevented by checking first whether `data` is not `None` before performing the call. == Resources === Documentation * The Python Data Model on https://docs.python.org/3/reference/datamodel.html#none[None] * https://docs.python.org/3/library/exceptions.html#AttributeError[Attribute Error] * https://docs.python.org/3/reference/expressions.html#attribute-references[Attribute References] === Articles & blog posts * CVE - https://cwe.mitre.org/data/definitions/476[CWE-476: - NULL Pointer Dereference] 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[]