-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
97 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,19 @@ | ||
# built-in | ||
import ast | ||
from typing import Optional | ||
|
||
# external | ||
import astroid | ||
|
||
# app | ||
from .common import TOKENS, Extractor, Token, infer | ||
from .common import TOKENS, Extractor, Token | ||
from .value import UNKNOWN, get_value | ||
|
||
|
||
get_asserts = Extractor() | ||
inner_extractor = Extractor() | ||
|
||
|
||
@get_asserts.register(*TOKENS.ASSERT) | ||
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 | ||
|
||
|
||
# any constant value in astroid | ||
@inner_extractor.register(astroid.Const) | ||
def handle_const(expr: astroid.Const) -> Optional[Token]: | ||
if expr.value: | ||
return None | ||
return Token(value=expr.value, line=expr.lineno, col=expr.col_offset) | ||
|
||
|
||
# Python <3.8 | ||
# string, binary string | ||
@inner_extractor.register(ast.Str, ast.Bytes) | ||
def handle_str(expr) -> Optional[Token]: # pragma: py>=38 | ||
if expr.s: | ||
return None | ||
return Token(value=expr.s, line=expr.lineno, col=expr.col_offset) | ||
|
||
|
||
# Python <3.8 | ||
# True, False, None | ||
@inner_extractor.register(ast.NameConstant) | ||
def handle_name_constant(expr: ast.NameConstant) -> Optional[Token]: # pragma: py>=38 | ||
if expr.value: | ||
value = get_value(expr=expr.test) | ||
if value is UNKNOWN: | ||
return None | ||
return Token(value=expr.value, line=expr.lineno, col=expr.col_offset) | ||
|
||
|
||
# positive number | ||
@inner_extractor.register(ast.Num, getattr(ast, 'Constant', None)) | ||
def handle_num(expr) -> Optional[Token]: | ||
if expr.n: | ||
if value: | ||
return None | ||
return Token(value=expr.n, line=expr.lineno, col=expr.col_offset) | ||
return Token(value=value, line=expr.lineno, col=expr.col_offset + 7) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# built-in | ||
import ast | ||
from contextlib import suppress | ||
|
||
# external | ||
import astroid | ||
|
||
# app | ||
from .common import Extractor, infer | ||
|
||
|
||
inner_extractor = Extractor() | ||
UNKNOWN = object() | ||
|
||
|
||
def get_value(expr): | ||
if isinstance(expr, ast.AST): | ||
with suppress(ValueError, SyntaxError): | ||
return ast.literal_eval(expr) | ||
|
||
if isinstance(expr, astroid.node_classes.NodeNG): | ||
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 | ||
|
||
|
||
@inner_extractor.register(astroid.List, astroid.Set, astroid.Tuple) | ||
def handle_collections(expr): | ||
result = [] | ||
for element_expr in expr.elts: | ||
value = get_value(expr=element_expr) | ||
if value is UNKNOWN: | ||
return UNKNOWN | ||
result.append(value) | ||
|
||
if type(expr) is astroid.Tuple: | ||
return tuple(result) | ||
if type(expr) is astroid.Set: | ||
return set(result) | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters