Last active
November 24, 2020 13:03
-
-
Save jonafato/101567a28398765050311e37581c18d6 to your computer and use it in GitHub Desktop.
fparse.py
This file contains hidden or 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
import ctypes | |
import inspect | |
from parse import parse | |
def fparse(template, string): | |
parent_frame = inspect.currentframe().f_back | |
parent_frame.f_locals.update(parse(template, string).named) | |
ctypes.pythonapi.PyFrame_LocalsToFast( | |
ctypes.py_object(parent_frame), | |
ctypes.c_int(0), | |
) |
This file contains hidden or 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
# It works at the top level of a module | |
>>> from fparse import fparse | |
>>> fparse('The {animal} jumped over the {celestial_body}', 'The cow jumped over the moon') | |
>>> animal | |
'cow' | |
>>> celestial_body | |
'moon' |
This file contains hidden or 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
# It works inside of a function, but the names must be pre-defined. | |
# This only works because of the `PyFrame_LocalsToFast` call. | |
# Without it, the names don't make it into the function scope. | |
>>> def in_a_function(): | |
... animal = None | |
... celestial_body = None | |
... fparse('The {animal} jumped over the {celestial_body}', 'The cow jumped over the moon') | |
... print(animal, celestial_body) | |
... | |
>>> in_a_function() | |
cow moon |
This file contains hidden or 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
# If you don't pre-define the names, | |
# the function appears to work. | |
>>> def in_another_function(): | |
... fparse('The {animal} jumped over the {celestial_body}', 'The cow jumped over the moon') | |
... return locals() | |
... | |
>>> in_another_function() | |
{'animal': 'cow', 'celestial_body': 'moon'} |
This file contains hidden or 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
# However it does not. | |
# Instead, we get a `NameError`. | |
# As far as I'm aware, there's no way to make this work. | |
>>> def in_a_third_function(): | |
... fparse('The {animal} jumped over the {celestial_body}', 'The cow jumped over the moon') | |
... print(animal, celestial_body) | |
... | |
>>> in_a_third_function() | |
Traceback (most recent call last): | |
File "<stdin>", line 1, in <module> | |
File "<stdin>", line 3, in in_a_third_function | |
NameError: name 'animal' is not defined |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment