Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
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:
if isinstance(expr, astroid.node_classes.NodeNG):
# AttributeError: 'AsStringVisitor3' object has no attribute 'visit_unknown'
with suppress(AttributeError): # pragma: no cover
renderred = expr.as_string()
with suppress(ValueError, SyntaxError):
return ast.literal_eval(renderred)
handler = inner_extractor.handlers.get(type(expr))
if handler:
value = handler(expr=expr)
if value is not UNKNOWN:
return value
# astroid inference
if hasattr(expr, 'infer'):
for parent_expr in infer(expr=expr):
if parent_expr == expr: # avoid recursion
continue
value = get_value(expr=parent_expr)
if value is not UNKNOWN:
return value
return UNKNOWN
def handle_assert(expr) -> Optional[Token]:
# inner_extractor
for token in inner_extractor.handle(expr=expr.test):
return token
# astroid inference
if hasattr(expr.test, 'infer'):
for value in infer(expr.test):
if not isinstance(value, astroid.Const):
continue
if value.value:
continue
return Token(value=value.value, line=expr.lineno, col=expr.col_offset)
return None
def _is_pathlib_write(expr) -> bool:
if not isinstance(expr, astroid.Call):
return False
if not isinstance(expr.func, astroid.Attribute):
return False
if expr.func.attrname not in ('write_text', 'write_bytes', 'open'):
return False
# if it's open, check that mode is "w"
if expr.func.attrname == 'open':
if not _is_open_to_write(expr):
return False
for value in infer(expr.func.expr):
if isinstance(value, astroid.Instance):
if value.pytype().startswith('pathlib.'):
return True
return False
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_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
def handle_astroid_call(expr: astroid.Call, *, dive: bool = True, stubs: StubsManager) -> Iterator[Token]:
extra = dict(
line=expr.lineno,
col=expr.col_offset,
)
for value in infer(expr=expr.func):
if type(value) is not astroid.FunctionDef:
continue
module_name, func_name = _get_full_name(expr=value)
stub = _get_stub(module_name=module_name, expr=value, stubs=stubs)
if stub is None:
continue
names = stub.get(func=func_name, contract=Category.RAISES)
for name in names:
name = getattr(builtins, name, name)
yield Token(value=name, **extra)