When I press tab
on the command python3.7
I get the following
python3.7 python3.7-config python3.7m python3.7m-config
I looked up what's python3.7m
and found the answer - https://stackoverflow.com/a/16677339/6849682.
Next I go to the python terminal of each implementation and type the following code
>>> import sysconfig
>>> sysconfig.get_config_var('EXT_SUFFIX')
I get the same output in both python implementations i.e .cpython-37m-darwin.so
I also tried the command diff <(python3.7 -m sysconfig) <(python3.7m -m sysconfig)
to see if there's any difference in configuration info of the 2 executables but the output is empty means they are the same.
If all the executables and configuration variables are same, then why create two different implementations of python?
Note:
I'm not talking about python3.7/3.7m-config
here.
For a C extension to be compatible across interpreter builds, some of the build-time flags need to be identical. One of these flags is whether pymalloc
(a memory-allocation library intended to be faster for Python-specific use cases) is enabled. Versions of libpython have an m
suffix indicating that this flag was present at build time, when it in fact was.
If a C extension is built with pymalloc support, it can't be used by an interpreter using the standard C library's malloc()
, and the inverse. Consequently, for someone who has a C extension as a prebuilt binary that was built with pymalloc
, it can be useful to be able to start a Python interpreter that is known to be itself pymalloc
-enabled.
If a Linux distribution chooses to only ship a pymalloc-enabled interpreter, it makes sense to have only one binary available under both python3.7
and python3.7m
names. (This leaves folks who need a non-pymalloc interpreter a bit out of luck, but build tools aren't as hard to come by on Linux as they are on Windows, so ABI compatibility is not as critical).
python3.7
and python3.7m
are the same program, just with two different names. These two files are hard-linked, meaning they point to the same file on disk (i.e., they have the same inode).
Here is the line in the cpython 3.7 Makefile
that performs this hardlink.
(cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE));
$(LDVERSION)
would be 3.7m
, and $(VERSION)
would be 3.7
. This is the only place in the Makefile that performs a hardlink.
The python3.7 Docker image is used below to demonstrate that python3.7
and python3.7
have the same inode.
$ docker run --rm -it python:3.7-alpine ash
/ # ls -i $(which python3.7)
927902 /usr/local/bin/python3.7
/ # ls -i $(which python3.7m)
927902 /usr/local/bin/python3.7m
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With