Python pdb on python script run as package - python

I have a python program that I usually run as a part of a package:
python -m mymod.client
in order to deal with relative imports inside "mymod/client.py." How do I run this with pdb - the python debugger. The following does not work:
python -m pdb mymod.client
It yields the error:
Error: mymod.client does not exist
EDIT #1 (to address possible duplicity of question)
My question isn't really about running two modules simultaneously python, rather it is about how to use pdb on a python script that has relative imports inside it and which one usually deals with by running the script with "python -m."
Restated, my question could then be, how do I use pdb on such a script while not having to change the script itself just to have it run with pdb (ie: preserving the relative imports inside the script as much as possible). Shouldn't this be possible, or am I forced to refactor in some way if I want to use pdb? If so what would be the minimal changes to the structure of the script that I'd have to introduce to allow me to leverage pdb.
In summary, I don't care how I run the script, just so long as I can get it working with pdb without changing it's internal structure (relative imports, etc) too much.

I think I have a solution.
Run it like this:
python -m pdb path/mymod/client.py arg1 arg2
that will run it as a script, but will not treat it as a package.
At the top of client.py, the first line should be:
import mymod
That will get the package itself loaded.
I am still playing with this, but it seems to work so far.

This is not possible. Though unstated in documentation, Python will not parse two modules via the -m command line option.

Related

Difference between running ./pythonscript and python pythonscript.py

