I am currently trying to debug an app that I have not written myself. I have narrowed the problem down to a particular method that is imported from a module outside of the current script. I would like to step through this module by writing to a file at each step, however it doesn't seem to work.
I have a version of the app that is running correctly and when I write to a file from within the module, the script runs fine but no file is created. Am I missing something here?
Example
Script that I am debugging
from module import method
example code ...
method(data) --- where error occurs
more code ...
module.py
def method(data):
file = open('filetowrite.txt','w')
file.write('something ....')
file.close()
Do not reinvent the wheel, use standard logging module.
Since you mentioned "I would like to step through this module" that's how you can do it with again standard pdb module.
Your code for file writing looks fine. I would look at the path (the location) where the file is being written to.
Check out:
How to get full path of current file's directory in Python?
Related
I have a flask app with the root folder called project_folder.
A code snippet from the __init__.py file of this project_folder package:
#jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
jti = decrypted_token['jti']
return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
from project_folder.Controller.root import root
from project_folder.Controller import auth_controller
from project_folder.Controller import item_controller
Now the interesting thing is, that the project_folder package naturally has other smaller packages itself, which I'm importing to use them (for REST resources in this example). These are the last 3 lines, nothing throws an error so far.
But, if you take a look at the annotated function (in this example it always runs before some kind of JWT Token is being used), I am returning some inner package's function. Now when the logic truly runs this part the code breaks:
PROJECT_ROUTE\project_folder\__init__.py", line 38, in check_if_token_in_blacklist
return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
NameError: name 'project_folder' is not defined
After thinking about it, it seems understandable. Importing from project_folder does import from the __init__.py file of the package, which is the actual file the interpreter currently is. So removing the package name prefix form the
return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
to
return Model.RevokedTokenModel.is_jti_blacklisted(jti)
does not throw an error anymore.
The question is: Why is it only a problem inside the callback function and not with the last 3 imports?
This has to do with circular imports in python. Circular import is a form of circular dependency, created at the module import level.
How it works:
When you launch your application, python keeps a register (a kind of table) in which it records all the imported modules. When you call somewhere in your code a module, python will see in its registry if it has already been registered and loads it from there. You can access this registry via sys.module, which is actually a dictionary containing all the modules that have been imported since Python was started.
Example of use:
>>> import sys
>>> print('\n'.join(sys.modules.keys()))
So, since Python is an interpreted language, reading and execution of code is done line by line from top to bottom.
In your code, you put your imports at the bottom of your __init__.py file.
While browsing it, when python arrives at the line return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti), it will look if the module exists in its register. Which is clearly not yet the case. That's why he raises an NameError: name 'project_folder' is not defined exception.
I wrote a module that, if it is imported, automatically changes the error output of my program. It is quite handy to have it in almost any python code I write.
Thus I don't want to add the line import my_errorhook to every code I write but want to have this line added automatically.
I found this answer, stating that it should be avoided to change the behavior of python directly. So I thought about changing the command line, something like
python --importModule my_errorhook main.py
and defining an alias in the bashrc to overwrite the python command to automatically add the parameter. Is there any way I could achieve such a behavior?
There is no such thing like --importModule in python command line. The only way you can incept the code without explicitly importing is by putting your functions in builtins module. However, this is a practice that is discouraged because it makes your code hard to maintain without proper design.
Let's assume that your python file main.py is the entry point of the whole program. Now you can create another file bootstrap.py, and put below codes into the new file.
import main
__builtins__.func = lambda x: x>=0
main.main()
Then the function func() can be called from all modules without being imported. For example in main.py
def main():
...
print(func(1))
...
A little bit of an explanation of my situation before my question.
I created a module called foo. foo's location in the file system is
/runtime/foo
and the script "test.py" which imports foo by using sys.path.append() is located in.
/runtime/bar/test.py
Foo's structure is as follows
foo
mtr.txt
__init__.py
datasources.py
I would like a class within datasources.py to open the file mtr.txt. However, I am not able to do this without explicting giving a path within datasources. In this case it would be
/runtime/foo/mtr.txt
My code will work if I do give it this path, but this is something that should be doable, but I can't find the answer.
I have tried the following commands within a class in datasources.py.
open("mtr.txt")
open("./mtr.txt")
and a few other things using the os.path.dirname()
Is there a way to open the file 'mtr.txt' without giving its full path within datasources.py?
Thanks
Use pkg_resources
import pkg_resources
data = pkg_resources.resource_string(__name__, "mtr.txt")
There are more methods provided by this package, check the docs for Resource Manager API.
I am trying to get a python script to open another python script in a directory that I know of but the actual filename is a variable. I would like to execute this file or be able to import the file (either way would work for what I am trying to do) but I am having problems with each one.
for trying to execute it, the dos style box appears but quickly disappears, too quickyl to really do anything. I even added a Raw_Input() and executed the file on its own and got it to work. here is the like on code:
os.system("python actions/"+Script)
Script being the name of the python file in a string. I know that the file is found but the problem is that it disapears too quickly
the other way I am trying to do it is by importing the file:
import 'actions/'+Script
this is the only logical way I can think of to import the damn thing but I keep getting syntax errors
Use the __import__ function to import a module whose name isn't known until runtime:
# Import the module
mymodule = __import__('actions/' + Script)
# Call functions in the module etc.
mymodule.do_something(42);
Or try import (been around a while I believe) or importlib (added in python 2.7):
import">http://docs.python.org/library/functions.html#import
http://docs.python.org/library/importlib.html#importlib.import_module
try:
import sys
sys.path = ["./actions"] + sys.path
exec("import " + Script[-3])
I have 3 python files.(first.py, second.py, third.py) I'm executing 2nd python file from the 1st python file. 2nd python file uses the 'import' statement to make use of 3rd python file. This is what I'm doing.
This is my code.
first.py
import os
file_path = "folder\second.py"
os.system(file_path)
second.py
import third
...
(rest of the code)
third.py (which contains ReportLab code for generating PDF )
....
canvas.drawImage('xyz.jpg',0.2*inch, 7.65*inch, width=w*scale, height=h*scale)
....
when I'm executing this code, it gives error
IOError: Cannot open resource "xyz.jpg"
But when i execute second.py file directly by writing python second.py , everything works fine..!!
Even i tried this code,
file_path = "folder\second.py"
execfile(file_path)
But it gives this error,
ImportError: No module named third
But as i stated everything works fine if i directly execute the second.py file. !!
why this is happening? Is there any better idea for executing such a kind of nested python files?
Any idea or suggestions would be greatly appreciated.
I used this three files just to give the basic idea of my structure. You can consider this flow of execution as a single process. There are too many processes like this and each file contains thousandth lines of codes. That's why i can't change the whole code to be modularize which can be used by import statement. :-(
So the question is how to make a single python file which will take care of executing all the other processes. (If we are executing each process individually, everything works fine )
This should be easy if you do it the right way. There's a couple steps that you can follow to set it up.
Step 1: Set your files up to be run or imported
#!/usr/bin/env python
def main():
do_stuff()
if __name__ == '__main__':
The __name__ special variable will contain __main__ when invoked as a script, and the module name if imported. You can use that to provide a file that can be used either way.
Step 2: Make your subdirectory a package
If you add an empty file called __init__.py to folder, it becomes a package that you can import.
Step 3: Import and run your scripts
from folder import first, second, third
first.main()
second.main()
third.main()
The way you are doing thing is invalid.
You should: create a main application, and import 1,2,3.
In 1,2,3: You should define the things as your functions. Then call them from the main application.
IMHO: I don't need that you have much code to put into separate files, you just also put them into one file with function definitions and call them properly.
I second S.Lott: You really should rethink your design.
But just to provide an answer to your specific problem:
From what I can guess so far, you have second.py and third.py in folder, along with xyz.jpg. To make this work, you will have to change your working directory first. Try it in this way in first.py:
import os
....
os.chdir('folder')
execfile('second.py')
Try reading about the os module.
Future readers:
Pradyumna's answer from here solved Moin Ahmed's second issue for me:
import sys, change "sys.path" by appending the path during run
time,then import the module that will help
[i.e. sys.path.append(execfile's directory)]