This Magisk module contains Python3 3.15 for Android 

Please note that this is NOT an official release of Python!

This is a development release of Python compiled using the source files from the archive

https://www.python.org/ftp/python/3.15.0/Python-3.15.0a1.tgz

in November 2025.

ASUS_I006D:/ $ python --version
Python 3.15.0a1
ASUS_I006D:/ $ 


Also included in this Magisk Module are the OpenSSL libraries necessary to use SSL in Python scripts:

ASUS_I006D:/ $ ls -l /system/usr/lib/*ssl* /system/usr/lib/*crypto*
-rw-r--r-- 1 root root 6846664 2025-11-07 21:11 /system/usr/lib/libcrypto.so.3
-rw-r--r-- 1 root root  914016 2025-11-07 21:11 /system/usr/lib/libssl.so.3
ASUS_I006D:/ $ 


The Python module to install other modules, pip, is already installed:

ASUS_I006D:/ $ pip --version
pip 25.3 from /system/usr/lib/python3.15/site-packages/pip (python 3.15)
ASUS_I006D:/ $ 


There are two Python executables in the module, the binary python3.15 needs the Python library in /system/usr/lib and the binary python3.15-static only needs the standard Android OS libraries:

ASUS_I006D:/ $  LD_LIBRARY_PATH=/system/usr/lib ldd /system/usr/bin/python3.15
	linux-vdso.so.1 => [vdso] (0x7c394f7000)
	libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7c35c1d000)
	libpython3.15.so.1.0 => /system/usr/lib/libpython3.15.so.1.0 (0x7c31c48000)
	libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7c361d2000)
	liblog.so => /system/lib64/liblog.so (0x7c3825d000)
	libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x7c35dc5000)
	libc++.so => /system/lib64/libc++.so (0x7c36055000)
ASUS_I006D:/ $ 


ASUS_I006D:/ $ ldd /system/usr/bin/python3.15-static
	linux-vdso.so.1 => [vdso] (0x759dfda000)
	libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x7598502000)
	libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7598797000)
	liblog.so => /system/lib64/liblog.so (0x7598616000)
	libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x75987c6000)
	libc++.so => /system/lib64/libc++.so (0x7598645000)
ASUS_I006D:/ $ 


The module also contains a "static" binary with stripped symbols:

ASUS_I006D:/ $  file /system/usr/bin/python3.15-static  /system/usr/bin/python3.15-static-stripped
/system/usr/bin/python3.15-static:          ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27d (13750724), not stripped
/system/usr/bin/python3.15-static-stripped: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 31, built by NDK r27d (13750724), stripped
ASUS_I006D:/ $

ASUS_I006D:/ $ ls -ldh /system/usr/bin/python3.15-static /system/usr/bin/python3.15-static-stripped
-rwxr-xr-x 1 root root 36M 2025-11-07 20:39 /system/usr/bin/python3.15-static
-rwxr-xr-x 1 root root 15M 2025-11-07 20:39 /system/usr/bin/python3.15-static-stripped
ASUS_I006D:/ $ 

Please note that a "real" static binary for Python is not really usefull because static binaries in Android can not resolve hostnames via DNS.



The standard executable is the binary that requires the Python library; therefor the wrapper script 

/system/bin/python_wrapper 

is used to execute the python executables:

ASUS_I006D:/ $ ls -l /system/bin | grep python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 idle3 -> ./python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 pip -> ./python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 pip3 -> ./python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 pip3.15 -> ./python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 pydoc3 -> ./python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 python3 -> ./python_wrapper
lrwxrwxrwx 1 root root        16 1970-03-22 02:55 python3-config -> ./python_wrapper
-rwxr-xr-x 1 root root      2579 2025-11-07 20:39 python_wrapper
ASUS_I006D:/ $ 


The wrapper script also sets other environment variables for Python (see below).


The configured directories for site-packages are:

ASUS_I006D:/ $ ASUS_I006D:/ $ python3 -m site
sys.path = [
    '/',
    '/system/usr/lib/python315.zip',
    '/system/usr/lib/python3.15',
    '/system/usr/lib/python3.15/lib-dynload',
    '/system/usr/lib/python3.15/site-packages',
    '/data/local/tmp/home/python3.15/site-packages',
    '/data/local/tmp/home/python/site-packages',
]
USER_BASE: '/data/local/tmp/home/.local' (exists)
USER_SITE: '/data/local/tmp/home/.local/lib/python3.15/site-packages' (doesn't exist)
ENABLE_USER_SITE: True
ASUS_I006D:/ $ 



The directories in /data/local/tmp are writable by the user shell and can be used to add additional site-packages.

pip can be used to install additional Python modules; the target directory for these modules defined in the wrapper script is

/data/local/tmp/home/python/site-packages

To use another target directory for the Python modules export the variable PIP_TARGET before executing pip.
Or use the parameter "--target=<dir>" for pip to set the target directory.


The wrapper script defines the environment variable SSL_CERT_DIR with the value /system/etc/security/cacerts if it is not already defined.

Use 

python -c "import ssl; print(ssl.get_default_verify_paths()) "  

to show which certificate paths are being used.



The wrapper script defines the environment variable PYTHONPYCACHEPREFIX with 

/data/local/tmp/home/python/cache

This directory is then used for the compiled Python scripts. The customization script creates this directory if it does not yet exist.


The wrapper script defines the variable TERMINFO with 

/system/etc/terminfo 

or 

/system_ext/etc/terminfo

if one of these directories exists and the variable TERMINFO is not already defined


The wrapper scripts sets the environment variable LD_LIBRARY_PATH to 

/system/usr/lib


If the directory 

/data/local/tmp/home/libs 

exists it is also added to the environment variable LD_LIBRARY_PATH. This directory should be used for additional library files required by the Python scripts.


Set the variable DEBUG to any non-empty string before executing python to execute the wrapper script with "set -x", e.g.:

DEBUG=yes python --version           


If the file

/data/local/tmp/home/python_init.sh

exists, it will be sourced in by the wrapper script before executing the Python binary.

The file /data/local/tmp/home/python_init.sh can be used to define or overwrite the environment variables for Python ( ... or do anything else)

(see https://docs.python.org/3/using/cmdline.html for a list of supported environment variables; use the variable "$0" in the script to distinguish between the executables)


The Python executables from this Magisk Module were compiled on an ASUS Zenfone 8 with the clang19 toolchain for android 

see 

  http://bnsmb.de/My_HowTos_for_Android.html#How_to_install_a_Toolchain_for_clang_on_phones_without_root_access

or 

  https://xdaforums.com/t/guide-how-to-install-a-toolchain-for-clang-on-phones-without-root-access.4710235/


The clang19 toolchain is also available on github: 

  https://github.com/bnsmb/clang19_toolchain_for_android/


The approbiate patches from Termux are applied.

 ------------------------------------------------------------------------------

All modules included in Python 3.15 are compiled execpt these modules:

The following modules are *disabled* in configure script:
_dbm                  _gdbm                 _gdbm_compat       
_posixshmem           _tkinter                                 


 ------------------------------------------------------------------------------


History

08.11.2025 v1.0.0
  initial release

