-1

I am trying to write some kind of wrapper for testing python module. This wrapper simulates an environment and then starts other python module via execfile. There are many python modules to be tested (>200).

Inside those modules there are some hard-coded variables that contain some absolute file-paths, that are not existing in my simulated environment (I also cannot create them). Those file-paths are paths to option files, that the script will read in. There is always exactly one option-file for each module and the file-path to thisoption files is always saved in the same global variable (What I mean: The variable name is the same in each module: optionFile).

optionFile = "Path to Option file"

My thought was, that I could maybe pre-set this global variable "optionFile" with an existing path before I execute the test-module. But of course this alone won't help, since the executed module will just overwrite "optionFile" with the hard-coded value when it is executed.

I wondered if there might be a way to overwrite the __setattr__ function of the globals-object, so that it will do nothing for certain variable names, but I was not successful with my tries. Do you think this could work and have any suggestions?

and0r
  • 305
  • 1
  • 4
  • 13
  • 1
    What is the nature of the code in the module? If it's all at the module top-level you may be out of luck. That is, if a file has `optionFile = "/some/path"` and then on the very next line it does `open(optionFile)`, you're not going to be able to change the value of `optionFile` in between. You might have better luck monkeypatching the `open` function (or whatever other functions the modules use to interact with `optionFile`). – BrenBarn Jan 23 '17 at 08:01
  • Good interpretation: What you described is exactly the nature of the python module :( . How could I do it with the open-function? ...because this could actually work, since all extensions of those option-files are the same (.opt). If I make the open Function "reroute" all opening-requests to files that are ending with '.opt' to a hardcodet version (my replacementoption-file), this could work? – and0r Jan 23 '17 at 08:21
  • The question seems unclear to me, the title asks for ways to prevent variables from being altered however the body asks for ways to alter variables? – Stop harming Monica Jan 23 '17 at 08:30
  • Actually the body does indeed aks for a way to prevent variables from beeing altered: You should find that in the last paragraph, which is the actual question. The other paragraphs try to explain why I would need that. Can you explain, what is not clear to you, then I will try to edit the question. – and0r Jan 23 '17 at 09:17
  • @and0r: It is possible. Again, you would need to provide more details and examples of what the code *does*. Basically, you can't "freeze" `optionFile`, but you *might* be able to replace the functions that use it with patched versions that reroute to another file as you describe. However, whether you can do this depends on what is done with `optionFile`. If there are 500 different functions that call it, replacing them all may be impractical. – BrenBarn Jan 23 '17 at 19:17

1 Answers1

0

Based on the first impressions we got here it seems to be not possible to alter the __setattr__ of the globals object (though I don't understand why not...)

So the answer seems to be "No".

EDIT:
The reason, why this does not work here is, that there is no global "globals "-object. Instead each module has its "personal" namespace with its own global variables. This namespace is created once the module is loaded. It is for sure possible to alter that global namespace - but only after the module has already been loaded (which does not help in my application scenario). Thanks to BrenBarn for the clarification.
END OF EDIT

A workaround for my specific described problem would be to alter Python's built-in open-function instead.

# Keep original pointer to the actual Open-function
realOpen = open

# Overwrite the name of the Open-function to implement own logic
def open(filename, mode='r'):
    if filename.endswith(".opt"):
        print "Rerouting opening command"
        realOpen("myCentralOptionFile.opt","r")

    else:
        realOpen(filename,mode)

Attention: This workaround has nothing to do with the title anymore.

and0r
  • 305
  • 1
  • 4
  • 13
  • 1
    There is no "globals object". Global variables are stored in the module namespace. It is indeed possible to alter that namespace, but the problem is that you can't do it until after the module is loaded, by which point all the code will have already run and done whatever it wanted to do with `optionFile`. What you want is to run just part of the module (the part that defines `optionFile`), and then "pause" to change its value, but you can't do that. It's all or nothing: you either run the whole module or don't run it at all. – BrenBarn Jan 23 '17 at 19:20