portable-python


Nameportable-python JSON
Version 1.9.6 PyPI version JSON
download
home_pagehttps://github.com/codrsquad/portable-python
SummaryPortable python binaries
upload_time2024-11-20 21:53:12
maintainerNone
docs_urlNone
authorZoran Simic
requires_python>=3.6
licenseMIT
keywords python portable binary
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Portable python binaries
========================

.. image:: https://img.shields.io/pypi/v/portable-python.svg
    :target: https://pypi.org/project/portable-python/
    :alt: Version on pypi

.. image:: https://github.com/codrsquad/portable-python/workflows/Tests/badge.svg
    :target: https://github.com/codrsquad/portable-python/actions
    :alt: Tested with Github Actions

.. image:: https://codecov.io/gh/codrsquad/portable-python/branch/main/graph/badge.svg
    :target: https://codecov.io/gh/codrsquad/portable-python
    :alt: Test coverage

.. image:: https://img.shields.io/pypi/pyversions/portable-python.svg
    :target: https://github.com/codrsquad/portable-python
    :alt: Python versions tested (link to github project)


``Portable-Python`` is a CLI (and a python library) for compiling python binaries
from source than can be decompressed in any folder, and used from there without
further ado (ie: no need to run an "installer").


Motivation
----------

The idea here is to allow for automated systems to:

- Easily obtain a python binary, that can be used in sandboxes / workstations / laptops / instances...

- Inspect any python installation, and point out how portable it is, which
  shared or non-standard libraries it is using


Installation
------------

``portable-python`` is a regular python CLI, it can be installed with:

pickley_::

    pickley install portable-python
    portable-python --help
    portable-python inspect /usr/bin/python3

Or pipx_::

    pipx install portable-python
    portable-python inspect /usr/bin/python3

Using ``pip install`` (a CI builder would probably do this)::

    /usr/bin/python3 -mvenv /tmp/pp
    /tmp/pp/bin/python -mpip install portable-python
    /tmp/pp/bin/portable-python --help
    /tmp/pp/bin/portable-python inspect /usr/bin/python3


Supported operating systems
---------------------------

Portable python binaries can be built for Linux and MacOS (Intel/M1/M2).

Currently **Windows is NOT supported**, contributions are welcome.

Python binaries can be produced as "portable" (statically linked, can run from any folder
where the binary is unpacked in), or with a ``--prefix`` (build targeted to live in a
pre-determined folder, like ``/apps/pythonM.m``)

================  ========  ========
Operating system  Portable  --prefix
================  ========  ========
Linux                ✅        ✅
Macos                ✅        ✅
Windows              ❌        ❌
================  ========  ========


Building a portable cpython
===========================

Once ``portable-python`` is installed:

Build a binary::

    cd some-temp-folder
    portable-python build 3.9.7
    ls -l dist/cpython-3.9.7-macos-arm64.tar.gz

Unpack it somewhere::

    tar -C ~/tmp/versions/ -xf dist/cpython-3.9.7-macos-arm64.tar.gz
    ls -l ~/tmp/versions/

It's ready to be used::

    ~/tmp/versions/3.9.7/bin/python --version


Note that you can use ``--dryrun`` mode to inspect what would be done without doing it::

    $ portable-python --dryrun build 3.9.7

    INFO selected: xz openssl gdbm (3 modules) xz:5.2.5 openssl:1.1.1k gdbm:1.18.1
    INFO Platform: macos-x86_64
    ...
    --------------
    -- xz:5.2.5 --
    --------------
    Would download https://tukaani.org/xz/xz-5.2.5.tar.gz
    Would untar build/sources/xz-5.2.5.tar.gz -> build/components/xz
    INFO env PATH=build/deps/bin:/usr/bin:/bin
    INFO env MACOSX_DEPLOYMENT_TARGET=10.14
    Would run: ./configure --prefix=build/deps --enable-shared=no --enable-static=yes ...
    ...
    -------------------
    -- cpython:3.9.7 --
    -------------------
    Would download https://www.python.org/ftp/python/3.9.7/Python-3.9.7.tar.xz
    Would untar build/sources/Python-3.9.7.tar.xz -> build/components/cpython
    ...
    Would run: ./configure --prefix=/ppp-marker/3.9.7 --enable-optimizations ...
    Would run: /usr/bin/make
    Would run: /usr/bin/make install DESTDIR=build
    ...
    Would tar build/3.9.7 -> dist/cpython-3.9.7-macos-x86_64.tar.gz


