From: <bc...@wo...> - 2001-01-25 11:16:55
|
[William Byrd] >[...] >The getLocals() method returns a >*reference* to the PythonInterpreter.locals object, rather than a deep copy. >The result is that the object referenced by 'initialState' is modified when >I make additional calls to PythonInterpreter.exec(). > >Peeking at the source code for PythonInterpreter allowed me to create the >following hack: > > ... Set up the initial state of myInterpreter, as before ... > > // Save the initial state of myInterpreter. > PyStringMap localsMap = (PyStringMap) > myInterpreter.getLocals(); > PyObject initialState = (PyObject) localsMap.copy(); > > ... Change the state of myInterpreter, as before ... > > // Restore the initial state of myInterpreter. > myInterpreter.setLocals(((PyStringMap) > initialState).copy()); > >Of course, this code will break if the return type of getLocals() ever >changes. Right. While the odds are low for that to happen the hack of casting to a specific subtype is both wrong and fragile. The right (IMO) way is use only the methods on PyObject to call the methods in the PyStringMap: ... Set up the initial state of myInterpreter, as before .. // Save the initial state of myInterpreter. PyObject localsMap = myInterpreter.getLocals(); PyObject initialState = localsMap.invoke("copy"); ... Change the state of myInterpreter, as before ... // Restore the initial state of myInterpreter. myInterpreter.setLocals(initialState.invoke("copy")); This will work as long as the "locals" is an object that conforms to the mapping interface (whatever that actually mean). This is true for both PyStringMap and PyDictionary as well as any python object that implement the __[get|set]item__ and copy methods. >How can I achieve the same result without resorting to a hack? Should >getLocals() return a deep copy of PythonInterpreter.locals? No. >Am I using the getLocals() and setLocals() inappropriately? No. regards, finn |