I have a python script fetchcreative.py which typically fetches some data from db . The script has execute permission . When i run the script using
./fetchcreative.py rtb:3778:4019617065
it fails with ImportError: No module named psycopg2.
But when i run using
python fetchcreative.py rtb:3778:4019617065
it works fine. Just want to understand , what is going on here ? Please point to corresponding reference where i can learn more about it .
./fetchcreative.py will use the shebang (#!) magic at the beginning of the file to determine which python to run.
Usually it is best to have:
#!/usr/bin/env python
at the beginning of a script.py to get python from the environment (i.e. from $PATH) which should match (though aliases and other actions could make it different):
$ python script.py
However, if the #! is hard-coded to a specific python it may not match python on the command line.

How can I run a Jython script with Python

I am programming in Python(2.7), processing a bunch of data.
And I've got a software, what I have to use, and I want to start it automatically, and fill it up with data.
The problem is, that I cant open it with Python, because it has API only for Jython.
My question is, that how could I run a Jython script from a Python code(actually I am working on a standalone software)?
Is it even possible?
If it is, could you please give me a short example?
How to install Jython and how to run a file from python?
You can simply use Jython to run everything.
Having my_script.py and jython_script.py edit my_script.py by adding import jython_script and adding call jython_script.some_function().
# my_script.py
import jython_script
def my_function_using_some_function_from_jython_script():
...
jython_script.some_function()
...
Then simply call:
jython my_script.py
I assume you do not use modules that work only with CPython.

Different ways to execute python script

I think I already answered my own question in my mind but in case there are other reasons I don't see, I am wondering what's the benefit/difference between running a python script with
python script.py
and using the shebang
#!/usr/local/bin/python
I usually run my scripts as self executing scripts so I use the shebang. I just came across a team member who runs his programs using
python script.py
My question is which way is better or is this a personal preference thing?
If I run with shebang, I can specify which version I want/need to use. The only problem is I need to make sure that version is installed at that location.
If I run it the other way (not sure what to call it, non-shebang way?), I need to make sure the version I want to use is in my path or defined correctly in my path. I could also type in the full path of python but that can get rather tiring if the path is very long.
Are there other benefits/drawbacks that I don't see? Thanks.
If you want to run your script with shebang, you'll have to make sure that the user running the script has execution rights on the script in question (chmod u+x script.py). That's not the case if you call python with the script as an argument.
Another issue with the shebang solution is that you're forcing the location of the python executable. If I try to run your script and my version of python is in /usr/bin/python instead of /usr/local/bin/python, I'll have to edit your script. On other platforms, such as Windows, I'll have to edit it too.
With the shebang the script must be located on a volume that permits execution, must be allowed to execute by any security modules, and the interpreter specified in the shebang must be present.
Invoking the interpreter directly only requires the script to be readable.
In general environment they are the same.
However, shebang gives you an extra benefit that you can replace your executable very easily without changing any other files just by substituting the file. The second(better) implementation can potentially be anything. For a script based environment, I always use shebang, with a fixture of languages.
for the shebang line, the argument that you need to be concerned about the location of python binary is not valid. you can always write:
#!/usr/bin/env python
to have local environment to decide for you.
If you are treating python as scripting language that one might execute from a POSIX compliant shell then it really doesn't matter.
That said, given that Python is more or less becoming standardized with its package management and installation, I would argue none of the above. What should be done is that all scripts be turned into callables (either functions or callable class instances) that live within modules (preferably defined a namespace package). That callable is the entry point to your program/script. Then a setuptools compliant setup.py should be placed in the root directory of the project for this module and define that as the entry point to your program.
An example:
In example.package/example/package/script.py:
def main():
print('hello world')
The setup.py:
from setuptools import setup, find_packages
setup(
name='example.package',
description='An example package with an entry point',
...
entry_points="""
# -*- Entry points: -*-
[console_scripts]
script = example.package.script:main
""",
)
Note that the script is defined to be example.package.script:main, where the element before the : corresponds to the package and the second element is the callable. In this case, it corresponds to the main function in example/package/script.py (standard python module layout).
Installing the package (preferably in a virtualenv) will generate the correct "executable" that will be immediately accessible from the shell, across all operating systems (i.e. on Windows, a script.exe will be created that basically will start Python with the script).

Run Python script in Python environment?

In the terminal when starting Python, can we run a Python script under Python environment?
I know I can run it on bash, but don't know if I can run it in Python environment. The purpose is to see when the script goes wrong, the values of the variables at that time.
The purpose is to see when the script goes wrong, the values of the variables at that time.
You have two options for that (neither of which is precisely the question you're asking, but is nonetheless the proper way to achieve the desired outcome)
First, the pdb module:
import pdb; pdb.set_trace()
This enters the debugger at whatever point you place this code. Useful for seeing variables.
Second, running the command with -i:
$ python -i script.py
This drops into the full interpreter after execution, with all variables intact

Multiple -m command line arguments (Python)

I want to run both cProfiler (For time measurement, mainly) and also a memory profiler that I found here. However, both require the -m command line argument to be given, which doesn't exactly play nicely.
Is there a way to have both running? All I've managed to do so far is get the interpreter yelling at me.
If you need any more information, let me know and I'll do my best to provide it. Thanks in advance!
It is not possible to start two modules using two -m arguments. This is because the command line arguments after -m are all given to the named module as sys.argv. This is not described explicitly in the documentation but you can try it out experimentally.
Create two python files a.py and b.py.
Contents of a.py:
print 'a'
import sys
print sys.argv
Contents of b.py:
print 'b'
Now try to run both using two -m arguments:
$ python -m a -m b
Output:
a
['/home/lesmana/tmp/a.py', '-m', 'b']
As you can see module b is never started because the second -m is not handled by python. It is given to module a to handle.
While it's now evident to me that you can't use two -m arguments on the same file, I managed to pull together something of a solution. It's a bit round-about, and not exactly perfect, though.
I used 2 .bat files, which can be seen here. On the left hand side is the .bat that handles cProfiler, and on the right is the .bat that handles the memory profiler.
The code for the python programs seen in the .bat handling the memory profiler can be seen here and here.
The first program adds # to the line directly above the function in my main code here, which means that the program can actually run, and cProfiler can do its thing.
The second program removes that #, meaning that the memory profiler can work.
For this system to work properly with my layout, the "#profile" needs to be commented out in the first place.
It's a bit kludgey, and could use some refinement to automate it further (Such as having to specify the name of the file in the .bat file handling the memory profiler), but it'll do for now. I also realize that it's quite a specific case, but who knows, maybe someone is in the exact same position as I was...

Categories