Library
-------

Portable Python can be used as a python library to invoke builds, or inspect an installation.

Invoke a build from python code::

    from portable_python import BuildSetup

    setup = BuildSetup("cpython:3.9.7")
    setup.compile()


Invoke an inspection from python code::

    from portable_python.inspector import PythonInspector

    inspector = PythonInspector("/usr/bin/python3")
    print(inspector.represented())
    problem = inspector.full_so_report.get_problem(portable=True)
    if problem:
        print("oops, it is not portable!: %s" % problem)


From source, contributions welcome!::

    git clone https://github.com/codrsquad/portable-python.git
    cd portable-python
    python3 -mvenv .venv
    .venv/bin/pip install -r requirements.txt -r tests/requirements.txt
    .venv/bin/pip install -e .
    .venv/bin/portable-python --help
    .venv/bin/portable-python inspect /usr/bin/python3

    tox -e py311
    tox -e style


Build folder structure
----------------------

``portable-python`` uses this file structure (build/ and dist/ folders configurable)::

    build/
        ppp-marker/3.9.7/                   # Full installation (after build completes)
        components/                         # Builds of statically compiled extension modules are here
        deps/                               # --prefix=.../deps passed to all component ./configure scripts
        sources/
            openssl-1.1.1k.tar.gz           # Downloaded artifacts (downloaded only once)
    dist/
        cpython-3.9.7-macos-arm64.tar.gz    # Ready-to-go portable binary tarball


Guiding principles
------------------

- Focuses on just one thing: compile a portable python, and validate that it is indeed portable,
  produce outcome in (configurable) ``./dist/`` folder and that's it

- No patches: C compilation is done as simply as possible without modifying the upstream source code.
  Rely solely on the make/configure scripts, typically via stuff like ``--enable-shared=no``

- Builds are validated, an important part of the effort was to write up code that is able to
  ``inspect`` a python installation and detect whether it is portable or not (and why not if so).

- Only the last few non-EOL versions of python are supported (no historical stuff)

