What to reference in the shebang python26 or python2.6 - python

For a Python script I need a specific Python version. Now my installation of Python 2.6 contains both python26 and python2.6
Which one should I put in the shebang?
Option 1:
#!/usr/bin/env python2.6
Option 2:
#!/usr/bin/env python26
EDIT: Yes, there is a reason not to use plain python. In some of our environments in the university python is linked to python2.4 and my code uses quite some 2.6 features.

You can't always guarantee that the shebang will be used (or even that the user will have that version).
You shouldn't really limit to a specific version exactly. It's best to require at least a given version (if your code works on Python 2.6, why wouldn't it work on Python 2.7? I might not have Python 2.6 installed in a few months time.)
I would stick with the /usr/bin/env python shebang and instead dynamically detect the version. Believe it or not, the "normal" way of doing this is:
import sys
ver = sys.version[:3]
That will give you a 3-character string such as "2.6" or "2.7". I would just check that the first character = '2' (assuming you want to prevent Python 3 from running your scripts, since it's largely incompatible) and the third character >= '6'.
Edit: See Petr's comment -- use sys.version_info[0:2] instead (gives you a pair like (2, 6) or (2, 7).

Just checked on my Linux system there is only python2.6 not python26 so the former looks better.
Just to clarify, I would use conditional imports instead, in my case I need OrderedDict which is python 2.7+ only;
try:
from collections import OrderedDict
except ImportError:
print("Python 2.7+ is needed for this script.")
sys.exit(1)

Why don't you just use /usr/bin/python instead? Is there any reason for not doing that?
If you don't have it already, you can create a link to it using this command:
ln -s /usr/bin/python26 /usr/bin/python
This ensures compatibility if you ever upgrade your python in the future.

Related

Is there a way to specify minimum python version requirement for my script since pipfile does not support this?

Is there a way to specify minimum python version requirement for my script ? For example my script requires python 3.6+ because it uses f-string. I have test my script under 3.7, 3.8, 3.9, they all work.
But since pipfile doesn't support minimum version, refer to pipenv specify minimum version of python in pipfile? and this open issue https://github.com/pypa/pipfile/issues/87
So is there a way to do that ? Now I just write it in readme.
--- update ---
https://github.com/pypa/pipenv/issues/2683 indeed said
Note that the python_version key is optional. You can always remove it
if it causes problems, and document the version requirements otherwise
(i.e. in the README).
Check this post. This may do what you require:
#!/usr/bin/env python
import sys
if sys.version_info[0] != 3 or sys.version_info[1] < 6:
print("This script requires Python version 3.6")
sys.exit(1)
# rest of script, including real initial imports, here

Python 3 - Are "from __future__ import xyz" statements necessary/beneficial (emphasis on TensorFlow)?

As I'm getting further into TensorFlow and the finer points of Python, I've noticed these 3 statements at the top of many (perhaps most) .py files in the TensorFlow repository:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
Here are two examples:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_deep.py#L25
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/word2vec/word2vec_basic.py#L17
I should clarify that I have no interest or need to support Python 2 or substantially older versions of Python 3 in any projects I'm undertaking currently.
After reading about from __future__ import xyz statements, for example from these sources:
What is __future__ in Python used for and how/when to use it, and how it works
https://docs.python.org/2/library/future.html
https://docs.python.org/3/library/future.html
http://python-future.org/imports.html
I'm able to understand most of this documentation but I'm left with the following questions:
If only using Python 3, is there any need for these statements or can they safely be removed entirely in all cases? More specifically, if I put the following statement in the beginning of a program:
# check Python version is at least 3.6, if not, show an error and bail
if sys.version_info.major < 3 or sys.version_info.minor < 6:
print("ERROR: currently running Python version " + sys.version + ", at least version 3.6 is required")
return
# end if
Can the above statements be removed with no possibility of ill effects?
Would these statements matter in an older version of Python 3 vs a newer version of Python 3, ex. Python 3.1 vs Python 3.6?
Since TensorFlow requires Python version 3.5 or later, if these statements only matter if Python 2 (or possibly an older version of Python 3? see the previous question) is being used, why are these included in the TensorFlow codebase?
If removing these could ever cause a problem even when using a recent version of Python (ex. 3.5 or later), what would be an example to demonstrate such a problem?
-- EDIT --
user2357112 just pointed out that on Ubuntu TensorFlow supports Python 2.7 or Python 3.4:
I was honestly not aware of this as I'd been using the Windows version of TensorFlow, which requires at least Python 3.5:
So, I guess my question is specific to either a Windows TensorFlow install, or a TensorFlow install on a different OS using a recent version of 3.x.

Where is _functools.py located? [duplicate]

How do I learn where the source file for a given Python module is installed? Is the method different on Windows than on Linux?
I'm trying to look for the source of the datetime module in particular, but I'm interested in a more general answer as well.
For a pure python module you can find the source by looking at themodule.__file__.
The datetime module, however, is written in C, and therefore datetime.__file__ points to a .so file (there is no datetime.__file__ on Windows), and therefore, you can't see the source.
If you download a python source tarball and extract it, the modules' code can be found in the Modules subdirectory.
For example, if you want to find the datetime code for python 2.6, you can look at
Python-2.6/Modules/datetimemodule.c
You can also find the latest version of this file on github on the web at
https://github.com/python/cpython/blob/main/Modules/_datetimemodule.c
Running python -v from the command line should tell you what is being imported and from where. This works for me on Windows and Mac OS X.
C:\>python -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# C:\Python24\lib\site.pyc has bad mtime
import site # from C:\Python24\lib\site.py
# wrote C:\Python24\lib\site.pyc
# C:\Python24\lib\os.pyc has bad mtime
import os # from C:\Python24\lib\os.py
# wrote C:\Python24\lib\os.pyc
import nt # builtin
# C:\Python24\lib\ntpath.pyc has bad mtime
...
I'm not sure what those bad mtime's are on my install!
I realize this answer is 4 years late, but the existing answers are misleading people.
The right way to do this is never __file__, or trying to walk through sys.path and search for yourself, etc. (unless you need to be backward compatible beyond 2.1).
It's the inspect module—in particular, getfile or getsourcefile.
Unless you want to learn and implement the rules (which are documented, but painful, for CPython 2.x, and not documented at all for other implementations, or 3.x) for mapping .pyc to .py files; dealing with .zip archives, eggs, and module packages; trying different ways to get the path to .so/.pyd files that don't support __file__; figuring out what Jython/IronPython/PyPy do; etc. In which case, go for it.
Meanwhile, every Python version's source from 2.0+ is available online at http://hg.python.org/cpython/file/X.Y/ (e.g., 2.7 or 3.3). So, once you discover that inspect.getfile(datetime) is a .so or .pyd file like /usr/local/lib/python2.7/lib-dynload/datetime.so, you can look it up inside the Modules directory. Strictly speaking, there's no way to be sure of which file defines which module, but nearly all of them are either foo.c or foomodule.c, so it shouldn't be hard to guess that datetimemodule.c is what you want.
If you're using pip to install your modules, just pip show $module the location is returned.
The sys.path list contains the list of directories which will be searched for modules at runtime:
python -v
>>> import sys
>>> sys.path
['', '/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', ... ]
from the standard library try imp.find_module
>>> import imp
>>> imp.find_module('fontTools')
(None, 'C:\\Python27\\lib\\site-packages\\FontTools\\fontTools', ('', '', 5))
>>> imp.find_module('datetime')
(None, 'datetime', ('', '', 6))
datetime is a builtin module, so there is no (Python) source file.
For modules coming from .py (or .pyc) files, you can use mymodule.__file__, e.g.
> import random
> random.__file__
'C:\\Python25\\lib\\random.pyc'
Here's a one-liner to get the filename for a module, suitable for shell aliasing:
echo 'import sys; t=__import__(sys.argv[1],fromlist=[\".\"]); print(t.__file__)' | python -
Set up as an alias:
alias getpmpath="echo 'import sys; t=__import__(sys.argv[1],fromlist=[\".\"]); print(t.__file__)' | python - "
To use:
$ getpmpath twisted
/usr/lib64/python2.6/site-packages/twisted/__init__.pyc
$ getpmpath twisted.web
/usr/lib64/python2.6/site-packages/twisted/web/__init__.pyc
In the python interpreter you could import the particular module and then type help(module). This gives details such as Name, File, Module Docs, Description et al.
Ex:
import os
help(os)
Help on module os:
NAME
os - OS routines for Mac, NT, or Posix depending on what system we're on.
FILE
/usr/lib/python2.6/os.py
MODULE DOCS
http://docs.python.org/library/os
DESCRIPTION
This exports:
- all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
- os.path is one of the modules posixpath, or ntpath
- os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'
et al
On windows you can find the location of the python module as shown below:i.e find rest_framework module
New in Python 3.2, you can now use e.g. code_info() from the dis module:
http://docs.python.org/dev/whatsnew/3.2.html#dis
Check out this nifty "cdp" command to cd to the directory containing the source for the indicated Python module:
cdp () {
cd "$(python -c "import os.path as _, ${1}; \
print _.dirname(_.realpath(${1}.__file__[:-1]))"
)"
}
Just updating the answer in case anyone needs it now, I'm at Python 3.9 and using Pip to manage packages. Just use pip show, e.g.:
pip show numpy
It will give you all the details with the location of where pip is storing all your other packages.
On Ubuntu 12.04, for example numpy package for python2, can be found at:
/usr/lib/python2.7/dist-packages/numpy
Of course, this is not generic answer
Another way to check if you have multiple python versions installed, from the terminal.
$ python3 -m pip show pyperclip
Location: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-
$ python -m pip show pyperclip
Location: /Users/umeshvuyyuru/Library/Python/2.7/lib/python/site-packages
Not all python modules are written in python. Datetime happens to be one of them that is not, and (on linux) is datetime.so.
You would have to download the source code to the python standard library to get at it.
For those who prefer a GUI solution: if you're using a gui such as Spyder (part of the Anaconda installation) you can just right-click the module name (such as "csv" in "import csv") and select "go to definition" - this will open the file, but also on the top you can see the exact file location ("C:....csv.py")
If you are not using interpreter then you can run the code below:
import site
print (site.getsitepackages())
Output:
['C:\\Users\\<your username>\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\<your username>\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages']
The second element in Array will be your package location. In this case:
C:\Users\<your username>\AppData\Local\Programs\Python\Python37\lib\site-packages
In an IDE like Spyder, import the module and then run the module individually.
enter image description here
as written above
in python just use help(module)
ie
import fractions
help(fractions)
if your module, in the example fractions, is installed then it will tell you location and info about it, if its not installed it says module not available
if its not available it doesn't come by default with python in which case you can check where you found it for download info

Specify which python version pylint should evaluate for

I'm using Sublime Text 3 With Pylinter to run pylint on my files.
However, on the same machine, I work on files for both python 2, and python 3 projects (the code is executed on one of several remote test-VMs, via SSH. I'm modifying the files by opening them over SMB. This is my home test-lab, and I'm finally sitting down to learn py3k).
Can I easily override the mechanism pylint uses to determine the python version it should lint for? Ideally, there would be an inline directive, but I have not had much luck finding anything.
I'm (editing) on Windows (the remote VMs are linux, but that' irrelevant here), for what it's worth.
You can try python2 -m pylint ... and python3 -m pylint .... That ensures that you use the right version.
AFAIK Pylint lints for the version of Python it is running on and it is not possible to override it.
Expanding on #sthenault's answer and borrowing heavily from #simon's to a very similar question on askubuntu, the solution is to write a wrapper script around pylint that executes it with the appropriate version of the Python interpreter. Drop the following into a script called mypylint (or whatever) somewhere in your $PATH:
#! /usr/bin/env bash
python_interpreter="python${1}"
pylint_args="-f colorized ${#:2}"
pylint_import=$(cat << PYTHON
import sys
import pkg_resources
__requires__ = "pylint"
sys.exit(
pkg_resources.load_entry_point("pylint", "console_scripts", "pylint")()
)
PYTHON
)
$python_interpreter -c "$pylint_import" $pylint_args
Then, execute it like so: mypylint 2|3 PYLINT_ARGS. For instance:
mypylint 2 -f colorized module.py
I'm not sure how you can tie that into sublime-text, but it more generally answers the question of parallel versions of pylint. I also bundled the above solution into a gist.
This is good, but I think the simplest thing is just to use virtualenv, and install pylint in each virtualenv. The correct pylint and python interpreter will be used.
You can override on a per-project level in Sublime Text by changing the pylint executable setting in Project->Edit Project to include:
"settings":
{
"SublimeLinter.linters.pylint.executable": ["py", "-3.4", "-m", "pylint"],
}
substituting 3.4 for your preferred flavour
You should have two pylint installations, say pylint2 and pylint3, then write a wrapper script that will subprocess the desired one.
You can install pylint3 which will evaluate for python 3.0, and pylint which will evaluate the code as python 2.7 by default.

How can I allow python users with a version lower than python2.7 to run my program that uses `sysconfig`?

I made a python program which uses the sysconfig module. How can I allow python users with a python version lower than python2.7 to also run that program? I can not find this library in PyPI.
Before I had also used argparse and this was also not installed by default in python versions lower than python2.7. But I could just add it in my requirements file because it can be downloaded using pip.
You'll need to write a version of your code that works without sysconfig - your code would look something like this:
try:
import sysconfig
HAS_SYSCONFIG = True
except ImportError:
HAS_SYSCONFIG = False
...
if HAS_SYSCONFIG:
# sysconfig code here
else:
# compatibility code here
You could also try backporting sysconfig to an earlier version of python and including it with your script, but that may be more work than it's worth.

Categories