I need to scan a python file and figure out the value of an argument to a function. Take for example a file containing following code.
# start of file
path = "/a/b/c"
def main():
run(full_path=path, os="linux")
# end of file
I need to know what is the value of argument "full_path" without executing or importing this file.
I think any library which is used in developing IDEs can do it. Please help in case you have solved similar problems.
To give a little bit of background to the problem, I am running a server application hence cannot afford to execute any arbitrary python file and also I may not have all the related dependent packages in my environment in order to execute.
Related
I am trying to create a Shiny app where a user will choose a short string from a drop-down menu, that string will then be passed to a python script which will output some values which will be used in the shiny app.
Using reticulate's py_run_file function with the needed values hardcoded works great. However, using this:
py_run_file('test_script.py arg1')
gives this:
Error in py_run_file_impl(file, local, convert) :
Unable to open file 'test_script.py arg1' (does it exist?)
Several threads suggest using a system() call to run a .py script with command line arguments but I don't think that would be feasible for the goals because the argument needs to be able to change. Other threads have suggested creating a python file that calls the original python file using os.system() with arguments, but that also doesn't work for my situation.
Does anyone have any ideas?
Thanks
If anyone else is struggling with this problem: I found a workaround.
Instead of feeding an argument to the python script, I just create a R global environment variable then call it in the python script.
Had no idea you could reference R environment variables by calls such as r.RVar in the python script, similar to py$PythonVar when calling python variables in R scripts.
I would like to pass command line arguments to pycharm script from file.
I am aware command line arguments can be passed via run->edit configurations -> parameters.
This method is not good enough for me because
In some cases the parameters line gets deleted. not sure why, maybe git-pull? maybe other reason.
I want several configurations, and I want to save them in source control
I want to set those parameters programaticaly.
I think taking command-line arguments from some config file would solve all my problems.
How can I do that?
EDIT1:
Use case example, as it seems my point isn't perfectly clear:
I want to debug my code in pycharm with some configuration. add some breakpoints, go line by line.
Next I want to change configuration and debug again, with pycharm.
Doing this with some script that hacks the pycharm file where the run configurations are stored seems to me like going too far.
Does pycharm offer no way to give it command line parameters from file?
PyCharm lets you have unlimited named runtime configurations, as you appear to know, so I am a little puzzled that you ask. Click on the current configuraton name to the left of the green Run arrow, top right, then Edit Configurations.
These configurations live in workspace.xml. Nothing stopping you from checking it in.
For programs that take complex command line parameters it is traditional to provide a way to read the values from a named file, typically introduced by #. In argparse you specify this as follows:
parser = argparse.ArgumentParser(fromfile_prefix_chars='#')
Arguments read from a file must by default be one per line.
Create shell scripts calling the Python script the way you need.
I have a variable in my python script that holds the path to a file as a string. Is there a way, through a python module, etc, to keep the file path updated if the file were to be moved to another destination?
Short answer: no, not with a string.
Long answer: If you want to use only a string to record the location of this file, you're probably out of luck unless you use other tools to find the location of the file, or record whenever it moves - I don't know what those tools are.
You don't give a lot of info in your question about what you want this variable for; as #DeepSpace says in his comment, if you're trying to make this String follow the file between different runs of this program, then you'd be better off making an argument for the script. If, however, you expect the file to move sometime during the execution of your program, you might be able to use a file object to keep track of it. Or, rather - instead of keeping the filepath in memory, keep a file descriptor in memory instead (the kind you would generate by using the open() function, and just never close that file until the program terminates. You can use seek to return to the start of the file if you needed to read it multiple times. Problems with this include that it's not memory-safe, and it's absolutely not a best practice.
TL;DR
Your best bet is probably to go with a solution like #DeepSpace mentioned where you could go and call your script with a parameter in command-line which will then force the user to input a valid path.
This is actually a really good question, but unfortunately purely Pythonly speaking, this is impossible.
No python module will be able to dynamically linked a variable to a path on the file-system. You will need an external script or routine which will update any kind of data structure that will hold the path value.
Even then, the name of the file could change, but not it's location. here is what I mean by that.
Let's say you were to wrapped that file in a folder only containing that specific file. Since you now know that it's location is fixed (theoretically speaking), you can have another python script/routine that will read the filename and store it in a textfile. Your other script could go and get that file name (considering your routine would sync that file on a regular basis). But, as soon as the location of the file changes, how can you possibly know where it is now. It has to be manually hard coded somewhere to have something close to the behavior your expecting.
Note that my example is not in any way a solution to go-to for your problem. I'm actually trying to underline the shortcomings of such a feature.
I was thinking of how you execute code only once in Python. What I mean is setup code like when you set-up software; it only happens once and remembers you have already set up the software when you start the program again.
So in a sense I only want Python to execute a function once and not execute the function again even if the program is restarted.
you could create a file once set up is complete for example an empty .txt file and then check if it exists when program runs and if not runs setup
to check weather a file exists you can use os.pathlike so
import os.path
if not os.path.exists(file_path):
#run start up script
file = open (same_name_as_file_path, "w") #creates our file to say startup is complete you could write to this if you wanted as well
file.close
In addition to the method already proposed you may use pickle to save boolean variables representing whether some functions were executed (useful if you have multiple checks to carry out)
import pickle
f1_executed=True
f2_executed=False
pickle.dump([f1_executed,f2_executed],open("executed.pkl",mode='wb'))
##### Program Restarted #####
pickle.load(open("executed.pkl",mode='rb'))
If you need a kind of Setup-Script to install a program or to setup your operating system's environment, then I would go even further. Imagine that your setup became inconsistent in the mean-time and the program does not work properly anymore. Then it would be good to provide the user a script to repair that.
If you execute the script the second time, then you can:
either check, if the setup was correct and print an error message to the user, if the setup became inconsistent in the mean-time
or check the setup and repair it automatically, if inconsistent
Just reading a text file or something similar (f.e. storing a key in the registry of windows) may bring you into the situation that the setup became inconsistent, but your setup-script will say that everything is fine, because the text file (or the registry key) has been found.
Furthermore, if doing so, this facilitates also to "uninstall" your program. Since you know exactly what has been changed for installation, you can revert it by an uninstall script.
I'm sure someone has come across this before, but it was hard thinking of how to search for it.
Suppose I have a file generate_data.py and another plot_utils.py which contains a function for plotting this data.
Of note, generate_data.py takes a long time to run and I would like to only have to run it once. However, I haven't finished working out the kinks in plot_utils.py, so I have to run this a bunch of times.
It seems in spyder that when I run generate_data (be it in the current console or in a new dedicated python interpreter) that it doesn't allow me to modify plot_utils.py and call "from plot_utils import plotter" in the command line. -- I mean it doesn't have an error, but it's clear the changes haven't been made.
I guess I kind of want cell mode between different .py files.
EDIT: After being forced to formulate exactly what I want, I think I got around this by putting "from plot_utils import plotter" \n "plotter(foo)" inside a cell in generate_data.py. I am now wondering if there is a more elegant solution.
SECOND EDIT: actually the method mentioned above in the edit does not work as I said it did. Still looking for a method.
You need to reload it:
# Python 2.7
plotter = reload(plotter)
or
# Python 3.x
from imp import reload
plotter = reload(plotter)