In trying to create a Python function similar to Sage's var()
or function()
, I've encountered an apparently not-so-trivial problem in Python. Essentially, calling var('x')
in Sage not only returns a Sage symbolic expression, but does the equivalent of x = SR.var('x')
, i.e. it assigns the expression object to a variable in the current global namespace (the namespace of the calling module).
My question is, how the heck does it do that? If I do something like this:
in B.py
:
def func():
globals()['x'] = something
in A.py
from B import func
func()
I can only affect the variables in module B
's global namespace, not the calling module A
's global namespace.
Yet, the file var.pyx
distributed with my version of Sage looks like this:
...
def var(*args, **kwds):
if len(args)==1:
name = args[0]
else:
name = args
G = globals() # this is the reason the code must be in Cython.
if 'ns' in kwds:
# ...
# not relevant
v = SR.var(name, **kwds)
if isinstance(v, tuple):
for x in v:
G[repr(x)] = x
else:
G[repr(v)] = v
return v
...
In particular, the comment about Cython seems intriguing. I don't know much about Cython, so maybe that's my problem. If this is some special aspect of Cython, how would one go about replicating this function in "regular Python"/CPython?
PS: Yes, I realize that in general, such behavior is a bad idea. I'm mainly asking out of curiosity.