Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def handle_call(expr, dive: bool = True) -> Optional[Union[Token, Iterator[Token]]]:
token_info = dict(line=expr.lineno, col=expr.col_offset)
name = get_name(expr.func)
if name and name == 'exit':
return Token(value=SystemExit, **token_info)
# sys.exit()
if isinstance(expr.func, TOKENS.ATTR):
name = get_name(expr.func)
if name and name == 'sys.exit':
return Token(value=SystemExit, **token_info)
# infer function call and check the function body for raises
if dive:
return _exceptions_from_func(expr=expr)
return None
def handle_bin_op(expr, **kwargs) -> Optional[Token]:
token_info = dict(line=expr.lineno, col=expr.col_offset)
if isinstance(expr.op, ast.Div) or expr.op == '/':
if isinstance(expr.right, astroid.node_classes.NodeNG):
guesses = infer(expr=expr.right)
token_info['col'] = expr.right.col_offset
for guess in guesses:
if type(guess) is not astroid.Const:
continue
return Token(value=ZeroDivisionError, **token_info)
if isinstance(expr.right, ast.Num) and expr.right.n == 0:
token_info['col'] = expr.right.col_offset
return Token(value=ZeroDivisionError, **token_info)
return None
def handle_with(expr) -> Optional[Token]:
token_info = dict(line=expr.lineno, col=expr.col_offset)
for item in expr.items:
if isinstance(item, ast.withitem):
item = item.context_expr
else:
item = item[0]
if _is_pathlib_write(item):
return Token(value='Path.open', **token_info)
if not isinstance(item, TOKENS.CALL):
continue
name = get_name(item.func)
if name == 'open':
if _is_open_to_write(item):
return Token(value='open', **token_info)
return None
def _exceptions_from_func(expr) -> Iterator[Token]:
for value in infer(expr.func):
if type(value) is not astroid.FunctionDef:
continue
# recursively infer exceptions from the function body
for error in get_exceptions(body=value.body, dive=False):
yield Token(value=error.value, line=expr.lineno, col=expr.col_offset)
# get explicitly specified exceptions from `@deal.raises`
if not value.decorators:
continue
for category, args in get_contracts(value.decorators.nodes):
if category != 'raises':
continue
for arg in args:
name = get_name(arg)
if name is None:
continue
yield Token(value=name, line=expr.lineno, col=expr.col_offset)
return None
def handle(self, expr, **kwargs):
handler = self.handlers.get(type(expr))
if not handler:
return
token = handler(expr=expr, **kwargs)
if token is None:
return
if type(token) is Token:
yield token
return
yield from token
def handle_name_constant(expr: ast.NameConstant) -> Optional[Token]: # pragma: py>=38
if expr.value:
return None
return Token(value=expr.value, line=expr.lineno, col=expr.col_offset)
def handle_call(expr) -> Optional[Token]:
token_info = dict(line=expr.lineno, col=expr.col_offset)
name = get_name(expr.func)
if name in ('print', 'sys.stdout', 'sys.stderr'):
return Token(value=name, **token_info)
if name in ('sys.stdout.write', 'sys.stderr.write'):
return Token(value=name[:-6], **token_info)
if name == 'open':
if _is_open_to_write(expr):
return Token(value='open', **token_info)
if _is_pathlib_write(expr):
return Token(value='Path.open', **token_info)
return None
for category, contract_args in get_contracts(func.decorators.nodes):
if category != 'pre':
continue
contract = Contract(
args=contract_args,
category=Category.PRE,
func_args=func_args,
)
try:
result = contract.run(*args, **kwargs)
except NameError:
continue
if result is False or type(result) is str:
msg = _format_message(args, kwargs)
yield Token(value=msg, line=expr.lineno, col=expr.col_offset)
def handle_raise(expr, **kwargs) -> Optional[Token]:
token_info = dict(line=expr.lineno, col=expr.col_offset)
name = get_name(expr.exc)
if not name:
# raised a value, too tricky
if not isinstance(expr.exc, TOKENS.CALL):
return None
# raised an instance of an exception
name = get_name(expr.exc.func)
if not name or name[0].islower():
return None
exc = getattr(builtins, name, name)
token_info['col'] = expr.exc.col_offset
return Token(value=exc, **token_info)
def handle_returns(expr) -> Optional[Token]:
# inner_extractor
for token in inner_extractor.handle(expr=expr.value):
return token
# astroid inference
if hasattr(expr.value, 'infer'):
for value in infer(expr.value):
if isinstance(value, astroid.Const):
token_info = dict(line=expr.lineno, col=expr.value.col_offset)
return Token(value=value.value, **token_info)
return None