Is there an existing python module that can be used to detect which distro of Linux and which version of the distro is currently installed.
For example:
RedHat Enterprise 5
Fedora 11
Suse Enterprise 11
etc....
I can make my own module by parsing various files like /etc/redhat-release but I was wondering if a module already exists?
Cheers,
Ivan
Look up the docs for the platform module: http://docs.python.org/library/platform.html
Example:
>>> platform.uname()
('Linux', 'localhost', '2.6.31.5-desktop-1mnb', '#1 SMP Fri Oct 23 00:05:22 EDT 2009', 'x86_64', 'AMD Athlon(tm) 64 X2 Dual Core Processor 3600+')
>>> platform.linux_distribution()
('Mandriva Linux', '2010.0', 'Official')
I've written a package called distro (now used by pip) which aims to replace distro.linux_distribution. It works on many distributions which might return weird or empty tuples when using platform.
https://github.com/nir0s/distro (distro, on pypi)
It provides a much more elaborate API to retrieve distribution related information.
$ python
Python 2.7.12 (default, Nov 7 2016, 11:55:55)
[GCC 6.2.1 20160830] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import distro
>>> distro.linux_distribution()
(u'Antergos Linux', '', u'ARCHCODE')
By the way, platform.linux_distribution is to be removed in Python 3.7.
The above answer doesn't work on RHEL 5.x. The quickest way is on a redhat-like system is to read and look at the /etc/redhat-release file. This file is updated every time you run an update and the system gets upgraded by a minor release number.
$ python
>>> open('/etc/redhat-release','r').read().split(' ')[6].split('.')
['5', '5']
If you take the split parts out it will just give you string. No module like you asked, but I figured it was short and elegant enough that you may find it useful.
Might not be the best way, but I used subprocess to execute 'uname -v' and then looked for the distro name in the output.
import subprocess
process = subprocess.Popen(['uname','-v'], stdout=subprocess.PIPE)
stdout = process.communicate()[0]
distro = format(stdout).rstrip("\n")
if 'FreeBSD' in distro:
print "It's FreeBSD"
elif 'Ubuntu' in distro:
print "It's Ubuntu"
elif 'Darwin' in distro:
print "It's a Mac"
else:
print "Unknown distro"
Related
I am trying to use a code which was written for python 2 and may run with python 3.6.0, but it does not run with python 3.6.4. It imports the IN module, and uses IN.IP_RECVERR. I tried to google it, but it is a 'bit' hard to find anything about a module called IN (naming fail?). To demonstrate in REPL, that it works in python 2, but not in 3.6.4:
$ python2
Python 2.7.14 (default, Jan 5 2018, 10:41:29)
[GCC 7.2.1 20171224] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import IN
>>> IN.IP_RECVERR
11
>>>
$ python3
Python 3.6.4 (default, Jan 5 2018, 02:35:40)
[GCC 7.2.1 20171224] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import IN
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'IN'
>>>
What is the replacement for this IN module in newer versions of python 3?
This is presumably the private plat-linux/IN.py module, which was never intended to be used. There have been plans to remove these plat-* files for a few zillion years, but it looks like it finally happened in issue 28027 for 3.6. As mentioned in What's New in Python 3.6:
The undocumented IN, CDROM, DLFCN, TYPES, CDIO, and STROPTS modules have been removed. They had been available in the platform specific Lib/plat-*/ directories, but were chronically out of date, inconsistently available across platforms, and unmaintained. The script that created these modules is still available in the source distribution at Tools/scripts/h2py.py.
Most of the useful constants that are at least somewhat portable (as in you can expect them to be available and work the same on your old laptop's linux and your brand-new Galaxy's linux, if not on OS X or Solaris) have long been made available through other places in the stdlib.
I think this specific one you're looking for is an example of not completely useless, but not portable enough to put anywhere safe, because linux documents the existence of IP_RECVERR, but not its value. So, you really need the version from your own system's ip headers.
The way to do this safely, if you actually need the IN module, is to run Tools/scripts/h2py.py with the Python version you're using, on the specific platform you need. That will generate an IN.py from the appropriate headers on your system (or on your cross-compilation target), which you can then use on that system. If you want to distribute your code, you'd probably need to put a step to do that into the setup.py, so it'll be run at install time (and at wheel-building time for people who install pre-built wheels, but you may need to be careful to make sure the targets are specific enough).
If you don't need to be particularly portable, you just need to access the one value in a few scripts that you're only deploying on your laptop or your company's set of identical containers or the like, you may be better off hardcoding the values (with a nice scare comment explaining the details).
In Python 2.7, how can I make the IDLE app use \__future__ division without typing from \__future__ import division manually every time I start IDLE?
If I put from \__future__ import division at the top of my .idlestartup file it is ignored, even though the other things in .idlestartup get executed. For example:
~> cat >.idlestartup
from __future__ import division
print("Executing .idlestartup")
~> idle -s
Here's what my IDLE window looks like after I try dividing:
Python 2.7.8 |Anaconda 2.1.0 (x86_64)| (default, Aug 21 2014, 15:21:46)
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>>
Executing .idlestartup
>>> 2/3
0
>>>
I am using Mac OS X 10.9.5 Mavericks (also had the same problem on earlier versions of OS X). Note that the command line version above was included to make it easier to show what I'm talking about, but the version I'm more interested in is running the IDLE app from the GUI.
The solution suggested by Ashwini Chaudhary below worked for running the Anaconda version from the command line but not for running the IDLE app.
I was finally able to get future division working automatically in the IDLE app by adding "sys.argv.insert(1, '-Qnew')" to /Applications/IDLE.app/Contents/MacOS/IDLE. Both that and Ashwini Chaudhary's solution below seem brittle. I wonder if there is a cleaner way.
Adding the __future__ statement at the top of /usr/lib/python2.7/idlelib/PyShell.py did the job for me.
I am on Ubuntu, the path may vary for other OS:
>>> import idlelib
>>> idlelib.PyShell.__file__
'/usr/lib/python2.7/idlelib/PyShell.py'
I learned about pystones today and so I decided to see what my various environments were like. I ran pystones on my laptop that is running windows on the bare metal and got these results
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from test import pystone
>>> for i in range(0,10):
... pystone.pystones()
...
(1.636334799754252, 30556.094026423627)
(2.1157907919853756, 23631.82607155689)
(2.5324817108003685, 19743.479207278437)
(2.541626695533182, 19672.4405231788)
(2.536022267835051, 19715.915208695682)
(2.540327088340973, 19682.50475676099)
(2.544761766911506, 19648.20465716261)
(2.540296805235016, 19682.739393664764)
(2.533851636391205, 19732.804905346253)
(2.536483186973612, 19712.3325148696)
Then I ran it on some of our linux VMs and got 2.7-3.4 times better performance. So I fired up my vmware Linux VM on my laptop and reran the same test and got these results:
Python 2.7.2+ (default, Oct 4 2011, 20:03:08)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> for i in range(0,10):
... pystone.pystones()
...
(1.75, 28571.428571428572)
(1.17, 42735.042735042734)
(1.6600000000000001, 30120.48192771084)
(1.8399999999999999, 27173.913043478264)
(1.8200000000000003, 27472.52747252747)
(1.8099999999999987, 27624.30939226521)
(1.3099999999999987, 38167.938931297744)
(1.7800000000000011, 28089.88764044942)
(1.8200000000000038, 27472.527472527414)
(1.490000000000002, 33557.04697986573)
I can't quite understand how the linux VM running inside the same windows is actually FASTER than python running on the same bare metal under windows.
What is so different about python on windows that it performs slower on the bare OS than it does inside a VM running Linux on the same box?
More details
Windows platform Win7x64
32 bit python running on both platforms
32 bit linux VM running the windows platform in VMWare
Had similar problem on windows 10 - it was because of windows defender.
I had to exclude python directories and process in windows defender settings and restart computer.
Before: I had to wait like ~20 seconds to run any python code - now it's milliseconds.
I can't answer your question, however consider this list of things that could be making a difference:
You're using different versions of Python. "2.7.2+" indicates that your linux Python was built from a version control checkout rather than a release.
They were compiled with different compilers (and conceivably meaningfully different optimization levels).
You haven't mentioned reproducing this much. It's conceivable it was a fluke if you haven't.
Your VM might be timing inaccurately.
You're linking different implementations of Python's dependencies, notably libc as Ignacio Vazquez-Abrams points out.
I don't know what pystone's actual benchmarks are like, but many things work differently--things like unicode handling or disk IO could be system-dependent factors.
Do you run antivirus software on that Windows box? This perhaps could explain it. I personally like to add Python, Cygwin and my sources directory to antivirus exclusion list - I think I get a small, but noticeable speedup. Maybe that explains your results.
Benchmark your startup, but there are just simply some slow modules to initialize on windows. A tiny hack that saves me a second on startup every time:
import os
import mimetypes #mimetypes gets imported later in dep chain
if __name__ == "__main__":
# stub this out, so registry db wont ever be read, not needed
mimetypes._winreg = None
Another source of slowness is, multiple standard library modules compile and cache their regexes at import time. re.compile just looks like its slow on windows
With Python2.6, the Evt module (from Carbon import Evt) does not have seem to respond to TickCount() on OSX. But Python2.5 is fine:
from Carbon import Evt
s = Evt.TickCount()
On Python2.5 I get a returned integer. On Python2.6 I get:
AttributeError: 'module' object has no attribute 'TickCount'
This is on Snow Leopard. Is there some library that needs to be updated on OSX to allow for TickCount() to work? I'm actually having this problem due to using py2app.
Update for Barry's answer:
The problem is that the application that py2app creates, when launched, gives me:
File "/Users/cybertoast/Projects/scripts/dist/fixcatalystlibs.app/Contents/Resources/__boot__.py", line 40, in mainloop
[0x0-0x913913].org.pythonmac.unspecified.fixcatalystlibs[11722] stoptime = Evt.TickCount() + timeout
[0x0-0x913913].org.pythonmac.unspecified.fixcatalystlibs[11722] AttributeError: 'module' object has no attribute 'TickCount'
I added VERSIONER_PYTHON_PREFER_32_BIT=yes to my .bash_profile, but the app that py2app creates still has the same problem. The python interpreter, however is happy with the 32-bit fix. But still need a solution to py2app.
Since the broken code was only being used for argv emulation, I was able to get my app working by disabling argv emulation. This can be done by setting the 'argv_emulation' key in the py2app OPTIONS hash to False.
Example:
APP = ['MyApp.py']
OPTIONS = {
'argv_emulation': False,
...
}
setup(
app=APP,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
The code I have been using requires the use of argv_emulation, so the above solutions have not aided me. In the end, I made use of LSArchitecturePriority in the plist file, setting it to i386. This solved my problem, and allowed me to keep the argv_emulation set to True.
More info can be found here: http://developer.apple.com/library/mac/#documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#/
Python runs in 64-bit mode by default in Snow Leopard. It appears that Carbon.Evt hasn't made the transition to full 64-bit compatibility. You can confirm this by trying to run in 32-bit mode (see man python):
oso:~ barry$ export VERSIONER_PYTHON_PREFER_32_BIT=yes
oso:~ barry$ python
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import Carbon.Evt as evt
>>> evt.TickCount()
2973070
>>>
So, either run py2app in 32-bit mode, or tell us what you're trying to do and perhaps we can provide a 64-bit compatible alternative.
Probably the easiest solution is to use another, 32-bit-only Python instead of the Apple-supplied one in 10.6 - for example, install Python 2.6 using the python.org installer. If you want to distribute your app as a standalone app that can be used on multiple OS X versions, you'll need to do that anyway.
Essentially I am looking for a way to find the following, but from within Python without having to run system commands:
$ file `which python2.7`
/Library/.../2.7/bin/python2.7: Mach-O universal binary with 2 architectures
/Library/.../2.7/bin/python2.7 (for architecture i386): Mach-O executable i386
/Library/.../2.7/bin/python2.7 (for architecture x86_64): Mach-O 64-bit executable x86_64
Something like:
>>> get_mac_python_archs()
['i386', 'x86_64']
>>>
Possible?
As far as I know, there is no truly reliable way other than to examine the executable files themselves to see which architectures have been lipo-ed together, in other words, what file does. While the distutils.util.get_platform() noted elsewhere probably comes the closest, it is based on configuration information at Python build time and the criteria used has changed between releases and even among distributions of the same release.
For example, if you built a Python 2.6 on OS X 10.6 with the 4-way universal option (ppc, ppc64, i386, x86_64), get_platform() should report macosx-10.6-universal. However, the Apple-suppled Python 2.6 in OS X 10.6 reports the same string even though it is only a 3-way build (no ppc64). EDIT: That may not be the best example since, come to think of it, you probably couldn't build a ppc64 variant with the 10.6 SDK. However, the point still holds that the platform string is too context dependent to be totally reliable. It may be reliable enough for some needs, though. Otherwise, calling out to file or otool etc is likely the best way to go.
The function platform.architecture returns just the platform working:
Python 2.6.5 (r265:79359, Mar 24 2010, 01:32:55)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.machine()
'i386'
the nearest I can get to is by using distutils.util.get_platform:
>>> import distutils.util
>>> distutils.util.get_platform()
'macosx-10.3-fat'
which is the full answer if you are using Python 2.7/3.2, as you can see in the documentation. "Starting from Python 2.7 and Python 3.2 the architecture fat3 is used for a 3-way universal build (ppc, i386, x86_64) and intel is used for a univeral build with the i386 and x86_64 architectures"