shebang line - multiple allowed interpreters by order - python

I've got a script that requires python3.7 or above.
I've got multiple systems each with different python versions. all of them have either python3.7 or python3.8 but just "python3" can also be python3.6.
Is there a way to make a shebang line take either python3.7 or python3.8? and fail if none exist of course.
I tried a billion of options and nothing works. I was hoping for something like:
#!/usr/bin/python3.7 || /usr/bin/python3.8
or
#!/usr/bin/python3.7
#!/usr/bin/python3.8
but nada.. I also couldn't google it up which kinda makes me sad but who knows maybe the answer is there somewhere and I'm just using a bizarre jargon
these are not systems I can change defaults on and installing python3.7 on each such setup is sadly not an option (would make life awesome).

The shebang simply needs to point to an actual executable.
That executable can be one which finds a suitable version of the Python interpreter; see for example the py tool which was popular on Windows for a long time but which is now also being made available on real computers. other platforms.
Ultimately, something somewhere needs to be on the user's PATH, which obviously you will not always have control over. If you are targeting unsophisticated users, perhaps look into providing your code in a compiled executable, a prepackaged Docker image, or something vaguely like that.

Related

Python version and Anaconda

Recently, I've installed Anaconda3 in a MacOS laptop, but I need to set back the default python version to 2.7 because of some old codes involving the following syntax:
#! /usr/bin/env python
I read some comments and it seems like the easiest way to do it is by using an alias,
alias python="python2"
but even after setting this on my bash_profile, I'm still getting this:
$ which python
/anaconda3/bin/python
What am I doing wrong? Any suggestion is welcome. Thank you in advance!
IMO, you don't want to use an alias to do this. Rather, you want to manipulate your filesystem and/or PATH variable so that the first instance of a binary named 'python' found by the system on your PATH is the one you want to have running by default.
If it made sense to do so, and it was easy to do, an obvious fix would be to uninstall Anaconda. But I assume you still need it.
You could also dig into what the Mac might be doing in your case to manage multiple Python versions in some formal way. This might be the best solution, but I can't tell you how that works. You could Google for that information probably. If you want to take a more basic approach, read on.
What I'd suggest you do first is run the command ls -l `which python`. This will tell you which Python binary is currently the default one, and show you details about that binary. I'm guessing that that "binary" is actually a symbolic link, pointing to some other file. If so, you can just delete that link, or rename it to something else. The same thing will work if what you see is not a symbolic link, but rather a real executable, but it's a bigger deal to decide to delete or rename a real executable. If you just rename this file, you can obviously reverse what you've done any time you want.
Once you do this, do ls -l `which python` again. This should give you a new answer and be pointing at the original python installation. You can confirm which version of python is now the default by running python.

python power shell issues

Edited to include a specific example
I am learning to use python and work in a windows 10 environment (although on 3 separate computers). I have gotten past the "add python to %PATH% issue" but continue to see odd outcomes when I call simple scripts from powershell compared to running them from the python terminal. For example, I often see that lines of code are duplicated, even simple print statements. A second repeating issue is that some (but not all) modules work fine in the python terminal but can't be found when running a script from powershell, despite using pip install within powershell to install it in the first place.
Rather then seeking help on a specific issue, I'm hoping for some guidance into how powershell and python interact that might help me understand or identify some commonalities in these issues I keep experiencing that are common from within powershell. If thats as simple as redirecting me towards another source even that'd be apprecaited. But my search results always turn up the common issue of powershell not knowing what python is, and needing to add python to the PATH. But as indicated, I have already gotten past this and can get %50 of my python to work from powershell. There must be something else perhaps obvious to others that I'm missing that can help me understand why some things aren't working while others are.
Thanks for taking the time to consider my problem and any advice is greatly apprecaited.
Here is an example from some code I am trying to get working, but in troubleshooting I have taken out a lot of code and am now only running what is shown that defines a dataframe and a print statement. Everything works line by line in python, but when I call the script from powershell, the print statement executes twice.
#!/usr/bin/python3
import pandas as pd
joedata = {'fpr': [0.2,0.4,0.8], 'tpr':[0.9,0.5,0.1]}
joeframe = pd.DataFrame(data=joedata)
print(joeframe)
Concerning modules, you probably have multiple versions of Python installed on your system. Calling pip in the Powershell doesn't mean that it will install for the Python installation which is called by default when you execute Python in the Powershell. So you should try to figure out on which version pip is installing packages and which version is actually used when executing a script.
EDIT: I tested the example that you gave in Powershell and I don't have the problem, it's working fine.
Moreover, for me, without doing any special configuration, in Powershell the commands pip and python refer to the same version of Python. If by default everything is ok, you should consider uninstalling Python and just running the installer again and let it manage the PATH, etc.

How to list all Python versions installed in the system?

