Python Forum

Full Version: is an f-sting not a literal?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
is an f-sting not a literal? it fails in ast.literal_eval():
Output:
lt2a/forums /home/forums 4> py Python 3.6.9 (default, Jan 26 2021, 15:33:00) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import ast >>> a='f"""hello Python forum"""' >>> b=ast.literal_eval(a) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.6/ast.py", line 85, in literal_eval return _convert(node_or_string) File "/usr/lib/python3.6/ast.py", line 84, in _convert raise ValueError('malformed node or string: ' + repr(node)) ValueError: malformed node or string: <_ast.JoinedStr object at 0x7f42dd9486a0> >>> a='"""hello Python forum"""' >>> b=ast.literal_eval(a) >>> b 'hello Python forum' >>> lt2a/forums /home/forums 5>
This ain't f-string: 'f"""hello Python forum"""'

No fail with actual f-string:

>>> a = f'"""hello Python forum"""'
>>> ast.literal_eval(a)
'hello Python forum'
I think it doesn't work because f-strings allow dynamic behavior that is forbidden by literal_eval(). Example:
>>> class A:
...     def __getitem__(self, key):
...         print('Now erasing the whole filesystem...')
... 
>>> x = A()
>>> a = 'f"""{x[3]}"""'
>>> eval(a)
Now erasing the whole filesystem...
'None'
>>> import ast
>>> ast.literal_eval(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/ast.py", line 99, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python3.8/ast.py", line 98, in _convert
    return _convert_signed_num(node)
  File "/usr/lib/python3.8/ast.py", line 75, in _convert_signed_num
    return _convert_num(node)
  File "/usr/lib/python3.8/ast.py", line 66, in _convert_num
    _raise_malformed_node(node)
  File "/usr/lib/python3.8/ast.py", line 63, in _raise_malformed_node
    raise ValueError(f'malformed node or string: {node!r}')
ValueError: malformed node or string: <_ast.JoinedStr object at 0x7f939adfda00>
> No fail with actual f-string

but a is just a string after the literal is done. i an referring to the source code in the string being passed to the eval function. because of what i could get i'm trying to figure out how to interpret the f-string, which needs one of the quotes when my contents for the f-string could have any of the four possible quotes. i am trying to make a function that interprets an f-string.

foo = 'hi there'
bar = 'python forum'
s = '{foo} {bar}
a = f'{foo} {bar}'
b = fstring(s)
print(a)
print(b)
a and b should end up being the same. the intent is that fstring() does what the f in the source literal does, by different means.

an f-string is not a new data type. it is a literal modifier for a string literal that has the compiler build dynamic code that runs when control reaches the liter itself.
I suggest
s.format(**locals())
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a=4
>>> b=5
>>> f'{a+b}'
'9'
>>> '{a+b}'.format(**locals())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'a+b'
>>>
You could perhaps use module future-fstrings from pypi
>>> from future_fstrings import fstring_decode
>>> s = 'f"{a+b}"'
>>> text, _ = fstring_decode(s.encode())
>>> print(text)
"{}".format((a+b))
i'll have to go run a better python than 3.6 which i am currently on. i'll start a new AWS instance tomorrow that has 3.8.5. but i need to get to bed right now, if i can stay awake till then.