Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# if they will be completed
if isinstance(node, astroid.While):
return True
if isinstance(node, astroid.Raise):
# a Raise statement doesn't need to end with a return statement
# but if the exception raised is handled, then the handler has to
# ends with a return statement
if not node.exc:
# Ignore bare raises
return True
if not utils.is_node_inside_try_except(node):
# If the raise statement is not inside a try/except statement
# then the exception is raised and cannot be caught. No need
# to infer it.
return True
exc = utils.safe_infer(node.exc)
if exc is None or exc is astroid.Uninferable:
return False
exc_name = exc.pytype().split('.')[-1]
handlers = utils.get_exception_handlers(node, exc_name)
handlers = list(handlers) if handlers is not None else []
if handlers:
# among all the handlers handling the exception at least one
# must end with a return statement
return any(self._is_node_return_ended(_handler) for _handler in handlers)
# if no handlers handle the exception then it's ok
return True
if isinstance(node, astroid.If):
# if statement is returning if there are exactly two return statements in its
# children : one for the body part, the other for the orelse part
# Do not check if inner function definition are return ended.
return_stmts = [self._is_node_return_ended(_child) for _child in node.get_children()
def _check_membership_test(self, node):
if is_inside_abstract_class(node):
return
if is_comprehension(node):
return
inferred = safe_infer(node)
if inferred is None or inferred is astroid.Uninferable:
return
if not supports_membership_test(inferred):
self.add_message(
"unsupported-membership-test", args=node.as_string(), node=node
)
def _check_reversed(self, node):
""" check that the argument to `reversed` is a sequence """
try:
argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
except utils.NoSuchArgumentError:
pass
else:
if argument is astroid.YES:
return
if argument is None:
# Nothing was infered.
# Try to see if we have iter().
if isinstance(node.args[0], astroid.Call):
try:
func = next(node.args[0].func.infer())
except astroid.InferenceError:
return
if (getattr(func, 'name', None) == 'iter' and
utils.is_builtin_object(func)):
self.add_message('bad-reversed-sequence', node=node)
msg = "unsubscriptable-object"
elif node.ctx == astroid.Store:
supported_protocol = supports_setitem
msg = "unsupported-assignment-operation"
elif node.ctx == astroid.Del:
supported_protocol = supports_delitem
msg = "unsupported-delete-operation"
if isinstance(node.value, astroid.SetComp):
self.add_message(msg, args=node.value.as_string(), node=node.value)
return
if is_inside_abstract_class(node):
return
inferred = safe_infer(node.value)
if inferred is None or inferred is astroid.Uninferable:
return
if not supported_protocol(inferred):
self.add_message(msg, args=node.value.as_string(), node=node.value)
def visit_call(self, node):
func = utils.safe_infer(node.func)
if (
isinstance(func, astroid.BoundMethod)
and isinstance(func.bound, astroid.Instance)
and func.bound.name in ("str", "unicode", "bytes")
):
if func.name in ("strip", "lstrip", "rstrip") and node.args:
arg = utils.safe_infer(node.args[0])
if not isinstance(arg, astroid.Const) or not isinstance(arg.value, str):
return
if len(arg.value) != len(set(arg.value)):
self.add_message(
"bad-str-strip-call",
node=node,
args=(func.bound.name, func.name),
)
elif func.name == "format":
self._check_new_format(node, func)
)
structs = (astroid.Dict, astroid.Tuple, astroid.Set)
# These nodes are excepted, since they are not constant
# values, requiring a computation to happen.
except_nodes = (
astroid.Call,
astroid.BinOp,
astroid.BoolOp,
astroid.UnaryOp,
astroid.Subscript,
)
inferred = None
emit = isinstance(test, (astroid.Const,) + structs + const_nodes)
if not isinstance(test, except_nodes):
inferred = utils.safe_infer(test)
if emit:
self.add_message("using-constant-test", node=node)
elif isinstance(inferred, const_nodes):
# If the constant node is a FunctionDef or Lambda then
# it may be a illicit function call due to missing parentheses
call_inferred = None
if isinstance(inferred, astroid.FunctionDef):
call_inferred = inferred.infer_call_result()
elif isinstance(inferred, astroid.Lambda):
call_inferred = inferred.infer_call_result(node)
if call_inferred:
try:
for inf_call in call_inferred:
if inf_call != astroid.Uninferable:
self.add_message(
def visit_name(self, node):
"""Detect when a "bad" built-in is referenced."""
node_infer = utils.safe_infer(node)
if not utils.is_builtin_object(node_infer):
# Skip not builtin objects
return
if node_infer.name == 'eval':
self.add_message('eval-referenced', node=node)
def visit_callfunc(self, node):
"""check that called functions/methods are inferred to callable objects,
and that the arguments passed to the function match the parameters in
the inferred function's definition
"""
# Build the set of keyword arguments, checking for duplicate keywords,
# and count the positional arguments.
keyword_args = set()
num_positional_args = 0
for arg in node.args:
if isinstance(arg, astroid.Keyword):
keyword_args.add(arg.arg)
else:
num_positional_args += 1
called = safe_infer(node.func)
# only function, generator and object defining __call__ are allowed
if called is not None and not called.callable():
self.add_message('not-callable', node=node,
args=node.func.as_string())
self._check_uninferable_callfunc(node)
try:
called, implicit_args, callable_name = _determine_callable(called)
except ValueError:
# Any error occurred during determining the function type, most of
# those errors are handled by different warnings.
return
num_positional_args += implicit_args
if called.args.args is None:
# Built-in functions have no argument information.
index_type.getattr("__index__")
return
except exceptions.NotFoundError:
pass
invalid_slices += 1
if not invalid_slices:
return
# Anything else is an error, unless the object that is indexed
# is a custom object, which knows how to handle this kind of slices
parent = node.parent
if isinstance(parent, astroid.ExtSlice):
parent = parent.parent
if isinstance(parent, astroid.Subscript):
inferred = safe_infer(parent.value)
if inferred is None or inferred is astroid.Uninferable:
# Don't know what this is
return
known_objects = (
astroid.List,
astroid.Dict,
astroid.Tuple,
astroid.objects.FrozenSet,
astroid.Set,
)
if not isinstance(inferred, known_objects):
# Might be an instance that knows how to handle this slice object
return
for _ in range(invalid_slices):
self.add_message("invalid-slice-index", node=node)
def _should_exempt_from_invalid_name(node):
if node_type == "variable":
inferred = utils.safe_infer(node)
if isinstance(inferred, astroid.ClassDef):
return True
return False