0

I'm looking for a way to open another python file in the same folder, but it could be anywhere on a PC. (i.e when I send it to someone the program should be able to find it's way to the file (blahblahblah\IDLE\Login,py).

Here is the code I currently have after some googling, but I really have no idea what I'm doing.

from subprocess import call
import subprocess
import os

def main():
    subprocess.call(['bash' , os.path.expanduser('~')  + "\IDLE\Login.py" ] )

if __name__ == '__main__':
    main()

I know that one of the subprocess imports are redundant but it's just a remnant of older code while I try to find this new way.

The end goal of the project is to use the main file and turn it into an executable to run all the other files in the directory which are called by each other.

Many thanks!

  • 1
    You shouldn't have an "_unkown directory_". – Pedro Lobito Feb 28 '21 at 20:46
  • @PedroLobito - You don't need to know the directory when a program is in the PATH, has a shortcut on the desktop or is part of an application laucher like the Start menu. I think those fit the "unknown directory" criteria. – tdelaney Feb 28 '21 at 21:04

2 Answers2

0

This will give you a full path to the script's location

print('sys.argv[0] =', sys.argv[0])             
pathname = os.path.dirname(sys.argv[0])        
print('path =', pathname)
print('full path =', os.path.abspath(pathname)) 
sizzzzlerz
  • 4,277
  • 3
  • 27
  • 35
  • In the simple case, this will work. It has two "gotchas" that don't exist if you use `__file__` instead of `argv[0]`: 1) if this file is being used as a module included in another file, `argv[0]` isn't in the right place, and 2) if the current working directory has been changed, `argv[0]` could contain a relative path that won't be interpreted right by this code. – CryptoFool Feb 28 '21 at 20:53
-1

Here's how to run bash to execute a script named "Login.py" that is in the same directory as the currently running Python file:

import subprocess
import os

def main():
    here = os.path.dirname(os.path.abspath(__file__))
    subprocess.call(['bash', os.path.join(here, "Login.py")])

if __name__ == '__main__':
    main()

__file__ is always the path of the file containing the Python code being executed.

I don't know why you want to run bash on a .py file, but the mechanics would be the same if you wanted to run python instead or wanted to run bash on a file named Login.sh.

CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • Hi, I don't know why I'm using `.bash` either. It's just what I found online. I have no idea what any of this does. – HarveyLlG Feb 28 '21 at 21:07
  • `bash` runs shell scripts, not arbitrary programs, so `bash Login.py` won't work, just run Login.py directly. `os.path.dirname` isn't quite enough because it may resolve to the empty string. `os.path.dirname(os.path.abspath(__file__))` will work more generally. – tdelaney Feb 28 '21 at 21:15
  • @tdelaney - On point one, I totally agree, hence my comment at the bottom of my answer. I was choosing to leave that separate question alone other than to note it. - – CryptoFool Feb 28 '21 at 21:36
  • @tdelaney - This code will still have the desired effect. The code will simply refer to the "Login.sh" file in whatever way '\_\_file__' refers to the currently running Python file. That should always be a valid reference to that file short of the current directory changing. But then again...Wow. You're right about not getting an absolute path with my code. I made the same mistake that I said was only true of `argv[0]`. Why did I think that `__file__` was always a full path? - I updated my answer to use your advice. – CryptoFool Feb 28 '21 at 21:37
  • @tdelaney - if you know of a way that this code would fail in some other context where the current directory hasn't been changed by the program (a highly frowned upon thing to do), I would genuinely like to know what that case is. I use this method in a number of places in my code, and would love to know what sort of bugs I've left myself open for. - I figure that using `abspath` may do no better. If the contents of `__file__` is ever able to be misinterpreted, I can't think why `abspath` would fix the problem. – CryptoFool Feb 28 '21 at 21:43
  • @CryptoFool - If one tries to run `subprocess.call(['Login.py'])` on a unix-like system, it won't look on the current working directory, it will only look in the path. You need to qualifiy it `./Login.py`. This is a security measure to keep one from accidentally running a local version of what you think is a utility on the PATH. `os.path.dirname(__file__)` when the script is in the cwd, you may get an empty string `""` and `os..path.join(os.path.didrname(__file__), 'Login.py')` is just `Login.py` and won't run. – tdelaney Mar 01 '21 at 00:39
  • @tdelaney - ah, that makes sense. I doubt I'm ever relying on the current directory to run an executable, so that case doesn't really worry me. I use this to associate data files with modules. But I'll remember the distinction. I know the behavior well at a shell prompt, but I'm glad to have it pointed out that it works the same way in Python. That distinction doesn't apply here though, as 'Login.py' is an input parameter, not an executable, yes? – CryptoFool Mar 01 '21 at 00:48
  • @CryptoFool - On windows, .py files are executable if you've associated .py files with python. On linux/mac, its executable if it has the shebang at the top `#!/usr/bin/env python3` and `chmod +x Login.py`. Since we know `bash Login.py` doesn't work, its reasonable to just make `Login.py` executable. At that point, you have to worry about doing `./Login.py`. I think you have almost the rigt answer, so didn't answer myself. But the changes are to drop "bash" and do abspath. Then this is a great answer. – tdelaney Mar 01 '21 at 01:29
  • @tdelaney - I see your point. You are saying that my comment at the end of my answer pointing out that `bash python.py` didn't make much sense wasn't strong enough...that I should have addressed that issue. I can accept that. I disagree with you, however, that the correct way to address that is to get into dropping the reference to the interpreter and making the Python file executable rather than just fixing which interpreter is being referenced (ie: `bash` -> `python`). There are times when you can't or don't want to make a Python script executable. That's a separate issue. – CryptoFool Mar 01 '21 at 02:04
  • `"python"` isn't quite right option either. It wouldn't work on my machine where "python" links to pythnon 2 and "py" may be a better option for Windows which may use that shim to deal with virtual environments. Using `sys.executable` would be the better option in that case. – tdelaney Mar 01 '21 at 02:29
  • Sounding more and more like you should have posted your own answer. – CryptoFool Mar 01 '21 at 02:40