Name | universalPip JSON |
Version |
0.1.1
JSON |
| download |
home_page | None |
Summary | Creates an Universal2 distribution for given package on PyPI and installs it. |
upload_time | 2024-08-08 21:09:15 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | None |
keywords |
universal2
arm64
macosx
pyinstaller
x86_64
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# README
## universalPip
#### Universal Package Installer for Python
[![PyPI](https://img.shields.io/pypi/v/universalPip)](https://pypi.org/project/universalPip/)
[![downloads](https://static.pepy.tech/badge/universalPip/month)](https://pepy.tech/project/universalPip)
## Table of contents
- [Description](#description)
- [Story](#story)
- [Note about universal wheels](#note-about-universal-wheels)
- [Note about packaging](#important-note-about-packaging)
- [`uPip`'s installation logic](#uPips-installation-logic)
- [Uninstall packages](#how-to-uninstall-packages-installed-by-uPip)
- [Install the CLI](#installation)
- [Usage](#usage)
- [Install a package](#install-a-package)
- [Create `universal2` wheel](#create-an-universal2-wheel)
- [Check if a package is universal](#check-if-a-package-is-universal)
- [Show default stored wheel directory](#show-default-stored-wheel-directory)
- [Invoke pip](#invoke-pip)
- [`uPip`'s version](#printing-uPips-version)
- [Print documentation](#print-documentation)
- [Contributing](#contributing)
- [License](#license)
## Changelog
You can view the complete changelog [here](https://github.com/MaximeLeMagicien/uPip/blob/main/Changelog.md).
<hr>
### Description
The `universalPip` package (called `uPip` in this document) is a Python package which completes the `pip` command line tool provided with any standard Python3 installation. `uPip`'s main goal is to provide an easy way to install any python package in `universal2` binary mode, which is compatible with any macOS installation.
### Story
As you probably know, Apple recently stopped using `intel chips` as their processor for new macs. They released in September 2020 their own chip called the `M1`. Unfortunatly, apps built on intel chips can't run properly on M1 and newer chips. A complete app rebuild is necessary. Even if `rosetta` exists and enables the aibility to run `x86_64` apps on `M1` architecture, it is not a durable solution.
Due to the fact that most people still uses `intel` architecture and want to publish apps on both architectures, developers needs to package their apps into an `universal` app bundle in order to run their app on any mac installation.
Those changes had an huge impact on Python packages. In fact, all binary files (with `.so` extension) needed to be recompiled on newer macs with M1 chips to extend compatibility. This is why packages with binary dependencies now provides two different wheels: the first one `macosx_10_X_x86_64.whl` for `intel` macs and `macosx_11_0_arm64.whl` for `M1` macs and newer. See [below](#important-note-about-packaging) for more information.
In order to compile applications in universal mode, with `pyinstaller` for example; installed wheels in the Python environment need to have both architectures inside their `.so` binaries files. Usually these wheel distributions are named like this: `macosx_11_0_universal2.whl` (See [here](#note-about-universal-wheels) for more information about compiling `universal2` applications using `pyinstaller`). <u>Unfortunatly, some packages do not provide these kind of wheels but only seperarated wheels for each architecture.</u>
`uPip`'s story starts here: knowing all the facts mentionned above, the Python Package Index needed a new package to easily install any Python package in `universal2` mode. <u>`uPip` has `pip`'s same capabilities but adds a layer of verification when installing a package. If no `universal2` distribution wheel exists in the package repository, it will download each architecture wheel and fusionnate their wheels to create an `universal2` distribution and then install it.</u> Read [installation logic](#uPips-installation-logic) for further information.
### Note about universal wheels
`uPip`'s main goal is to handle the case where no `universal2` wheel distribution is provided for a package release. But not all packages needs an `universal2` wheel. In fact, if a package (like this one) doesn't have any binary dependencies, it often has only one release named `py3-none-any.whl` which means that all package's logic is coded in Python only and is compatible with any installation. So, even on `arm64` or `x86_64` mac architectures, those packages will work normally. See [installation logic](#uPips-installation-logic) for more information.
### Important note about packaging
Even if compiling universal app bundles for both `x86_64` and `arm64` architectures is possible, universal applications are way heavier in terms of size than separated architecture applications. For instance, a small app packaged with `pyinstaller` for `x86_64` only has a 50 MB size whereas the same application compiled in `universal2` mode has a 250 MB size.<br><b>Take this warning in consideration when compiling bigger applications because their final size can either double or triple!</b>
In order to compile an universal bundle on macOS with PyInstaller, you need to have all your project's requirements and dependencies installed in `universal2` mode and set inside your `.spec` file the target architecture to `universal2`. Read [pyinstaller's documentation](https://pyinstaller.org/en/stable/feature-notes.html#macos-multi-arch-support) for more information.
### `uPip`'s Installation logic
When installing a package, `uPip` will follow this logic:
- First, check if an `universal2.whl` exists for the given release version.
- If such a release exists, downloads it and installs it
- If no `universal2.whl` distribution exists, checks if a distribution `p3-none-any.whl` exists, meaning that the current packages has no platform specific dependencies.
- If such a release exists, downloads it and installs it
- If neither `universal2.whl` and `p3-none-any.whl` distribution exists, downloads both `macos_10_X_x86_64.whl` and `macosx_11_0_arm64.whl` wheels to fuse them into `macosx_11_0_universal2.whl` and then installs the created wheel.
When the universal2 wheel is installed, `uPip` checks the newly installed package's dependencies to also update them if they are not in universal2 mode. The same logic applies for processing package's dependencies as described above.
### How to uninstall packages installed by `uPip`?
There is no specific tool to uninstall packages installed by `uPip`. You can use `pip` directly to uninstall any package installed by `uPip` as you would normally do for a normal package. Or you can [invoke pip from `uPip`](#invoke-pip) to be sure to call the same python version as the one used by `uPip`.
### Installation
To install the `uPip` package, you can use the following command:
```shell
$ pip install universalPip
```
To verify the installation, call the `uPip` CLI from the terminal:
```shell
$ uPip
```
If the CLI is correctly installed, the documentation should show up.
### Usage
#### Install a package
<hr>
Once installed, you can use the `uPip` package to install other Python packages. Here's an example:
<br>Let's say we want to install [mzdata2mat](https://github.com/MaximeLeMagicien/mzdata2mat), a package aimed to convert `.mzData.xml` files into `.mat` files. Here is the command to install the package:
```shell
$ uPip --install mzdata2mat
```
The installation will be performed into the `site-packages` of the python installation which downloaded `uPip` inside the `wheels` folder.<br>
Additionnaly, you can add `--version` tag to specify a release version to install. Command would be:
```shell
$ uPip --install mzdata2mat --version "1.0.0"
```
If no version is specified, the latest one will be used.
<hr>
#### Create an universal2 wheel
If you just want to create a wheel without installing it, use the following command:
```shell
$ uPip --makeU mzdata2mat
```
Same logic for the `--version` tag, either specify it to create an `universal2` wheel or don't specify it and the latest version available will be used.
All created wheels are stored inside `uPip`'s install directory in the `site-packages` of the python installation in a folder called `wheels`. If you want to specify a custom path use the following command:
```shell
$ uPip --makeU mzdata2mat --destination "path/to/folder"
```
If `--destination` is not provided, default path will be used.
<hr>
#### Check if a package is universal
To avoid installing twice a package already in `universal2` mode, you can use the verification process of `uPip` by using this command:
```shell
$ uPip --checkU mzdata2mat
```
This command will verify if all `.so` files inside `mzdata2mat` package are in fat mode with both `arm64` and `x86_64` architectures inside.
<hr>
#### Show default stored wheel directory
You can show where is located the `wheels` directory by using this command:
```shell
$ uPip --showPath
```
This will print the default save location.
<hr>
#### Invoke `pip`
You can trigger pip from `uPip` CLI by adding this parameter to the command: `--pip`.
Here is an example:
```shell
$ uPip --pip "show mzdata2mat"
```
One main advantage to use `uPip` to call `pip` is to be sure to call the same python version of pip as the one used to run `uPip`. For instance, it could be useful to run pip like this in order to uninstall packages.
<hr>
#### Printing `uPip`'s version
To show `uPip`'s version use the following command:
```shell
$ uPip --V
```
<hr>
#### Print documentation
As a normal package, to print `uPip`'s documentation in the terminal use the following command:
```shell
$ uPip -h
```
or simply:
```shell
$ uPip
```
In fact, if there is no parameters provided with `uPip`'s call, documentation is printed by default.
### Contributing
Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the [GitHub repository](https://github.com/MaximeLeMagicien/uPip).
### License
This package is licensed under the MIT License. See the [LICENSE](https://github.com/MaximeLeMagicien/uPip/blob/main/LICENSE) file for more details.
Raw data
{
"_id": null,
"home_page": null,
"name": "universalPip",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "Universal2, arm64, macOSX, pyinstaller, x86_64",
"author": null,
"author_email": "Maxime CORDELLA <maxime.cordella.1@ulaval.ca>",
"download_url": "https://files.pythonhosted.org/packages/c9/45/cdf25d80cfdf2bf09a770c3bc19cf86a822a2894b476098f965f52990457/universalpip-0.1.1.tar.gz",
"platform": null,
"description": "# README\n\n## universalPip\n#### Universal Package Installer for Python\n\n[![PyPI](https://img.shields.io/pypi/v/universalPip)](https://pypi.org/project/universalPip/)\n[![downloads](https://static.pepy.tech/badge/universalPip/month)](https://pepy.tech/project/universalPip)\n\n## Table of contents\n- [Description](#description)\n- [Story](#story)\n- [Note about universal wheels](#note-about-universal-wheels)\n- [Note about packaging](#important-note-about-packaging)\n- [`uPip`'s installation logic](#uPips-installation-logic)\n- [Uninstall packages](#how-to-uninstall-packages-installed-by-uPip)\n- [Install the CLI](#installation)\n- [Usage](#usage)\n - [Install a package](#install-a-package)\n - [Create `universal2` wheel](#create-an-universal2-wheel)\n - [Check if a package is universal](#check-if-a-package-is-universal)\n - [Show default stored wheel directory](#show-default-stored-wheel-directory)\n - [Invoke pip](#invoke-pip)\n - [`uPip`'s version](#printing-uPips-version)\n - [Print documentation](#print-documentation)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Changelog\nYou can view the complete changelog [here](https://github.com/MaximeLeMagicien/uPip/blob/main/Changelog.md).\n\n<hr>\n\n### Description\nThe `universalPip` package (called `uPip` in this document) is a Python package which completes the `pip` command line tool provided with any standard Python3 installation. `uPip`'s main goal is to provide an easy way to install any python package in `universal2` binary mode, which is compatible with any macOS installation.\n\n### Story\nAs you probably know, Apple recently stopped using `intel chips` as their processor for new macs. They released in September 2020 their own chip called the `M1`. Unfortunatly, apps built on intel chips can't run properly on M1 and newer chips. A complete app rebuild is necessary. Even if `rosetta` exists and enables the aibility to run `x86_64` apps on `M1` architecture, it is not a durable solution.\n\nDue to the fact that most people still uses `intel` architecture and want to publish apps on both architectures, developers needs to package their apps into an `universal` app bundle in order to run their app on any mac installation.\n\nThose changes had an huge impact on Python packages. In fact, all binary files (with `.so` extension) needed to be recompiled on newer macs with M1 chips to extend compatibility. This is why packages with binary dependencies now provides two different wheels: the first one `macosx_10_X_x86_64.whl` for `intel` macs and `macosx_11_0_arm64.whl` for `M1` macs and newer. See [below](#important-note-about-packaging) for more information.\n\nIn order to compile applications in universal mode, with `pyinstaller` for example; installed wheels in the Python environment need to have both architectures inside their `.so` binaries files. Usually these wheel distributions are named like this: `macosx_11_0_universal2.whl` (See [here](#note-about-universal-wheels) for more information about compiling `universal2` applications using `pyinstaller`). <u>Unfortunatly, some packages do not provide these kind of wheels but only seperarated wheels for each architecture.</u> \n\n`uPip`'s story starts here: knowing all the facts mentionned above, the Python Package Index needed a new package to easily install any Python package in `universal2` mode. <u>`uPip` has `pip`'s same capabilities but adds a layer of verification when installing a package. If no `universal2` distribution wheel exists in the package repository, it will download each architecture wheel and fusionnate their wheels to create an `universal2` distribution and then install it.</u> Read [installation logic](#uPips-installation-logic) for further information.\n\n### Note about universal wheels\n`uPip`'s main goal is to handle the case where no `universal2` wheel distribution is provided for a package release. But not all packages needs an `universal2` wheel. In fact, if a package (like this one) doesn't have any binary dependencies, it often has only one release named `py3-none-any.whl` which means that all package's logic is coded in Python only and is compatible with any installation. So, even on `arm64` or `x86_64` mac architectures, those packages will work normally. See [installation logic](#uPips-installation-logic) for more information.\n\n### Important note about packaging\nEven if compiling universal app bundles for both `x86_64` and `arm64` architectures is possible, universal applications are way heavier in terms of size than separated architecture applications. For instance, a small app packaged with `pyinstaller` for `x86_64` only has a 50 MB size whereas the same application compiled in `universal2` mode has a 250 MB size.<br><b>Take this warning in consideration when compiling bigger applications because their final size can either double or triple!</b>\n\nIn order to compile an universal bundle on macOS with PyInstaller, you need to have all your project's requirements and dependencies installed in `universal2` mode and set inside your `.spec` file the target architecture to `universal2`. Read [pyinstaller's documentation](https://pyinstaller.org/en/stable/feature-notes.html#macos-multi-arch-support) for more information.\n\n### `uPip`'s Installation logic\nWhen installing a package, `uPip` will follow this logic: \n- First, check if an `universal2.whl` exists for the given release version.\n - If such a release exists, downloads it and installs it\n- If no `universal2.whl` distribution exists, checks if a distribution `p3-none-any.whl` exists, meaning that the current packages has no platform specific dependencies.\n - If such a release exists, downloads it and installs it\n- If neither `universal2.whl` and `p3-none-any.whl` distribution exists, downloads both `macos_10_X_x86_64.whl` and `macosx_11_0_arm64.whl` wheels to fuse them into `macosx_11_0_universal2.whl` and then installs the created wheel.\n\nWhen the universal2 wheel is installed, `uPip` checks the newly installed package's dependencies to also update them if they are not in universal2 mode. The same logic applies for processing package's dependencies as described above.\n\n### How to uninstall packages installed by `uPip`?\nThere is no specific tool to uninstall packages installed by `uPip`. You can use `pip` directly to uninstall any package installed by `uPip` as you would normally do for a normal package. Or you can [invoke pip from `uPip`](#invoke-pip) to be sure to call the same python version as the one used by `uPip`.\n\n### Installation\nTo install the `uPip` package, you can use the following command:\n\n```shell\n$ pip install universalPip\n```\nTo verify the installation, call the `uPip` CLI from the terminal:\n```shell\n$ uPip\n```\nIf the CLI is correctly installed, the documentation should show up.\n\n### Usage\n#### Install a package \n<hr>\nOnce installed, you can use the `uPip` package to install other Python packages. Here's an example:\n\n<br>Let's say we want to install [mzdata2mat](https://github.com/MaximeLeMagicien/mzdata2mat), a package aimed to convert `.mzData.xml` files into `.mat` files. Here is the command to install the package:\n\n```shell\n$ uPip --install mzdata2mat\n```\nThe installation will be performed into the `site-packages` of the python installation which downloaded `uPip` inside the `wheels` folder.<br>\n\nAdditionnaly, you can add `--version` tag to specify a release version to install. Command would be: \n```shell\n$ uPip --install mzdata2mat --version \"1.0.0\"\n```\nIf no version is specified, the latest one will be used.\n<hr>\n\n#### Create an universal2 wheel\nIf you just want to create a wheel without installing it, use the following command:\n```shell\n$ uPip --makeU mzdata2mat\n```\nSame logic for the `--version` tag, either specify it to create an `universal2` wheel or don't specify it and the latest version available will be used.\n\nAll created wheels are stored inside `uPip`'s install directory in the `site-packages` of the python installation in a folder called `wheels`. If you want to specify a custom path use the following command:\n```shell\n$ uPip --makeU mzdata2mat --destination \"path/to/folder\"\n```\n\nIf `--destination` is not provided, default path will be used.\n<hr>\n\n#### Check if a package is universal\nTo avoid installing twice a package already in `universal2` mode, you can use the verification process of `uPip` by using this command:\n```shell\n$ uPip --checkU mzdata2mat\n```\nThis command will verify if all `.so` files inside `mzdata2mat` package are in fat mode with both `arm64` and `x86_64` architectures inside.\n<hr>\n\n#### Show default stored wheel directory\nYou can show where is located the `wheels` directory by using this command:\n```shell\n$ uPip --showPath\n```\nThis will print the default save location.\n<hr>\n\n#### Invoke `pip`\nYou can trigger pip from `uPip` CLI by adding this parameter to the command: `--pip`.\nHere is an example:\n```shell\n$ uPip --pip \"show mzdata2mat\"\n```\nOne main advantage to use `uPip` to call `pip` is to be sure to call the same python version of pip as the one used to run `uPip`. For instance, it could be useful to run pip like this in order to uninstall packages.\n\n<hr>\n\n#### Printing `uPip`'s version\nTo show `uPip`'s version use the following command:\n```shell\n$ uPip --V\n```\n\n<hr>\n\n#### Print documentation\nAs a normal package, to print `uPip`'s documentation in the terminal use the following command:\n```shell\n$ uPip -h\n```\nor simply:\n```shell\n$ uPip\n```\nIn fact, if there is no parameters provided with `uPip`'s call, documentation is printed by default.\n### Contributing\nContributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the [GitHub repository](https://github.com/MaximeLeMagicien/uPip).\n\n### License\nThis package is licensed under the MIT License. See the [LICENSE](https://github.com/MaximeLeMagicien/uPip/blob/main/LICENSE) file for more details.",
"bugtrack_url": null,
"license": null,
"summary": "Creates an Universal2 distribution for given package on PyPI and installs it.",
"version": "0.1.1",
"project_urls": {
"Changelog": "https://github.com/MaximeLeMagicien/uPip/blob/main/Changelog.md",
"Homepage": "https://github.com/MaximeLeMagicien/uPip",
"Issues": "https://github.com/MaximeLeMagicien/uPip/issues"
},
"split_keywords": [
"universal2",
" arm64",
" macosx",
" pyinstaller",
" x86_64"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a3818bf18a0c4272071c92be55a8f5d40cf42246711cf04d326129f6a1fc3b43",
"md5": "81205d6cdf77b0148b9004a578bd450b",
"sha256": "62c753ad1d5ea2b8950e7177459f9e703005a43de33eff66986f5638f8038c19"
},
"downloads": -1,
"filename": "universalpip-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "81205d6cdf77b0148b9004a578bd450b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 10170,
"upload_time": "2024-08-08T21:09:14",
"upload_time_iso_8601": "2024-08-08T21:09:14.351738Z",
"url": "https://files.pythonhosted.org/packages/a3/81/8bf18a0c4272071c92be55a8f5d40cf42246711cf04d326129f6a1fc3b43/universalpip-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c945cdf25d80cfdf2bf09a770c3bc19cf86a822a2894b476098f965f52990457",
"md5": "1e80ded5c70748f504deee6fddf1d02a",
"sha256": "085748a1670590d425a4dfa681154ebcdb52cbb586bbfcae08942d2873317b1a"
},
"downloads": -1,
"filename": "universalpip-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "1e80ded5c70748f504deee6fddf1d02a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 8957,
"upload_time": "2024-08-08T21:09:15",
"upload_time_iso_8601": "2024-08-08T21:09:15.325371Z",
"url": "https://files.pythonhosted.org/packages/c9/45/cdf25d80cfdf2bf09a770c3bc19cf86a822a2894b476098f965f52990457/universalpip-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-08 21:09:15",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "MaximeLeMagicien",
"github_project": "uPip",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "universalpip"
}