Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-installer for
openSUSE:Factory checked in at 2022-12-15 19:24:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-installer (Old)
and /work/SRC/openSUSE:Factory/.python-installer.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-installer"
Thu Dec 15 19:24:11 2022 rev:4 rq:1042890 version:0.6.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-installer/python-installer.changes
2022-06-17 21:23:13.474796528 +0200
+++
/work/SRC/openSUSE:Factory/.python-installer.new.1835/python-installer.changes
2022-12-15 19:24:14.383726719 +0100
@@ -1,0 +2,6 @@
+Tue Dec 13 15:40:26 UTC 2022 - Yogalakshmi Arunachalam <[email protected]>
+
+- Update to 0.6.0
+ * Add support for Python 3.11
+
+-------------------------------------------------------------------
Old:
----
installer-0.5.1.tar.gz
New:
----
installer-0.6.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-installer.spec ++++++
--- /var/tmp/diff_new_pack.QHh1Y1/_old 2022-12-15 19:24:14.951729952 +0100
+++ /var/tmp/diff_new_pack.QHh1Y1/_new 2022-12-15 19:24:14.959729997 +0100
@@ -26,7 +26,7 @@
%bcond_with test
%endif
Name: python-installer%{pkg_suffix}
-Version: 0.5.1
+Version: 0.6.0
Release: 0
Summary: A library for installing Python wheels
License: MIT
++++++ installer-0.5.1.tar.gz -> installer-0.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/.github/workflows/ci.yml
new/installer-0.6.0/.github/workflows/ci.yml
--- old/installer-0.5.1/.github/workflows/ci.yml 2022-02-16
20:24:54.870046600 +0100
+++ new/installer-0.6.0/.github/workflows/ci.yml 2022-12-07
03:28:06.838576600 +0100
@@ -4,6 +4,14 @@
push:
branches: [main]
+concurrency:
+ # prettier-ignore
+ group: >-
+ ${{ github.workflow }}-
+ ${{ github.ref_type }}-
+ ${{ github.event.pull_request.number || github.sha }}
+ cancel-in-progress: true
+
jobs:
tests:
name: tests / ${{ matrix.os }} / ${{ matrix.python-version }}
@@ -12,17 +20,17 @@
strategy:
matrix:
os: [Windows, Ubuntu, MacOS]
- python-version: ["3.7", "3.8", "3.9", "3.10"]
+ python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
include:
# Only run PyPy jobs, on Ubuntu.
- os: Ubuntu
python-version: pypy-3.7
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
# Get Python to test against
- - uses: actions/setup-python@v2
+ - uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
@@ -34,7 +42,7 @@
id: pip-cache-dir
run: echo "::set-output name=dir::$(pip cache dir)"
- name: pip cache
- uses: actions/cache@v1
+ uses: actions/cache@v3
with:
path: ${{ steps.pip-cache-dir.outputs.dir }}
key: pip-v1-${{ runner.os }}-${{ steps.date.outputs.date }}
@@ -42,9 +50,11 @@
- run: pip install nox
+ # prettier-ignore
- run: >
nox
- -s test-${{ matrix.python-version }} doctest-${{
matrix.python-version }}
+ -s test-${{ matrix.python-version }}
+ doctest-${{ matrix.python-version }}
--error-on-missing-interpreters
if: matrix.python-version != 'pypy-3.7'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/.pre-commit-config.yaml
new/installer-0.6.0/.pre-commit-config.yaml
--- old/installer-0.5.1/.pre-commit-config.yaml 2022-02-16 20:24:54.870880800
+0100
+++ new/installer-0.6.0/.pre-commit-config.yaml 2022-12-07 03:28:06.838862000
+0100
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
- rev: "22.1.0"
+ rev: "22.10.0"
hooks:
- id: black
language_version: python3.8
@@ -12,13 +12,19 @@
files: \.py$
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: "v0.931"
+ rev: "v0.991"
hooks:
- id: mypy
exclude: docs/.*|tests/.*|noxfile.py
+ - repo: https://github.com/pre-commit/mirrors-prettier
+ rev: "v3.0.0-alpha.4"
+ hooks:
+ - id: prettier
+ args: [--prose-wrap, always]
+
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: "v4.1.0"
+ rev: "v4.4.0"
hooks:
- id: check-builtin-literals
- id: check-added-large-files
@@ -31,7 +37,7 @@
- id: trailing-whitespace
- repo: https://github.com/PyCQA/flake8
- rev: "4.0.1"
+ rev: "6.0.0"
hooks:
- id: flake8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/.readthedocs.yml
new/installer-0.6.0/.readthedocs.yml
--- old/installer-0.5.1/.readthedocs.yml 2022-02-16 20:39:36.766151700
+0100
+++ new/installer-0.6.0/.readthedocs.yml 2022-03-24 09:42:24.281402800
+0100
@@ -8,3 +8,5 @@
version: 3.8
install:
- requirements: docs/requirements.txt
+ - method: pip
+ path: .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/CONTRIBUTING.md
new/installer-0.6.0/CONTRIBUTING.md
--- old/installer-0.5.1/CONTRIBUTING.md 2021-07-29 01:44:40.748468900 +0200
+++ new/installer-0.6.0/CONTRIBUTING.md 2022-03-13 08:38:01.852072000 +0100
@@ -13,8 +13,8 @@
## Bugs and Feature Requests
If you have found any bugs or would like to request a new feature, please do
-check if there is an existing issue already filed for the same, in the
-project's GitHub [issue tracker]. If not, please file a new issue.
+check if there is an existing issue already filed for the same, in the
project's
+GitHub [issue tracker]. If not, please file a new issue.
If you want to help out by fixing bugs, choose an open issue in the [issue
tracker] to work on and claim it by posting a comment saying "I would like to
@@ -35,7 +35,7 @@
Checklist:
-1. All pull requests *must* be made against the `main` branch.
+1. All pull requests _must_ be made against the `main` branch.
2. Include tests for any functionality you implement. Any contributions helping
improve existing tests are welcome.
3. Update documentation as necessary and provide documentation for any new
@@ -94,8 +94,10 @@
[pytest]: https://docs.pytest.org/en/stable/
[coverage]: https://coverage.readthedocs.io/
-[code coverage isn't everything]:
https://bryanpendleton.blogspot.com/2011/02/code-coverage-isnt-everything-but-its.html
-[pytest's rich CLI]:
https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests
+[code coverage isn't everything]:
+
https://bryanpendleton.blogspot.com/2011/02/code-coverage-isnt-everything-but-its.html
+[pytest's rich cli]:
+ https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests
### Documentation
@@ -107,4 +109,4 @@
$ nox -s docs
```
-[Sphinx]: https://www.sphinx-doc.org/
+[sphinx]: https://www.sphinx-doc.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/PKG-INFO new/installer-0.6.0/PKG-INFO
--- old/installer-0.5.1/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/installer-0.6.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +1,28 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: installer
-Version: 0.5.1
+Version: 0.6.0
Summary: A library for installing Python wheels.
-Home-page: None
-Author: None
Author-email: Pradyun Gedam <[email protected]>
+Requires-Python: >=3.7
+Description-Content-Type: text/markdown
+Classifier: License :: OSI Approved :: MIT License
+Project-URL: GitHub, https://github.com/pypa/installer
+
+# installer
+
+<!-- start readme-pitch -->
+
+This is a low-level library for installing a Python package from a
+[wheel distribution](https://packaging.python.org/glossary/#term-Wheel). It
+provides basic functionality and abstractions for handling wheels and
installing
+packages from wheels.
+
+- Logic for "unpacking" a wheel (i.e. installation).
+- Abstractions for various parts of the unpacking process.
+- Extensible simple implementations of the abstractions.
+- Platform-independent Python script wrapper generation.
+
+<!-- end readme-pitch -->
+
+You can read more in the [documentation](https://installer.rtfd.io/).
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/README.md
new/installer-0.6.0/README.md
--- old/installer-0.5.1/README.md 2021-07-29 01:44:40.748786000 +0200
+++ new/installer-0.6.0/README.md 2022-03-13 08:38:01.852336600 +0100
@@ -3,9 +3,9 @@
<!-- start readme-pitch -->
This is a low-level library for installing a Python package from a
-[wheel distribution](https://packaging.python.org/glossary/#term-Wheel).
-It provides basic functionality and abstractions for handling wheels and
-installing packages from wheels.
+[wheel distribution](https://packaging.python.org/glossary/#term-Wheel). It
+provides basic functionality and abstractions for handling wheels and
installing
+packages from wheels.
- Logic for "unpacking" a wheel (i.e. installation).
- Abstractions for various parts of the unpacking process.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/_static/custom.css
new/installer-0.6.0/docs/_static/custom.css
--- old/installer-0.5.1/docs/_static/custom.css 2021-07-29 01:44:40.749075700
+0200
+++ new/installer-0.6.0/docs/_static/custom.css 2022-03-13 08:38:01.852982300
+0100
@@ -3,7 +3,7 @@
/* Make inline code blocks nicer to look at */
code.literal {
border-radius: 0.3em;
- padding: 0.0em 0.3em;
+ padding: 0em 0.3em;
}
div.highlight pre {
@@ -21,8 +21,9 @@
/* Add a tiny dash of color to names of things */
dt > .property {
- color: #A02000;
+ color: #a02000;
}
-.sig-name, .sig-prename {
+.sig-name,
+.sig-prename {
color: #0066bb;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/changelog.md
new/installer-0.6.0/docs/changelog.md
--- old/installer-0.5.1/docs/changelog.md 2022-03-11 09:49:14.268968300
+0100
+++ new/installer-0.6.0/docs/changelog.md 2022-12-07 03:29:41.190069000
+0100
@@ -1,5 +1,16 @@
# Changelog
+## v0.6.0 (Dec 7, 2022)
+
+- Add support for Python 3.11 (#154)
+- Encode hashes in `RECORD` files correctly (#141)
+- Add `py.typed` marker file (#138)
+- Implement `--prefix` option (#103)
+- Fix the unbound `is_executable` (#115)
+- Construct `RECORD` file using `csv.writer` (#118)
+- Move away from `import installer.xyz` style imports (#110)
+- Improve existing documentation content (typos, formatting) (#109)
+
## v0.5.1 (Mar 11, 2022)
- Change all names in `installer.__main__` to be underscore prefixed.
@@ -38,9 +49,9 @@
{any}`RecordEntry` objects.
- Implement {any}`WheelFile`, completing the end-to-end wheel installation
pipeline.
-- Generate {any}`RecordEntry` for `RECORD` file in the
- {any}`installer.install`, instead of requiring every `WheelDestination`
- implementation to do the exact same thing.
+- Generate {any}`RecordEntry` for `RECORD` file in the
{any}`installer.install`,
+ instead of requiring every `WheelDestination` implementation to do the exact
+ same thing.
## v0.2.0 (May 3, 2021)
@@ -48,9 +59,9 @@
---
-Thank you to [Dan Ryan] and [Tzu-ping Chung] for the project name on
-PyPI. The PyPI releases before 0.2.0 come from
-<https://github.com/sarugaku/installer> and have been [yanked].
+Thank you to [Dan Ryan] and [Tzu-ping Chung] for the project name on PyPI. The
+PyPI releases before 0.2.0 come from <https://github.com/sarugaku/installer>
and
+have been [yanked].
[dan ryan]: https://github.com/techalchemy
[tzu-ping chung]: https://github.com/uranusjr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/concepts.md
new/installer-0.6.0/docs/concepts.md
--- old/installer-0.5.1/docs/concepts.md 2021-07-29 01:44:40.750274200
+0200
+++ new/installer-0.6.0/docs/concepts.md 2022-03-13 08:38:01.853547600
+0100
@@ -2,39 +2,37 @@
This library has two main abstractions:
-- {any}`WheelSource`: Serves as source of information about a wheel
- file.
-- {any}`WheelDestination`: Handles all file writing and
- post-installation processing.
+- {any}`WheelSource`: Serves as source of information about a wheel file.
+- {any}`WheelDestination`: Handles all file writing and post-installation
+ processing.
## WheelSource
-These objects represent a wheel file, abstracting away how the actual
-file is stored or accessed.
+These objects represent a wheel file, abstracting away how the actual file is
+stored or accessed.
-This allows the core install logic to be used with in-memory wheel
-files, or unzipped-on-disk wheel, or with {any}`zipfile.ZipFile`
-objects from an on-disk wheel, or something else entirely.
-
-This protocol/abstraction is designed to be implementable without a
-direct dependency on this library. This allows for other libraries in
-the Python Packaging ecosystem to provide implementations of the
-protocol, allowing for more code reuse opportunities.
-
-One of the benefits of this fully described interface is the possibility
-to decouple the implementation of additional validation on wheels
-(such as validating the RECORD entries in a wheel match the actual
-contents of the wheel, or enforcing signing requirements) based on what
-the specific usecase demands.
+This allows the core install logic to be used with in-memory wheel files, or
+unzipped-on-disk wheel, or with {any}`zipfile.ZipFile` objects from an on-disk
+wheel, or something else entirely.
+
+This protocol/abstraction is designed to be implementable without a direct
+dependency on this library. This allows for other libraries in the Python
+packaging ecosystem to provide implementations of the protocol, allowing for
+more code reuse opportunities.
+
+One of the benefits of this fully described interface is the possibility to
+decouple the implementation of additional validation on wheels (such as
+validating the RECORD entries in a wheel match the actual contents of the
wheel,
+or enforcing signing requirements) based on what the specific usecase demands.
## WheelDestination
These objects are responsible for handling the writing-to-filesystem
-interactions, determining RECORD file entries and post-install actions
-(like generating .pyc files). While this is a lot of responsibility,
-this was explicitly provided to make it possible for custom
-`WheelDestination` implementations to be more powerful and flexible.
-
-Most of these tasks can either be delegated to utilities provided in
-this library (eg: script generation), or to the Python standard libary
-(eg: generating `.pyc` files).
+interactions, determining RECORD file entries and post-install actions (like
+generating .pyc files). While this is a lot of responsibility, this was
+explicitly provided to make it possible for custom `WheelDestination`
+implementations to be more powerful and flexible.
+
+Most of these tasks can either be delegated to utilities provided in this
+library (eg: script generation), or to the Python standard libary (eg:
+generating `.pyc` files).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/conf.py
new/installer-0.6.0/docs/conf.py
--- old/installer-0.5.1/docs/conf.py 2022-02-16 20:41:21.967974400 +0100
+++ new/installer-0.6.0/docs/conf.py 2022-03-24 09:42:34.875664200 +0100
@@ -1,10 +1,6 @@
"""A sphinx documentation configuration file.
"""
-import os
-import pathlib
-import sys
-
# -- Project information
---------------------------------------------------------------
#
https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
@@ -44,14 +40,6 @@
# Don't show the class signature with the class name.
autodoc_class_signature = "separated"
-if "READTHEDOCS" in os.environ:
- src_folder = pathlib.Path(__file__).resolve().parent.parent / "src"
- sys.path.append(str(src_folder))
-
- print("Detected running on ReadTheDocs")
- print(f"Added {src_folder} to sys.path")
- __import__("installer")
-
# -- Options for intersphinx
----------------------------------------------------------
#
https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/development/design.md
new/installer-0.6.0/docs/development/design.md
--- old/installer-0.5.1/docs/development/design.md 2021-07-29
01:44:40.750646800 +0200
+++ new/installer-0.6.0/docs/development/design.md 2022-03-13
08:38:01.853908500 +0100
@@ -3,7 +3,7 @@
## What this is for
This project is born out of [this discussion][1]. Effectively, the volunteers
-who maintain the Python Packaging toolchain identified a need for a library in
+who maintain the Python packaging toolchain identified a need for a library in
the ecology that handles the details of "wheel -> installed package". This is
that library.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/development/index.md
new/installer-0.6.0/docs/development/index.md
--- old/installer-0.5.1/docs/development/index.md 2021-07-29
01:44:40.750800400 +0200
+++ new/installer-0.6.0/docs/development/index.md 2022-03-13
08:38:01.854266000 +0100
@@ -3,8 +3,8 @@
Thank you for your interest in installer! â¨
installer is a volunteer maintained open source project, and we welcome
-contributions of all forms. This section of installer's documentation
-serves as a resource to help you to contribute to the project.
+contributions of all forms. This section of installer's documentation serves as
+a resource to help you to contribute to the project.
```{toctree}
:hidden:
@@ -13,6 +13,7 @@
design
```
+<!-- prettier-ignore-start -->
[Code of Conduct]
: Applies within all community spaces. If you are not familiar with our Code
of Conduct, take a minute to read it before starting with your first
contribution.
@@ -21,5 +22,6 @@
[Design and Scope](./design)
: Describes what this project is for, and how that informs the design
decisions made.
+<!-- prettier-ignore-end -->
[code of conduct]: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/docs/development/workflow.md
new/installer-0.6.0/docs/development/workflow.md
--- old/installer-0.5.1/docs/development/workflow.md 2021-10-13
20:48:27.358275700 +0200
+++ new/installer-0.6.0/docs/development/workflow.md 2022-03-13
08:38:01.854580900 +0100
@@ -1,13 +1,12 @@
# Workflow
-This page describes the tooling used during development of this
-project. It also serves as a reference for the various commands that
-you would use when working on this project.
+This page describes the tooling used during development of this project. It
also
+serves as a reference for the various commands that you would use when working
+on this project.
## Overview
-This project uses the [GitHub Flow] for collaboration. The codebase
-is Python.
+This project uses the [GitHub Flow] for collaboration. The codebase is Python.
- [flit] is used for automating development tasks.
- [nox] is used for automating development tasks.
@@ -17,8 +16,7 @@
## Repository Layout
-The repository layout is pretty standard for a modern pure-Python
-project.
+The repository layout is pretty standard for a modern pure-Python project.
- `CODE_OF_CONDUCT.md`
- `LICENSE`
@@ -67,15 +65,15 @@
nox -s test
```
-Run the tests against all supported Python versions, if an interpreter for
-that version is available locally.
+Run the tests against all supported Python versions, if an interpreter for that
+version is available locally.
```sh
nox -s test-3.9
```
-Run the tests against Python 3.9. It is also possible to specify other
-supported Python versions (like `3.7` or `pypy3`).
+Run the tests against Python 3.9. It is also possible to specify other
supported
+Python versions (like `3.7` or `pypy3`).
### Documentation
@@ -83,20 +81,20 @@
nox -s docs
```
-Generate the documentation for installer into the `build/docs` folder.
-This (mostly) does the same thing as `nox -s docs-live`, except it
-invokes `sphinx-build` instead of [sphinx-autobuild].
+Generate the documentation for installer into the `build/docs` folder. This
+(mostly) does the same thing as `nox -s docs-live`, except it invokes
+`sphinx-build` instead of [sphinx-autobuild].
```sh
nox -s docs-live
```
-Serve this project's documentation locally, using [sphinx-autobuild].
-This will open the generated documentation page in your browser.
+Serve this project's documentation locally, using [sphinx-autobuild]. This will
+open the generated documentation page in your browser.
-The server also watches for changes made to the documentation (`docs/`),
-which will trigger a rebuild. Once the build is completed, server will
-automagically reload any open pages using livereload.
+The server also watches for changes made to the documentation (`docs/`), which
+will trigger a rebuild. Once the build is completed, server will automagically
+reload any open pages using livereload.
## Release process
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/noxfile.py
new/installer-0.6.0/noxfile.py
--- old/installer-0.5.1/noxfile.py 2021-10-24 09:42:13.561079500 +0200
+++ new/installer-0.6.0/noxfile.py 2022-12-07 03:28:06.839124200 +0100
@@ -20,7 +20,7 @@
session.run("flit", "install", "--deps=production", *args, silent=True)
[email protected](python="3.8")
[email protected](python="3.11")
def lint(session):
session.install("pre-commit")
@@ -34,7 +34,7 @@
session.run("pre-commit", "run", "--all-files", *args)
[email protected](python=["3.7", "3.8", "3.9", "3.10", "pypy3"])
[email protected](python=["3.7", "3.8", "3.9", "3.10", "3.11", "pypy3"])
def test(session):
_install_this_project_with_flit(session, editable=True)
session.install("-r", "tests/requirements.txt")
@@ -54,7 +54,7 @@
)
[email protected](python=["3.7", "3.8", "3.9", "3.10", "pypy3"])
[email protected](python=["3.7", "3.8", "3.9", "3.10", "3.11", "pypy3"])
def doctest(session):
session.install(".")
session.install("-r", "docs/requirements.txt")
@@ -62,7 +62,7 @@
session.run("sphinx-build", "-b", "doctest", "docs/", "build/doctest")
[email protected](python="3.8", name="update-launchers")
[email protected](python="3.11", name="update-launchers")
def update_launchers(session):
session.install("httpx")
session.run("python", "tools/update_launchers.py")
@@ -71,7 +71,7 @@
#
# Documentation
#
[email protected](python="3.8")
[email protected](python="3.11")
def docs(session):
_install_this_project_with_flit(session)
session.install("-r", "docs/requirements.txt")
@@ -80,7 +80,7 @@
session.run("sphinx-build", "-W", "-b", "html", "docs/", "build/docs")
[email protected](name="docs-live", python="3.8")
[email protected](name="docs-live", python="3.11")
def docs_live(session):
_install_this_project_with_flit(session, editable=True)
session.install("-r", "docs/requirements.txt")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/setup.py new/installer-0.6.0/setup.py
--- old/installer-0.5.1/setup.py 1970-01-01 01:00:00.000000000 +0100
+++ new/installer-0.6.0/setup.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-# setup.py generated by flit for tools that don't yet use PEP 517
-
-from distutils.core import setup
-
-packages = \
-['installer', 'installer._scripts']
-
-package_data = \
-{'': ['*']}
-
-package_dir = \
-{'': 'src'}
-
-setup(name='installer',
- version='0.5.1',
- description='A library for installing Python wheels.',
- author=None,
- author_email='Pradyun Gedam <[email protected]>',
- url=None,
- packages=packages,
- package_data=package_data,
- package_dir=package_dir,
- python_requires='>=3.7',
- )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/src/installer/__init__.py
new/installer-0.6.0/src/installer/__init__.py
--- old/installer-0.5.1/src/installer/__init__.py 2022-03-11
09:50:21.574751100 +0100
+++ new/installer-0.6.0/src/installer/__init__.py 2022-12-07
03:30:07.284015000 +0100
@@ -1,6 +1,6 @@
"""A library for installing Python wheels."""
-__version__ = "0.5.1"
+__version__ = "0.6.0"
__all__ = ["install"]
from installer._core import install # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/src/installer/__main__.py
new/installer-0.6.0/src/installer/__main__.py
--- old/installer-0.5.1/src/installer/__main__.py 2022-03-11
09:08:15.070507300 +0100
+++ new/installer-0.6.0/src/installer/__main__.py 2022-12-07
03:28:06.839389000 +0100
@@ -24,6 +24,13 @@
help="destination directory (prefix to prepend to each file)",
)
parser.add_argument(
+ "--prefix",
+ "-p",
+ metavar="path",
+ type=str,
+ help="override prefix to install packages to",
+ )
+ parser.add_argument(
"--compile-bytecode",
action="append",
metavar="level",
@@ -39,12 +46,18 @@
return parser
-def _get_scheme_dict(distribution_name: str) -> Dict[str, str]:
+def _get_scheme_dict(
+ distribution_name: str, prefix: Optional[str] = None
+) -> Dict[str, str]:
"""Calculate the scheme dictionary for the current Python environment."""
- scheme_dict = sysconfig.get_paths()
+ vars = {}
+ if prefix is None:
+ installed_base = sysconfig.get_config_var("base")
+ assert installed_base
+ else:
+ vars["base"] = vars["platbase"] = installed_base = prefix
- installed_base = sysconfig.get_config_var("base")
- assert installed_base
+ scheme_dict = sysconfig.get_paths(vars=vars)
# calculate 'headers' path, not currently in sysconfig - see
# https://bugs.python.org/issue44445. This is based on what distutils does.
@@ -72,7 +85,7 @@
with WheelFile.open(args.wheel) as source:
destination = SchemeDictionaryDestination(
- scheme_dict=_get_scheme_dict(source.distribution),
+ scheme_dict=_get_scheme_dict(source.distribution,
prefix=args.prefix),
interpreter=sys.executable,
script_kind=get_launcher_kind(),
bytecode_optimization_levels=bytecode_levels,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/src/installer/_core.py
new/installer-0.6.0/src/installer/_core.py
--- old/installer-0.5.1/src/installer/_core.py 2022-02-16 20:24:54.873332700
+0100
+++ new/installer-0.6.0/src/installer/_core.py 2022-12-07 03:28:06.839731500
+0100
@@ -71,7 +71,7 @@
:param source: wheel to install.
:param destination: where to write the wheel.
:param additional_metadata: additional metadata files to generate, usually
- generated by the installer.
+ generated by the caller.
"""
root_scheme = _process_WHEEL_file(source)
@@ -123,7 +123,7 @@
scheme=root_scheme,
path=path,
stream=other_stream,
- is_executable=is_executable,
+ is_executable=False,
)
written_records.append((root_scheme, record))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/src/installer/records.py
new/installer-0.6.0/src/installer/records.py
--- old/installer-0.5.1/src/installer/records.py 2022-02-16
20:24:54.874736500 +0100
+++ new/installer-0.6.0/src/installer/records.py 2022-12-07
03:28:06.840245700 +0100
@@ -103,11 +103,11 @@
self.hash_ = hash_
self.size = size
- def to_line(self, path_prefix: Optional[str] = None) -> bytes:
- """Convert this into a line that can be written in a RECORD file.
+ def to_row(self, path_prefix: Optional[str] = None) -> Tuple[str, str,
str]:
+ """Convert this into a 3-element tuple that can be written in a RECORD
file.
:param path_prefix: A prefix to attach to the path -- must end in `/`
- :return: A binary-encoded line, that doesn't contain a newline
+ :return: a (path, hash, size) row
"""
if path_prefix is not None:
assert path_prefix.endswith("/")
@@ -119,13 +119,11 @@
if os.sep == "\\":
path = path.replace("\\", "/") # pragma: no cover
- entry = ",".join(
- [
- (str(elem) if elem is not None else "")
- for elem in [path, self.hash_, self.size]
- ]
+ return (
+ path,
+ str(self.hash_ or ""),
+ str(self.size) if self.size is not None else "",
)
- return entry.encode("utf-8")
def __repr__(self) -> str:
return "RecordEntry(path={!r}, hash_={!r}, size={!r})".format(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/src/installer/sources.py
new/installer-0.6.0/src/installer/sources.py
--- old/installer-0.5.1/src/installer/sources.py 2022-02-16
20:24:54.875755000 +0100
+++ new/installer-0.6.0/src/installer/sources.py 2022-03-24
09:42:55.220565300 +0100
@@ -7,8 +7,8 @@
from contextlib import contextmanager
from typing import BinaryIO, Iterator, List, Tuple, cast
-import installer.records
-import installer.utils
+from installer.records import parse_record_file
+from installer.utils import parse_wheel_filename
WheelContentElement = Tuple[Tuple[str, str, str], BinaryIO, bool]
@@ -109,7 +109,7 @@
assert f.filename
basename = os.path.basename(f.filename)
- parsed_name = installer.utils.parse_wheel_filename(basename)
+ parsed_name = parse_wheel_filename(basename)
super().__init__(
version=parsed_name.version,
distribution=parsed_name.distribution,
@@ -147,7 +147,7 @@
"""
# Convert the record file into a useful mapping
record_lines = self.read_dist_info("RECORD").splitlines()
- records = installer.records.parse_record_file(record_lines)
+ records = parse_record_file(record_lines)
record_mapping = {record[0]: record for record in records}
for item in self._zipfile.infolist():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/src/installer/utils.py
new/installer-0.6.0/src/installer/utils.py
--- old/installer-0.5.1/src/installer/utils.py 2022-02-16 20:24:54.876176000
+0100
+++ new/installer-0.6.0/src/installer/utils.py 2022-12-07 03:28:06.840684400
+0100
@@ -1,6 +1,8 @@
"""Utilities related to handling / interacting with wheel files."""
+import base64
import contextlib
+import csv
import hashlib
import io
import os
@@ -129,7 +131,7 @@
dest.write(buf)
size += len(buf)
- return hasher.hexdigest(), size
+ return
base64.urlsafe_b64encode(hasher.digest()).decode("ascii").rstrip("="), size
def get_launcher_kind() -> "LauncherKind": # pragma: no cover
@@ -192,11 +194,14 @@
:return: A stream that can be written to file. Must be closed by the
caller.
"""
- stream = io.BytesIO()
+ stream = io.TextIOWrapper(
+ io.BytesIO(), encoding="utf-8", write_through=True, newline=""
+ )
+ writer = csv.writer(stream, delimiter=",", quotechar='"',
lineterminator="\n")
for scheme, record in records:
- stream.write(record.to_line(prefix_for_scheme(scheme)) + b"\n")
+ writer.writerow(record.to_row(prefix_for_scheme(scheme)))
stream.seek(0)
- return stream
+ return stream.detach()
def parse_entrypoints(text: str) -> Iterable[Tuple[str, str, str,
"ScriptSection"]]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/tests/test_core.py
new/installer-0.6.0/tests/test_core.py
--- old/installer-0.5.1/tests/test_core.py 2022-02-16 20:24:54.876905000
+0100
+++ new/installer-0.6.0/tests/test_core.py 2022-12-07 03:28:06.841139300
+0100
@@ -25,7 +25,6 @@
# A hacky approach to making sure we got the right objects going in.
def custom_write_file(scheme, path, stream, is_executable):
assert isinstance(stream, BytesIO)
- assert is_executable is False
return (path, scheme, 0)
def custom_write_script(name, module, attr, section):
@@ -834,3 +833,73 @@
)
assert "fancy-1.0.0.data/invalid/fancy/invalid.py" in str(ctx.value)
+
+ def test_ensure_non_executable_for_additional_metadata(self,
mock_destination):
+ # Create a fake wheel
+ source = FakeWheelSource(
+ distribution="fancy",
+ version="1.0.0",
+ regular_files={
+ "fancy/__init__.py": b"""\
+ # put me in purelib
+ """,
+ },
+ dist_info_files={
+ "top_level.txt": b"""\
+ fancy
+ """,
+ "WHEEL": b"""\
+ Wheel-Version: 1.0
+ Generator: magic (1.0.0)
+ Root-Is-Purelib: true
+ Tag: py3-none-any
+ """,
+ "METADATA": b"""\
+ Metadata-Version: 2.1
+ Name: fancy
+ Version: 1.0.0
+ Summary: A fancy package
+ Author: Agendaless Consulting
+ Author-email: [email protected]
+ License: MIT
+ Keywords: fancy amazing
+ Platform: UNKNOWN
+ Classifier: Intended Audience :: Developers
+ """,
+ },
+ )
+ all_contents = list(source.get_contents())
+ source.get_contents = lambda: (
+ (*contents, True) for (*contents, _) in all_contents
+ )
+ install(
+ source=source,
+ destination=mock_destination,
+ additional_metadata={
+ "fun_file.txt": b"this should be in dist-info!",
+ },
+ )
+
+ mock_destination.assert_has_calls(
+ [
+ mock.call.write_file(
+ scheme="purelib",
+ path="fancy/__init__.py",
+ stream=mock.ANY,
+ is_executable=True,
+ ),
+ mock.call.write_file(
+ scheme="purelib",
+ path="fancy-1.0.0.dist-info/METADATA",
+ stream=mock.ANY,
+ is_executable=True,
+ ),
+ mock.call.write_file(
+ scheme="purelib",
+ path="fancy-1.0.0.dist-info/fun_file.txt",
+ stream=mock.ANY,
+ is_executable=False,
+ ),
+ ],
+ any_order=True,
+ )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/tests/test_destinations.py
new/installer-0.6.0/tests/test_destinations.py
--- old/installer-0.5.1/tests/test_destinations.py 2022-02-16
20:24:54.877523400 +0100
+++ new/installer-0.6.0/tests/test_destinations.py 2022-12-07
03:28:06.841588700 +0100
@@ -124,7 +124,7 @@
"data",
destination.write_file(
"data",
- "my_data3.bin",
+ "my_data3,my_data4.bin",
io.BytesIO(b"my data 3"),
is_executable=False,
),
@@ -163,11 +163,11 @@
data = f.read()
assert data == (
-
b"../data/my_data1.bin,sha256=355d00f8ce0e3eea93b078de0fa5ad87ff94aaba40000772a6572eb2d159f2ce,9\n"
-
b"../data/my_data2.bin,sha256=94fed5f2858baa0c9709b74048d88f76c5288333d466186dffb17c4f96c2dde4,9\n"
-
b"../data/my_data3.bin,sha256=d7c92baeebb582bd35c7e58cffd0a14804a81efd267d1015ebe0766ddf6cc69a,9\n"
-
b"../scripts/my_script,sha256=33ad1f5af51230990fb70d9aa54be3596c0e72744f715cbfccee3ee25a47d3ca,9\n"
-
b"../scripts/my_script2,sha256=93dffdf7b9136d36109bb11714b7255592f59b637df2b53dd105f8e9778cbe36,22\n"
-
b"../scripts/my_entrypoint,sha256=fe9ffd9f099e21ea0c05f4346a486bd4a6ca9f795a0f2760d09edccb416ce892,216\n"
+
b"../data/my_data1.bin,sha256=NV0A-M4OPuqTsHjeD6Wth_-UqrpAAAdyplcustFZ8s4,9\n"
+
b"../data/my_data2.bin,sha256=lP7V8oWLqgyXCbdASNiPdsUogzPUZhht_7F8T5bC3eQ,9\n"
+
b'"../data/my_data3,my_data4.bin",sha256=18krruu1gr01x-WM_9ChSASoHv0mfRAV6-B2bd9sxpo,9\n'
+
b"../scripts/my_script,sha256=M60fWvUSMJkPtw2apUvjWWwOcnRPcVy_zO4-4lpH08o,9\n"
+
b"../scripts/my_script2,sha256=k9_997kTbTYQm7EXFLclVZL1m2N98rU90QX46XeMvjY,22\n"
+
b"../scripts/my_entrypoint,sha256=_p_9nwmeIeoMBfQ0akhr1KbKn3laDydg0J7cy0Fs6JI,216\n"
b"RECORD,,\n"
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/tests/test_main.py
new/installer-0.6.0/tests/test_main.py
--- old/installer-0.5.1/tests/test_main.py 2022-02-17 02:45:44.163254000
+0100
+++ new/installer-0.6.0/tests/test_main.py 2022-12-07 03:28:06.842462000
+0100
@@ -1,3 +1,5 @@
+import os
+
from installer.__main__ import _get_scheme_dict as get_scheme_dict
from installer.__main__ import _main as main
@@ -7,6 +9,14 @@
assert set(d.keys()) >= {"purelib", "platlib", "headers", "scripts",
"data"}
+def test_get_scheme_dict_prefix():
+ d = get_scheme_dict(distribution_name="foo", prefix="/foo")
+ for key in ("purelib", "platlib", "headers", "scripts", "data"):
+ assert d[key].startswith(
+ f"{os.sep}foo"
+ ), f"{key} does not start with /foo: {d[key]}"
+
+
def test_main(fancy_wheel, tmp_path):
destdir = tmp_path / "dest"
@@ -17,6 +27,26 @@
assert {f.stem for f in installed_py_files} == {"__init__", "__main__",
"data"}
installed_pyc_files = destdir.rglob("*.pyc")
+ assert {f.name.split(".")[0] for f in installed_pyc_files} == {
+ "__init__",
+ "__main__",
+ }
+
+
+def test_main_prefix(fancy_wheel, tmp_path):
+ destdir = tmp_path / "dest"
+
+ main([str(fancy_wheel), "-d", str(destdir), "-p", "/foo"], "python -m
installer")
+
+ installed_py_files = list(destdir.rglob("*.py"))
+
+ for f in installed_py_files:
+ assert str(f.parent).startswith(
+ str(destdir / "foo")
+ ), f"path does not respect destdir+prefix: {f}"
+ assert {f.stem for f in installed_py_files} == {"__init__", "__main__",
"data"}
+
+ installed_pyc_files = destdir.rglob("*.pyc")
assert {f.name.split(".")[0] for f in installed_pyc_files} == {
"__init__",
"__main__",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/tests/test_records.py
new/installer-0.6.0/tests/test_records.py
--- old/installer-0.5.1/tests/test_records.py 2021-10-24 09:42:13.565047700
+0200
+++ new/installer-0.6.0/tests/test_records.py 2022-12-07 03:28:06.842787300
+0100
@@ -136,10 +136,10 @@
def test_string_representation(self, scheme, elements, data,
passes_validation):
record = RecordEntry.from_elements(*elements)
- expected_string_value = ",".join(
+ expected_row = tuple(
[(str(elem) if elem is not None else "") for elem in elements]
)
- assert record.to_line() == expected_string_value.encode()
+ assert record.to_row() == expected_row
@pytest.mark.parametrize(
("scheme", "elements", "data", "passes_validation"), SAMPLE_RECORDS
@@ -149,10 +149,13 @@
):
record = RecordEntry.from_elements(*elements)
- expected_string_value = "prefix/" + ",".join(
- [(str(elem) if elem is not None else "") for elem in elements]
+ expected_row = tuple(
+ [
+ (str(elem) if elem is not None else "")
+ for elem in ("prefix/" + elements[0], elements[1], elements[2])
+ ]
)
- assert record.to_line("prefix/") == expected_string_value.encode()
+ assert record.to_row("prefix/") == expected_row
def test_equality(self):
record = RecordEntry.from_elements(
@@ -255,3 +258,18 @@
list(parse_record_file(record_lines))
assert "Row Index 3" in str(exc_info.value)
+
+ def test_parse_record_entry_with_comma(self):
+ record_lines = [
+
'"file1,file2.txt",sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144',
+ "distribution-1.0.dist-info/RECORD,,",
+ ]
+ records = list(parse_record_file(record_lines))
+ assert records == [
+ (
+ "file1,file2.txt",
+ "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI",
+ "3144",
+ ),
+ ("distribution-1.0.dist-info/RECORD", "", ""),
+ ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/installer-0.5.1/tests/test_utils.py
new/installer-0.6.0/tests/test_utils.py
--- old/installer-0.5.1/tests/test_utils.py 2021-10-24 09:42:13.566290900
+0200
+++ new/installer-0.6.0/tests/test_utils.py 2022-12-07 03:28:06.843163700
+0100
@@ -1,6 +1,7 @@
"""Tests for installer.utils
"""
+import base64
import hashlib
import textwrap
from email.message import Message
@@ -96,7 +97,11 @@
class TestCopyFileObjWithHashing:
def test_basic_functionality(self):
data = b"input data is this"
- hash_ = hashlib.sha256(data).hexdigest()
+ hash_ = (
+ base64.urlsafe_b64encode(hashlib.sha256(data).digest())
+ .decode("ascii")
+ .rstrip("=")
+ )
size = len(data)
with BytesIO(data) as source: