I understand how to use hy.read_str
and hy.eval
from python to evaluate an hy
expression from within python. However, when I use this methodology, imports and globals are not shared between the hy
and python
environments. Consider this example:
import hy
def hyeval(x=None):
if x is None:
return None
try:
return hy.eval(hy.read_str(str(x)))
except Exception as e:
print('!!! exception: {}'.format(e))
return None
import datetime # this is ignored within `hyeval` calls
now = hyeval('((. datetime datetime now))')
print('result: {}'.format(now))
This prints ...
!!! exception: name 'datetime' is not defined
result: None
Even if I do the following, it generates the same exception ...
... etc. ...
hyeval('(import datetime)')
now = hyeval('((. datetime datetime now))')
print('result: {}'.format(now))
I have to explicitly import datetime
within the string
passed to my hyeval
function ...
... etc. ...
now = hyeval('((do (import datetime) (. datetime datetime now)))')
print('result: {}'.format(now))
This properly prints the following ...
result: 2017-09-22 09:41:49.771139
If I re-invoke the ((. datetime datetime now))
call via a string, I have to keep repeating the (import datetime)
call via a (do ...)
block.
Is there any way when invoking hy
strings from within python that imports and globals can be remembered between successive calls to hy.read_str/hy.eval
, or that the python globals and imports can be recognized when invoking strings via hy
?
I figured it out: if the second argument to hy.eval
is globals()
, the python environment's globals and imports are available when performing the hy
string evaluation ...
import hy
def hyeval(x=None, g=None):
if x is None:
return None
try:
if not g:
g = globals()
return hy.eval(hy.read_str(str(x)), g)
except Exception as e:
print('!!! exception: {}'.format(e))
return None
import datetime
now = hyeval('((. datetime datetime now))')
print('result: {}'.format(now))
This correctly prints the following ...
result: 2017-09-22 10:25:36.752656