- As time goes on, the code of this tool will evolve so that the latest pythons keep building
  (but won't worry that older versions still keep building)


For this repo itself:

- Code is pure python, it is a CLI with one entry-point called ``portable-python``

  - Can be ran in a debugger

  - 100% test coverage, has a ``--dryrun`` mode to help with testing / debugging / seeing what would be done quickly

  - No shell scripts (those are hard to maintain/test/debug)

  - Can be ``pip install``-ed and reused


.. _pickley: https://pypi.org/project/pickley/

.. _pipx: https://pypi.org/project/pipx/

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/codrsquad/portable-python",
    "name": "portable-python",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "python, portable, binary",
    "author": "Zoran Simic",
    "author_email": "zoran@simicweb.com",
    "download_url": "https://files.pythonhosted.org/packages/4a/24/b73e4be5212118facbae6974351204cd24e5207ab159d99d3fc8ca0664b8/portable_python-1.9.6.tar.gz",
    "platform": null,
    "description": "Portable python binaries\n========================\n\n.. image:: https://img.shields.io/pypi/v/portable-python.svg\n    :target: https://pypi.org/project/portable-python/\n    :alt: Version on pypi\n\n.. image:: https://github.com/codrsquad/portable-python/workflows/Tests/badge.svg\n    :target: https://github.com/codrsquad/portable-python/actions\n    :alt: Tested with Github Actions\n\n.. image:: https://codecov.io/gh/codrsquad/portable-python/branch/main/graph/badge.svg\n    :target: https://codecov.io/gh/codrsquad/portable-python\n    :alt: Test coverage\n\n.. image:: https://img.shields.io/pypi/pyversions/portable-python.svg\n    :target: https://github.com/codrsquad/portable-python\n    :alt: Python versions tested (link to github project)\n\n\n``Portable-Python`` is a CLI (and a python library) for compiling python binaries\nfrom source than can be decompressed in any folder, and used from there without\nfurther ado (ie: no need to run an \"installer\").\n\n\nMotivation\n----------\n\nThe idea here is to allow for automated systems to:\n\n- Easily obtain a python binary, that can be used in sandboxes / workstations / laptops / instances...\n\n- Inspect any python installation, and point out how portable it is, which\n  shared or non-standard libraries it is using\n\n\nInstallation\n------------\n\n``portable-python`` is a regular python CLI, it can be installed with:\n\npickley_::\n\n    pickley install portable-python\n    portable-python --help\n    portable-python inspect /usr/bin/python3\n\nOr pipx_::\n\n    pipx install portable-python\n    portable-python inspect /usr/bin/python3\n\nUsing ``pip install`` (a CI builder would probably do this)::\n\n    /usr/bin/python3 -mvenv /tmp/pp\n    /tmp/pp/bin/python -mpip install portable-python\n    /tmp/pp/bin/portable-python --help\n    /tmp/pp/bin/portable-python inspect /usr/bin/python3\n\n\nSupported operating systems\n---------------------------\n\nPortable python binaries can be built for Linux and MacOS (Intel/M1/M2).\n\nCurrently **Windows is NOT supported**, contributions are welcome.\n\nPython binaries can be produced as \"portable\" (statically linked, can run from any folder\nwhere the binary is unpacked in), or with a ``--prefix`` (build targeted to live in a\npre-determined folder, like ``/apps/pythonM.m``)\n\n================  ========  ========\nOperating system  Portable  --prefix\n================  ========  ========\nLinux                \u2705        \u2705\nMacos                \u2705        \u2705\nWindows              \u274c        \u274c\n================  ========  ========\n\n\nBuilding a portable cpython\n===========================\n\nOnce ``portable-python`` is installed:\n\nBuild a binary::\n\n    cd some-temp-folder\n    portable-python build 3.9.7\n    ls -l dist/cpython-3.9.7-macos-arm64.tar.gz\n\nUnpack it somewhere::\n\n    tar -C ~/tmp/versions/ -xf dist/cpython-3.9.7-macos-arm64.tar.gz\n    ls -l ~/tmp/versions/\n\nIt's ready to be used::\n\n    ~/tmp/versions/3.9.7/bin/python --version\n\n\nNote that you can use ``--dryrun`` mode to inspect what would be done without doing it::\n\n    $ portable-python --dryrun build 3.9.7\n\n    INFO selected: xz openssl gdbm (3 modules) xz:5.2.5 openssl:1.1.1k gdbm:1.18.1\n    INFO Platform: macos-x86_64\n    ...\n    --------------\n    -- xz:5.2.5 --\n    --------------\n    Would download https://tukaani.org/xz/xz-5.2.5.tar.gz\n    Would untar build/sources/xz-5.2.5.tar.gz -> build/components/xz\n    INFO env PATH=build/deps/bin:/usr/bin:/bin\n    INFO env MACOSX_DEPLOYMENT_TARGET=10.14\n    Would run: ./configure --prefix=build/deps --enable-shared=no --enable-static=yes ...\n    ...\n    -------------------\n    -- cpython:3.9.7 --\n    -------------------\n    Would download https://www.python.org/ftp/python/3.9.7/Python-3.9.7.tar.xz\n    Would untar build/sources/Python-3.9.7.tar.xz -> build/components/cpython\n    ...\n    Would run: ./configure --prefix=/ppp-marker/3.9.7 --enable-optimizations ...\n    Would run: /usr/bin/make\n    Would run: /usr/bin/make install DESTDIR=build\n    ...\n    Would tar build/3.9.7 -> dist/cpython-3.9.7-macos-x86_64.tar.gz\n\n\nLibrary\n-------\n\nPortable Python can be used as a python library to invoke builds, or inspect an installation.\n\nInvoke a build from python code::\n\n    from portable_python import BuildSetup\n\n    setup = BuildSetup(\"cpython:3.9.7\")\n    setup.compile()\n\n\nInvoke an inspection from python code::\n\n    from portable_python.inspector import PythonInspector\n\n    inspector = PythonInspector(\"/usr/bin/python3\")\n    print(inspector.represented())\n    problem = inspector.full_so_report.get_problem(portable=True)\n    if problem:\n        print(\"oops, it is not portable!: %s\" % problem)\n\n\nFrom source, contributions welcome!::\n\n    git clone https://github.com/codrsquad/portable-python.git\n    cd portable-python\n    python3 -mvenv .venv\n    .venv/bin/pip install -r requirements.txt -r tests/requirements.txt\n    .venv/bin/pip install -e .\n    .venv/bin/portable-python --help\n    .venv/bin/portable-python inspect /usr/bin/python3\n\n    tox -e py311\n    tox -e style\n\n\nBuild folder structure\n----------------------\n\n``portable-python`` uses this file structure (build/ and dist/ folders configurable)::\n\n    build/\n        ppp-marker/3.9.7/                   # Full installation (after build completes)\n        components/                         # Builds of statically compiled extension modules are here\n        deps/                               # --prefix=.../deps passed to all component ./configure scripts\n        sources/\n            openssl-1.1.1k.tar.gz           # Downloaded artifacts (downloaded only once)\n    dist/\n        cpython-3.9.7-macos-arm64.tar.gz    # Ready-to-go portable binary tarball\n\n\nGuiding principles\n------------------\n\n- Focuses on just one thing: compile a portable python, and validate that it is indeed portable,\n  produce outcome in (configurable) ``./dist/`` folder and that's it\n\n- No patches: C compilation is done as simply as possible without modifying the upstream source code.\n  Rely solely on the make/configure scripts, typically via stuff like ``--enable-shared=no``\n\n- Builds are validated, an important part of the effort was to write up code that is able to\n  ``inspect`` a python installation and detect whether it is portable or not (and why not if so).\n\n- Only the last few non-EOL versions of python are supported (no historical stuff)\n\n- As time goes on, the code of this tool will evolve so that the latest pythons keep building\n  (but won't worry that older versions still keep building)\n\n\nFor this repo itself:\n\n- Code is pure python, it is a CLI with one entry-point called ``portable-python``\n\n  - Can be ran in a debugger\n\n  - 100% test coverage, has a ``--dryrun`` mode to help with testing / debugging / seeing what would be done quickly\n\n  - No shell scripts (those are hard to maintain/test/debug)\n\n  - Can be ``pip install``-ed and reused\n\n\n.. _pickley: https://pypi.org/project/pickley/\n\n.. _pipx: https://pypi.org/project/pipx/\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Portable python binaries",
    "version": "1.9.6",
    "project_urls": {
        "Documentation": "https://github.com/codrsquad/portable-python/wiki",
        "Homepage": "https://github.com/codrsquad/portable-python",
        "Release notes": "https://github.com/codrsquad/portable-python/wiki/Release-notes",
        "Source": "https://github.com/codrsquad/portable-python"
    },
    "split_keywords": [
        "python",
        " portable",
        " binary"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c6b508e69f76e75d2ca2dfd46c5c67cbe84e03666fe726cbfad7b708315b0966",
                "md5": "4554d335fe5bba3fc113616616d6e0f0",
                "sha256": "bc9d80186e11e2d7fe9e9ce844375ab5332a0015a45d3a9c8a09941b044502b0"
            },
            "downloads": -1,
            "filename": "portable_python-1.9.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4554d335fe5bba3fc113616616d6e0f0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 40698,
            "upload_time": "2024-11-20T21:53:10",
            "upload_time_iso_8601": "2024-11-20T21:53:10.008578Z",
            "url": "https://files.pythonhosted.org/packages/c6/b5/08e69f76e75d2ca2dfd46c5c67cbe84e03666fe726cbfad7b708315b0966/portable_python-1.9.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4a24b73e4be5212118facbae6974351204cd24e5207ab159d99d3fc8ca0664b8",
                "md5": "7ae4afd4898e3afd646525909bfc90b7",
                "sha256": "51837fd66fad2ecf7500032f10990fa0f6d0524d3b3071b397ef0eb526c0fcc1"
            },
            "downloads": -1,
            "filename": "portable_python-1.9.6.tar.gz",
            "has_sig": false,
            "md5_digest": "7ae4afd4898e3afd646525909bfc90b7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 46609,
            "upload_time": "2024-11-20T21:53:12",
            "upload_time_iso_8601": "2024-11-20T21:53:12.041749Z",
            "url": "https://files.pythonhosted.org/packages/4a/24/b73e4be5212118facbae6974351204cd24e5207ab159d99d3fc8ca0664b8/portable_python-1.9.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-20 21:53:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "codrsquad",
    "github_project": "portable-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "tox": true,
    "lcname": "portable-python"
}
        
Elapsed time: 7.56407s