I need to present the user a list of Python installations to choose from for executing something. I suppose in Windows I could get this information from registry. Don't know about Linux and Mac.
Any hints? Or maybe you even know a place where I could find Python code for this?
EDIT: it is not important that I find really all interpreters. Finding interpreters from standard locations would be actually fine. Agreed, it's not something too difficult, but I was just hoping that maybe someone has code for this lying around or that I've overlooked a function for that in stdlib.
I'm writing a Python IDE and I want to let user to choose the interpreter for executing the program.
Just do it like other IDEs then and simply supply a dialog where users can add interpreters they want to be able to run the code with.
Eclipse does this for example for Java Runtimes, and it’s perfectly fine to have it like that. Especially for languages like Python where virtual environments are an important thing which each have their own exectutable.
You certainly can come up with a one-time detection that checks some common locations. For Windows, this would obviously be the registry, as the py.exe launcher requires the interpreters to be registered there—at least the system-wide ones. On Unix machines, you could check the common bin/ folders, most prominently /usr/local/bin/ which is the standard location where Python installs itself. You could also check the PATH for Python executables. But all those things should be considered carefully and only offer an initial setup. There are always edge cases where a user didn’t do the “standard thing” where your detection will fail. For example I don’t have my Python interpreters in my path, and a linux server I access I have installed Python into a non-standard folder in my home directory. And finally, just because it looks like Python doesn’t mean it is Python.
Yes, you can do some guesswork to come up with an initial set of interpreters, but really don’t spend too much time on it. In the end, you won’t be able to detect everything perfectly anyway. And you will miss virtual environments—which might be very crucial to the project the user is working on in your IDE.
So instead of wasting time on bad detection, spend more time on creating a manual dialog to register interpreters. You will need that anyway, and a good interface can make it very easy—even for beginners—to use it.
Not sure this is entirely possible, but here's a dirty fix:
from subprocess import *
from time import sleep
for i in range(2, 4):
x = Popen('python' + str(i) + ' --version', shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
while x.poll() == None:
sleep(0.025)
print('Exit code of ' + str(i) + ' is:',x.poll())
x.stdout.close()
x.stdin.close()
The exit code will tell you if Python2 or Python3 is installed.
You could add a second iterator for python versions 2.4, 2.4, 3.1, 3.2 etc etc. Or just keep them in a list, whichever you prefer for this already dirty fix.

How to create a Mac OS X app with Python?

I want to create a GUI application which should work on Windows and Mac. For this I've chosen Python.
The problem is on Mac OS X.
There are 2 tools to generate an ".app" for Mac: py2app and pyinstaller.
py2app is pretty good, but it adds the source code in the package. I
don't want to share the code with the final users.
Pyinstaller generates UNIX executable, so how to run it on Mac? I
created a bundles with this executable, but the resulted ".app" is
not working.
The questions are:
How to configure py2app to include the source code in the
executable, so the final users will not have access to my program?
How to convert UNIX executable to Mac ".app" ?
Is there a way to compile Python code with GCC ?
In Windows it's easy, I created an "exe" file from Python code and
it works. Is it possible to create a single file "app" for Mac ?
P.S. I use two computers (Windows and for Mac), Python 2.7, wxPython, py2exe, py2app and pyinstaller.
Also, I have checked out these sites:
http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html
http://www.pyinstaller.org/export/develop/project/doc/Manual.html?format=raw
http://www.pyinstaller.org/wiki/Features/MacOsCompatibility
http://www.stackoverflow.com/questions/2933/an-executable-python-app
How to configure py2app to include the source code in the executable,
so the final users will not have access to my program?
Unless you very seriously hack the python interpreter (and include the mangled version) there is no really good way to hide the source from a moderately skilled and determined user. I strongly believe this is true on Windows also. Basically, whether you include true source or bytecode, a pretty clean version of the source can be recovered. More importantly, in my opinion, unless you include the actual source code (as opposed to bytecode, you will introduce a possible dependency on the interpreter version).
How to convert UNIX executable to Mac ".app" ?
What do you mean by a UNIX executable? A Darwin (OS X) binary [which isn't actually UNIX]? That can be done using the kinds of tools you already mentioned, but it must be done carefully to avoid library dependencies.
If all you want it a simple wrapper to put a command-line binary into a window, it's pretty easy to accomplish and the free XCode suite has several examples that would serve (depending on what output
you wan to deliver, if any).
Is there a way to compile Python code with GCC ?
GCC does not compile Python. It's a different language (although there tools in the gcc family rthat support multiple language front-ends, but not Python). There are tools that attempt to translate Python into C, and then you can compile that into a true binary, but this only works for programs that avoid certain types of construct, and the process (and restrictions) need to apply your libraries as well.
One project to allow this is Cython. It works well for some types
of code, mostly numerical code, but it is not trivial to install and
exploit, very especially if you want to produce something that runs on multiple
different computers.
In Windows it's easy, I created an "exe" file from Python code and it
works. Is it possible to create a single file "app" for Mac ?
I would have to say I am skeptical -- very skeptical -- about this. Just like the OS X case, the exe almost certainly has the source code trivially accessible within it.
One fairly easy trick is to encrypt the source code and then decrypt it on the fly, but this
seems to me like more trouble than it's worth.
PyInstaller will automatically create bundles under Mac OSX for windowed executables. When running ypinstaller.py, make sure to pass the option "--windowed".
This feature is documented in the website of pyinstaller
If you're not completely committed to wxPython (and for anyone else looking for a cross platform Python GUI framework), I recommend you check out Kivy. It's cross platform, GPU accelerated, and it will do the app packaging for you. It's easy to jump into, has a well thought-out architecture, and gives you an incredible amount of flexibility in terms of the interface. It's the best way I've found to make a cross platform Python GUI app.
cxFreeze was the choice.
I use it pack my python program to a Mac OS X app. Which works like a charm.
Automator was already mentioned as a quick and simple solution for Pythons scripts that are contained in a single file, but since the Automator UI has so many options, and it is not obvious how to actually do it, I'll provide step-by-step instructions (verified to work on Yosemite):
In Automator select File > New and pick Application as document type.
Next, make sure Actions tab is selected on the left, and then in the search box type run. Among other options you'll see Run Shell Script — doubleclick it, and an editor window will appear in the right panel.
From the Shell dropdown menu select /usr/bin/python.
Paste your Python code into the edit window and then pick File > Save.
By default, the app will be saved under $HOME/Applications and will appear in Spotlight.
If you want to be able to set your own icon and have some fancy features, like task bar icons with a menu, log windows etc, then have a look at Platypus — an open-source app for creating MacOS native bundles.
2: You can't "convert" it, but you can move the executable to App.app/Contents/MacOS/something in a .app file, with CFBundleExecutable set to "something". This would not generally be recommended.
A motivated person could probably reconstruct usable source code from the Python bytecode in your app, so you might reconsider your opposition to py2app. If you don't trust your final users, why are you doing business with them?
Having used py2exe for windows users so they wouldn't have to deal with library versions, I've torn apart the compiled programs, they include the python bytecode files. While you can make it a violation of the license to look inside those, the fact is that if a computer can execute them, I can read them. It is possible to compile python programs with gcc, via a C preprocessor (try looking for 2c.py on google), I don't know if any of them support GCC. Again, you don't gain any security through using them, but you can get a significant speed improvement.
I haven't tried it with big Python projects, but for my own scripts, the easiest way I found was to use Automator
You can interactively create an app project with Run Shell Script action, then paste in your script in its editor, select your shell program (/usr/bin/python), finally save the project. And you have yourself a Mac native app.
Automator can also be driven by AppleScript. So you can pipeline this py-2-app conversion process to your build scripts.
I've never tested a GUI program with it so I don't know if you'll be happy with it. But I'd give it a try since you may wonder how well all the cited 3rd-party python modules/applications are maintained, and how long they are gonna last. Coming bundled with OS X, Automator will likely stay, unless Apple got REALLY tired of it.
cxFreeze is best solution available, first create your program or application using python and than make setup file for your application, and than build the app using build command python setup.py build, according to your requirement you need to make some changes.
The only way is py2app. You have no other way. Sorry.
The research you did seems very solid and you did not miss anything.

Why is '#!/usr/bin/env python' supposedly more correct than just '#!/usr/bin/python'?

Anyone know this? I've never been able to find an answer.
If you're prone to installing python in various and interesting places on your PATH (as in $PATH in typical Unix shells, %PATH on typical Windows ones), using /usr/bin/env will accomodate your whim (well, in Unix-like environments at least) while going directly to /usr/bin/python won't. But losing control of what version of Python your scripts run under is no unalloyed bargain... if you look at my code you're more likely to see it start with, e.g., #!/usr/local/bin/python2.5 rather than with an open and accepting #!/usr/bin/env python -- assuming the script is important I like to ensure it's run with the specific version I have tested and developed it with, NOT a semi-random one;-).
From wikipedia
Shebangs specify absolute paths to system executables; this can cause
problems on systems which have non-standard file system layouts
Often, the program /usr/bin/env can be used to circumvent this
limitation
it finds the python executable in your environment and uses that. it's more portable because python may not always be in /usr/bin/python. env is always located in /usr/bin.
It finds 'python' also in /usr/local/bin, ~/bin, /opt/bin, ... or wherever it may hide.
You may find this post to be of interest:
http://mail.python.org/pipermail/python-list/2008-May/661514.html
This may be a better explanation:
http://mail.python.org/pipermail/tutor/2007-June/054816.html

Categories