# Buggy code
def hardcoded_password_string(context):
    """**B105: Test for use of hard-coded password strings**

    The use of hard-coded passwords increases the possibility of password
    guessing tremendously. This plugin test looks for all string literals and
    checks the following conditions:

    - assigned to a variable that looks like a password
    - assigned to a dict key that looks like a password
    - used in a comparison with a variable that looks like a password

    Variables are considered to look like a password if they have match any one
    of:

    - "password"
    - "pass"
    - "passwd"
    - "pwd"
    - "secret"
    - "token"
    - "secrete"

    Note: this can be noisy and may generate false positives.

    **Config Options:**

    None

    :Example:

    .. code-block:: none

        >> Issue: Possible hardcoded password '(root)'
           Severity: Low   Confidence: Low
           Location: ./examples/hardcoded-passwords.py:5
        4 def someFunction2(password):
        5     if password == "root":
        6         print("OK, logged in")

    .. seealso::

        - https://www.owasp.org/index.php/Use_of_hard-coded_password

    .. versionadded:: 0.9.0

    """
    node = context.node
    if isinstance(node.parent, ast.Assign):
        # looks for "candidate='some_string'"
        for targ in node.parent.targets:
            if isinstance(targ, ast.Name) and RE_CANDIDATES.search(targ.id):
                return _report(node.s)

    elif isinstance(node.parent, ast.Index) and RE_CANDIDATES.search(node.s):
        # looks for "dict[candidate]='some_string'"
        # assign -> subscript -> index -> string
        assign = node.parent.parent.parent
        if isinstance(assign, ast.Assign) and isinstance(assign.value, ast.Str):
            return _report(assign.value.s)

    elif isinstance(node.parent, ast.Compare):
        # looks for "candidate == 'some_string'"
        comp = node.parent
        if isinstance(comp.left, ast.Name):
            if RE_CANDIDATES.search(comp.left.id):
                if isinstance(comp.comparators[0], ast.Str):
                    return _report(comp.comparators[0].s)


# Traceback (AttributeError)
from bandit.core.config import BanditConfig
from bandit.core.meta_ast import BanditMetaAst
from bandit.core.metrics import Metrics
from bandit.core.node_visitor import BanditNodeVisitor
from bandit.core.test_set import BanditTestSet
from pyflakes.checker import Checker
import ast
profile = {}
bnv = BanditNodeVisitor(
...     'filename',
...     BanditMetaAst(),
...     BanditTestSet(BanditConfig(), profile=profile),
...     False,
...     [],
...     Metrics(),
... )
tree = ast.parse("""def test():
...     try:
...         x = 5
...         if True:
...             x = 10  # noqa: F841
...     except AttributeError:
...         pass
... """)
bnv.generic_visit(tree)
Checker(tree=tree)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 673, in __init__
self.runDeferred(self._deferredFunctions)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 710, in runDeferred
handler()
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1474, in runFunction
self.handleChildren(node, omit='decorator_list')
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1073, in handleChildren
self.handleNode(node, tree)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1120, in handleNode
handler(node)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1623, in TRY
self.handleNode(child, node)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1120, in handleNode
handler(node)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1073, in handleChildren
self.handleNode(node, tree)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1120, in handleNode
handler(node)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1073, in handleChildren
self.handleNode(node, tree)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1120, in handleNode
handler(node)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1353, in NAME
self.handleNodeStore(node)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 1017, in handleNodeStore
self.addBinding(node, binding)
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 876, in addBinding
not self.differentForks(node, existing.source)):
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 857, in differentForks
if self.descendantOf(lnode, items, ancestor) ^ \
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 835, in descendantOf
if self.getCommonAncestor(node, a, stop):
File "/tmp/t/venv/lib/python3.5/site-packages/pyflakes/checker.py", line 827, in getCommonAncestor
if (lnode.depth > rnode.depth):
AttributeError: 'ExceptHandler' object has no attribute 'depth'

# Fixed code
def hardcoded_password_string(context):
    """**B105: Test for use of hard-coded password strings**

    The use of hard-coded passwords increases the possibility of password
    guessing tremendously. This plugin test looks for all string literals and
    checks the following conditions:

    - assigned to a variable that looks like a password
    - assigned to a dict key that looks like a password
    - used in a comparison with a variable that looks like a password

    Variables are considered to look like a password if they have match any one
    of:

    - "password"
    - "pass"
    - "passwd"
    - "pwd"
    - "secret"
    - "token"
    - "secrete"

    Note: this can be noisy and may generate false positives.

    **Config Options:**

    None

    :Example:

    .. code-block:: none

        >> Issue: Possible hardcoded password '(root)'
           Severity: Low   Confidence: Low
           Location: ./examples/hardcoded-passwords.py:5
        4 def someFunction2(password):
        5     if password == "root":
        6         print("OK, logged in")

    .. seealso::

        - https://www.owasp.org/index.php/Use_of_hard-coded_password

    .. versionadded:: 0.9.0

    """
    node = context.node
    if isinstance(node._bandit_parent, ast.Assign):
        # looks for "candidate='some_string'"
        for targ in node._bandit_parent.targets:
            if isinstance(targ, ast.Name) and RE_CANDIDATES.search(targ.id):
                return _report(node.s)

    elif isinstance(node._bandit_parent, ast.Index) and RE_CANDIDATES.search(node.s):
        # looks for "dict[candidate]='some_string'"
        # assign -> subscript -> index -> string
        assign = node._bandit_parent._bandit_parent._bandit_parent
        if isinstance(assign, ast.Assign) and isinstance(assign.value, ast.Str):
            return _report(assign.value.s)

    elif isinstance(node._bandit_parent, ast.Compare):
        # looks for "candidate == 'some_string'"
        comp = node._bandit_parent
        if isinstance(comp.left, ast.Name):
            if RE_CANDIDATES.search(comp.left.id):
                if isinstance(comp.comparators[0], ast.Str):
                    return _report(comp.comparators[0].s)