I'm trying to make a function in Python that does the equivalent of compile(), but also lets me get the original string back. Let's call those two functions comp() and decomp(), for disambiguation purposes. That is,
a = comp("2 * (3 + x)", "", "eval")
eval(a, dict(x=3)) # => 12
decomp(a) # => "2 * (3 + x)"
The returned string does not have to be identical ("2*(3+x)" would be acceptable), but it needs to be basically the same ("2 * x + 6" would not be).
Here's what I've tried that doesn't work:
- Setting an attribute on the code object returned by compile. You can't set custom attributes on code objects.
- Subclassing code so I can add the attribute. code cannot be subclassed.
- Setting up a WeakKeyDictionary mapping code objects to the original strings. code objects cannot be weakly referenced.
Here's what does work, with issues:
- Passing in the original code string for the filename to compile(). However, I lose the ability to actually keep a filename there, which I'd like to also do.
- Keeping a real dictionary mapping code objects to strings. This leaks memory, although since compiling is rare, it's acceptable for my current use case. I could probably run the keys through gc.get_referrers periodically and kill off dead ones, if I had to.