LibCST icon indicating copy to clipboard operation
LibCST copied to clipboard

[Feature Request] evaluated_value() method on [static] containers

Open jakkdl opened this issue 2 years ago • 2 comments

Integer.evaluated_value exists, so why not also a Tuple.evaluated_value, Dict.evaluated_value, etc?

Background: I just cobbled together this mess of a function:

def cst_literal_eval(node: cst.BaseExpression) -> Any:
    ast_node = cst.Module([cst.SimpleStatementLine([cst.Expr(node)])]).code
    try:
        return ast.literal_eval(ast_node)
    except Exception:
        return None

In flake8-trio, for seeing if for i in range(...) can be statically determined to run at least once, and would be great to just be able to call .evaluated_value on the node directly. (.code on something other than Module would also be neat, but that might be tricky).

jakkdl avatar Feb 28 '23 11:02 jakkdl

I'm not sure it's a good idea to provide a Tuple.evaluated_value, etc. Mainly because it's impossible to

  • correctly type hint it
  • make sure it's safe to evaluate (as in, it will return a meaningful value)

I'm open to adding a helper function like yours though - maybe somewhere in libcst.helpers, provided that some strong caveats are added in its documentation wrt. safety

zsol avatar May 25 '23 19:05 zsol

Sure, I don't think it matters if it's a class method or a helper function. And you're right that it's probably bad to elevate it to the same status as Integer.literal_eval given the risks & differences in functionality.

It should be relatively safe if it just evaluates literal values, but yeah it should have a warning label. This is the docstring for ast.literal_eval:

Evaluate an expression node or a string containing only a Python
expression.  The string or node provided may only consist of the following
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
sets, booleans, and None.

Caution: A complex expression can overflow the C stack and cause a crash.

jakkdl avatar Jun 01 '23 20:06 jakkdl