Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-compileall2 for openSUSE:Factory checked in at 2024-04-07 22:11:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-compileall2 (Old) and /work/SRC/openSUSE:Factory/.python-compileall2.new.1905 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-compileall2" Sun Apr 7 22:11:43 2024 rev:4 rq:1165871 version:0.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-compileall2/python-compileall2.changes 2023-01-08 21:25:27.895220517 +0100 +++ /work/SRC/openSUSE:Factory/.python-compileall2.new.1905/python-compileall2.changes 2024-04-07 22:13:59.940166971 +0200 @@ -1,0 +2,12 @@ +Sat Apr 6 19:18:36 UTC 2024 - Dirk Müller <dmuel...@suse.com> + +- update to 0.8.0: + * bpo-36786: Run compileall in parallel during "make install" + * bpo-40692: Run more test_concurrent_futures tests (GH-20239) + * gh-105931: Fix surprising compileall stripdir behaviour + (GH-108671) + * GH-84559: Deprecate fork being the multiprocessing default. + * bpo-40447: accept all path-like objects in + * Fix missing space with help for -m compileall -o + +------------------------------------------------------------------- Old: ---- LICENSE compileall2-0.7.2.tar.gz New: ---- compileall2-0.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-compileall2.spec ++++++ --- /var/tmp/diff_new_pack.NNpWLb/_old 2024-04-07 22:14:00.392183548 +0200 +++ /var/tmp/diff_new_pack.NNpWLb/_new 2024-04-07 22:14:00.392183548 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-compileall2 # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,16 +16,14 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} -%define skip_python2 1 +%{?sle15_python_module_pythons} Name: python-compileall2 -Version: 0.7.2 +Version: 0.8.0 Release: 0 Summary: Enhanced Python `compileall` module License: Python-2.0 URL: https://github.com/fedora-python/compileall2 Source: https://files.pythonhosted.org/packages/source/c/compileall2/compileall2-%{version}.tar.gz -Source1: https://raw.githubusercontent.com/fedora-python/compileall2/master/LICENSE Source2: https://raw.githubusercontent.com/fedora-python/compileall2/master/test_compileall2.py BuildRequires: %{python_module pip} BuildRequires: %{python_module pytest} @@ -41,7 +39,7 @@ %prep %setup -q -n compileall2-%{version} -cp %{SOURCE1} %{SOURCE2} . +cp -p %{SOURCE2} . %build export LANG=en_US.UTF-8 ++++++ compileall2-0.7.2.tar.gz -> compileall2-0.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/PKG-INFO new/compileall2-0.8.0/PKG-INFO --- old/compileall2-0.7.2/PKG-INFO 2020-12-08 13:57:16.249812100 +0100 +++ new/compileall2-0.8.0/PKG-INFO 2024-03-21 16:55:01.669314400 +0100 @@ -1,183 +1,110 @@ Metadata-Version: 2.1 Name: compileall2 -Version: 0.7.2 +Version: 0.8.0 Summary: Enhanced Python `compileall` module Home-page: https://github.com/fedora-python/compileall2 Author: LumÃr Balhar Author-email: frenzy.madn...@gmail.com License: PSFv2 -Description: # compileall2 Python module - - Copy of `compileall` module from CPython source code with some new features, namely: - - * compatibility with Python >= 3.4 & PyPy 3 - - * default recursion limit is now "unlimited" (actually limited by `sys.getrecursionlimit()`) - - * `-s` and `-p` command line options for manipulation of the path baked into - a compiled `*.pyc` file. - - * the `-o` command line option can be specified multiple times to compile for - multiple optimization levels in one run - - * the `-e` command line option for ignoring symlinks pointing outside a specific directory - - * the `--hardlink-dupes` command line option which creates hardlinks between - `.pyc` files with the same content - - ## Installation - - * From [PyPI](https://pypi.org/project/compileall2/) via `pip install compileall2` - - * RPMs will be available in [Fedora COPR](https://copr.fedorainfracloud.org/coprs/lbalhar/compileall2/) - - ## Usage - - `compileall2` can be executed as a Python module or directly. - - Example usage: - - ```shell - # Create some script (this one raises an exception to show tracebacks) - $ echo "1 / 0" > test.py - - # Compile it - $ compileall2 test.py - Compiling 'test.py'... - - # Try to execute compiled version directly - $ python __pycache__/test.cpython-37.pyc - Traceback (most recent call last): - File "test.py", line 1, in <module> - 1 / 0 - ZeroDivisionError: division by zero - - # Recompile it with changes path which will be visible in error message - $ compileall2 -f -p /foo/bar test.py - Compiling 'test.py'... - $ python __pycache__/test.cpython-37.pyc - Traceback (most recent call last): - File "/foo/bar/test.py", line 1, in <module> - ZeroDivisionError: division by zero - - # Same thing as above but executed as a Python module - $ python -m compileall2 -f -p /bar/baz test.py - Compiling 'test.py'... - $ python __pycache__/test.cpython-37.pyc - Traceback (most recent call last): - File "/bar/baz/test.py", line 1, in <module> - ZeroDivisionError: division by zero - ``` - - ## Done - - * â Start project :) - - * â Make upstream tests running - - * Make `compileall2` compatible with CPythons: - - * 3.8 â - * 3.7 â - * 3.6 â - * 3.5 â - * 3.4 â - - * â Make `compileall2` compatible with PyPy 3 - - * â Remove maximum depth limit as described above - - * â Add possibility to strip some part of a path to an original file from compiled one - - * â Publish it to PyPI - - * â Make it available in Fedora COPR - - * â Test it with Python packages in COPR - - * Push it to Fedora rawhide - - * â %py_byte_compile RPM macro uses `compileall2` (done in [python-rpm-macros](https://src.fedoraproject.org/rpms/python-rpm-macros/pull-request/25)) - * â switch brp-python-bytecompile RPM script to `compileall2` (done in [redhat-rpm-config](https://src.fedoraproject.org/rpms/redhat-rpm-config/pull-request/64#)) - - * â Test it in Fedora infrastructure with all Python packages (done in the mass rebuild for Fedora 31) - - * â Prepare patches for upstream CPython - * [Pull request](https://github.com/python/cpython/pull/16012) merged and will be part of Python 3.9 - - * â Changes from upstream CPython backported back - - * â Implemented important features for Fedora RPM build system - - ## Testing - - You can test it locally with tox or unittest directly: - - ```shell - $ python3 -m unittest test_compileall2.py - ..............sss....ss.......................sss....ss.....................ss.............................---------------------------------------------------------------------- - Ran 107 tests in 3.714s - - OK (skipped=12) - ``` - - but running in a Docker container might be better because the superuser has privileges to write to `sys.path` which lowers the number of skipped tests. - - You can just build the prepared one: - - ```shell - $ docker build -t compileall2 . - Sending build context to Docker daemon 177.2 kB - Step 1/3 : FROM frenzymadness/fedora-python-tox:latest - ---> 00f92ad0e1d3 - ... etc ... - ``` - - and run tests in it: - - ```shell - $ docker run --rm -it -e TOXENV=py37 -v $PWD:/src:Z -w /src compileall2 - py37 installed: atomicwrites==1.3.0,attrs==19.3.0,compileall2==0.5.0,coverage==4.5.4,importlib-metadata==0.23,more-itertools==7.2.0,packaging==19.2,pluggy==0.13.0,py==1.8.0,pyparsing==2.4.5,pytest==5.2.3,six==1.13.0,wcwidth==0.1.7,zipp==0.6.0 - py37 run-test-pre: PYTHONHASHSEED='1615314833' - py37 runtests: commands[0] | coverage run --append -m py.test - ==================================== test session starts ===================================== - platform linux -- Python 3.7.5, pytest-5.2.3, py-1.8.0, pluggy-0.13.0 - cachedir: .tox/py37/.pytest_cache - rootdir: /src - collected 107 items - test_compileall2.py ............ss..................................................ss [ 61%] - ..............................ss......... [100%] - - =============================== 101 passed, 6 skipped in 7.40s =============================== - py37 runtests: commands[1] | coverage report -i '--omit=.tox/*' - Name Stmts Miss Cover - ----------------------------------------- - compileall2.py 232 48 79% - test_compileall2.py 621 8 99% - ----------------------------------------- - TOTAL 853 56 93% - __________________________________________ summary ___________________________________________ - py37: commands succeeded - congratulations :) - ``` - - ## License - - [PSF license v2](LICENSE) - -Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: Operating System :: POSIX :: Linux Classifier: Topic :: Software Development :: Compilers Description-Content-Type: text/markdown +License-File: LICENSE + +# compileall2 Python module + +Copy of `compileall` module from CPython source code with some new features, namely: + +* compatibility with Python >= 3.6 & PyPy 3 + +The following features were first implemented in this project and then included +into the standard libraty of CPython. + +* default recursion limit is now "unlimited" (actually limited by `sys.getrecursionlimit()`) + +* `-s` and `-p` command line options for manipulation of the path baked into + a compiled `*.pyc` file. + +* the `-o` command line option can be specified multiple times to compile for + multiple optimization levels in one run + +* the `-e` command line option for ignoring symlinks pointing outside a specific directory + +* the `--hardlink-dupes` command line option which creates hardlinks between + `.pyc` files with the same content + +## Installation + +* From [PyPI](https://pypi.org/project/compileall2/) via `pip install compileall2` + +* In Fedora Linux, compileall2.py is a part of python-srpm-macros RPM package. + +## Usage + +`compileall2` can be executed as a Python module or directly. + +Example usage: + +```shell +# Create some script (this one raises an exception to show tracebacks) +$ echo "1 / 0" > test.py + +# Compile it +$ compileall2 test.py +Compiling 'test.py'... + +# Try to execute compiled version directly +$ python __pycache__/test.cpython-37.pyc +Traceback (most recent call last): + File "test.py", line 1, in <module> + 1 / 0 +ZeroDivisionError: division by zero + +# Recompile it with changes path which will be visible in error message +$ compileall2 -f -p /foo/bar test.py +Compiling 'test.py'... +$ python __pycache__/test.cpython-37.pyc +Traceback (most recent call last): + File "/foo/bar/test.py", line 1, in <module> +ZeroDivisionError: division by zero + +# Same thing as above but executed as a Python module +$ python -m compileall2 -f -p /bar/baz test.py +Compiling 'test.py'... +$ python __pycache__/test.cpython-37.pyc +Traceback (most recent call last): + File "/bar/baz/test.py", line 1, in <module> +ZeroDivisionError: division by zero +``` + +## Testing + +You can test it locally with tox or unittest directly: + +```shell +$ python3 -m unittest test_compileall2.py +..............sss....ss.......................sss....ss.....................ss.............................---------------------------------------------------------------------- +Ran 107 tests in 3.714s + +OK (skipped=12) +``` + +but running in a container might be better because the superuser has privileges to write to `sys.path` which lowers the number of skipped tests. + +## License + +[PSF license v2](LICENSE) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/README.md new/compileall2-0.8.0/README.md --- old/compileall2-0.7.2/README.md 2020-12-08 10:41:18.000000000 +0100 +++ new/compileall2-0.8.0/README.md 2024-03-21 16:51:21.000000000 +0100 @@ -2,7 +2,10 @@ Copy of `compileall` module from CPython source code with some new features, namely: -* compatibility with Python >= 3.4 & PyPy 3 +* compatibility with Python >= 3.6 & PyPy 3 + +The following features were first implemented in this project and then included +into the standard libraty of CPython. * default recursion limit is now "unlimited" (actually limited by `sys.getrecursionlimit()`) @@ -21,7 +24,7 @@ * From [PyPI](https://pypi.org/project/compileall2/) via `pip install compileall2` -* RPMs will be available in [Fedora COPR](https://copr.fedorainfracloud.org/coprs/lbalhar/compileall2/) +* In Fedora Linux, compileall2.py is a part of python-srpm-macros RPM package. ## Usage @@ -61,46 +64,6 @@ ZeroDivisionError: division by zero ``` -## Done - -* â Start project :) - -* â Make upstream tests running - -* Make `compileall2` compatible with CPythons: - - * 3.8 â - * 3.7 â - * 3.6 â - * 3.5 â - * 3.4 â - -* â Make `compileall2` compatible with PyPy 3 - -* â Remove maximum depth limit as described above - -* â Add possibility to strip some part of a path to an original file from compiled one - -* â Publish it to PyPI - -* â Make it available in Fedora COPR - -* â Test it with Python packages in COPR - -* Push it to Fedora rawhide - - * â %py_byte_compile RPM macro uses `compileall2` (done in [python-rpm-macros](https://src.fedoraproject.org/rpms/python-rpm-macros/pull-request/25)) - * â switch brp-python-bytecompile RPM script to `compileall2` (done in [redhat-rpm-config](https://src.fedoraproject.org/rpms/redhat-rpm-config/pull-request/64#)) - -* â Test it in Fedora infrastructure with all Python packages (done in the mass rebuild for Fedora 31) - -* â Prepare patches for upstream CPython - * [Pull request](https://github.com/python/cpython/pull/16012) merged and will be part of Python 3.9 - -* â Changes from upstream CPython backported back - -* â Implemented important features for Fedora RPM build system - ## Testing You can test it locally with tox or unittest directly: @@ -113,45 +76,7 @@ OK (skipped=12) ``` -but running in a Docker container might be better because the superuser has privileges to write to `sys.path` which lowers the number of skipped tests. - -You can just build the prepared one: - -```shell -$ docker build -t compileall2 . -Sending build context to Docker daemon 177.2 kB -Step 1/3 : FROM frenzymadness/fedora-python-tox:latest - ---> 00f92ad0e1d3 -... etc ... -``` - -and run tests in it: - -```shell -$ docker run --rm -it -e TOXENV=py37 -v $PWD:/src:Z -w /src compileall2 -py37 installed: atomicwrites==1.3.0,attrs==19.3.0,compileall2==0.5.0,coverage==4.5.4,importlib-metadata==0.23,more-itertools==7.2.0,packaging==19.2,pluggy==0.13.0,py==1.8.0,pyparsing==2.4.5,pytest==5.2.3,six==1.13.0,wcwidth==0.1.7,zipp==0.6.0 -py37 run-test-pre: PYTHONHASHSEED='1615314833' -py37 runtests: commands[0] | coverage run --append -m py.test -==================================== test session starts ===================================== -platform linux -- Python 3.7.5, pytest-5.2.3, py-1.8.0, pluggy-0.13.0 -cachedir: .tox/py37/.pytest_cache -rootdir: /src -collected 107 items -test_compileall2.py ............ss..................................................ss [ 61%] -..............................ss......... [100%] - -=============================== 101 passed, 6 skipped in 7.40s =============================== -py37 runtests: commands[1] | coverage report -i '--omit=.tox/*' -Name Stmts Miss Cover ------------------------------------------ -compileall2.py 232 48 79% -test_compileall2.py 621 8 99% ------------------------------------------ -TOTAL 853 56 93% -__________________________________________ summary ___________________________________________ - py37: commands succeeded - congratulations :) -``` +but running in a container might be better because the superuser has privileges to write to `sys.path` which lowers the number of skipped tests. ## License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/compileall2.egg-info/PKG-INFO new/compileall2-0.8.0/compileall2.egg-info/PKG-INFO --- old/compileall2-0.7.2/compileall2.egg-info/PKG-INFO 2020-12-08 13:57:16.000000000 +0100 +++ new/compileall2-0.8.0/compileall2.egg-info/PKG-INFO 2024-03-21 16:55:01.000000000 +0100 @@ -1,183 +1,110 @@ Metadata-Version: 2.1 Name: compileall2 -Version: 0.7.2 +Version: 0.8.0 Summary: Enhanced Python `compileall` module Home-page: https://github.com/fedora-python/compileall2 Author: LumÃr Balhar Author-email: frenzy.madn...@gmail.com License: PSFv2 -Description: # compileall2 Python module - - Copy of `compileall` module from CPython source code with some new features, namely: - - * compatibility with Python >= 3.4 & PyPy 3 - - * default recursion limit is now "unlimited" (actually limited by `sys.getrecursionlimit()`) - - * `-s` and `-p` command line options for manipulation of the path baked into - a compiled `*.pyc` file. - - * the `-o` command line option can be specified multiple times to compile for - multiple optimization levels in one run - - * the `-e` command line option for ignoring symlinks pointing outside a specific directory - - * the `--hardlink-dupes` command line option which creates hardlinks between - `.pyc` files with the same content - - ## Installation - - * From [PyPI](https://pypi.org/project/compileall2/) via `pip install compileall2` - - * RPMs will be available in [Fedora COPR](https://copr.fedorainfracloud.org/coprs/lbalhar/compileall2/) - - ## Usage - - `compileall2` can be executed as a Python module or directly. - - Example usage: - - ```shell - # Create some script (this one raises an exception to show tracebacks) - $ echo "1 / 0" > test.py - - # Compile it - $ compileall2 test.py - Compiling 'test.py'... - - # Try to execute compiled version directly - $ python __pycache__/test.cpython-37.pyc - Traceback (most recent call last): - File "test.py", line 1, in <module> - 1 / 0 - ZeroDivisionError: division by zero - - # Recompile it with changes path which will be visible in error message - $ compileall2 -f -p /foo/bar test.py - Compiling 'test.py'... - $ python __pycache__/test.cpython-37.pyc - Traceback (most recent call last): - File "/foo/bar/test.py", line 1, in <module> - ZeroDivisionError: division by zero - - # Same thing as above but executed as a Python module - $ python -m compileall2 -f -p /bar/baz test.py - Compiling 'test.py'... - $ python __pycache__/test.cpython-37.pyc - Traceback (most recent call last): - File "/bar/baz/test.py", line 1, in <module> - ZeroDivisionError: division by zero - ``` - - ## Done - - * â Start project :) - - * â Make upstream tests running - - * Make `compileall2` compatible with CPythons: - - * 3.8 â - * 3.7 â - * 3.6 â - * 3.5 â - * 3.4 â - - * â Make `compileall2` compatible with PyPy 3 - - * â Remove maximum depth limit as described above - - * â Add possibility to strip some part of a path to an original file from compiled one - - * â Publish it to PyPI - - * â Make it available in Fedora COPR - - * â Test it with Python packages in COPR - - * Push it to Fedora rawhide - - * â %py_byte_compile RPM macro uses `compileall2` (done in [python-rpm-macros](https://src.fedoraproject.org/rpms/python-rpm-macros/pull-request/25)) - * â switch brp-python-bytecompile RPM script to `compileall2` (done in [redhat-rpm-config](https://src.fedoraproject.org/rpms/redhat-rpm-config/pull-request/64#)) - - * â Test it in Fedora infrastructure with all Python packages (done in the mass rebuild for Fedora 31) - - * â Prepare patches for upstream CPython - * [Pull request](https://github.com/python/cpython/pull/16012) merged and will be part of Python 3.9 - - * â Changes from upstream CPython backported back - - * â Implemented important features for Fedora RPM build system - - ## Testing - - You can test it locally with tox or unittest directly: - - ```shell - $ python3 -m unittest test_compileall2.py - ..............sss....ss.......................sss....ss.....................ss.............................---------------------------------------------------------------------- - Ran 107 tests in 3.714s - - OK (skipped=12) - ``` - - but running in a Docker container might be better because the superuser has privileges to write to `sys.path` which lowers the number of skipped tests. - - You can just build the prepared one: - - ```shell - $ docker build -t compileall2 . - Sending build context to Docker daemon 177.2 kB - Step 1/3 : FROM frenzymadness/fedora-python-tox:latest - ---> 00f92ad0e1d3 - ... etc ... - ``` - - and run tests in it: - - ```shell - $ docker run --rm -it -e TOXENV=py37 -v $PWD:/src:Z -w /src compileall2 - py37 installed: atomicwrites==1.3.0,attrs==19.3.0,compileall2==0.5.0,coverage==4.5.4,importlib-metadata==0.23,more-itertools==7.2.0,packaging==19.2,pluggy==0.13.0,py==1.8.0,pyparsing==2.4.5,pytest==5.2.3,six==1.13.0,wcwidth==0.1.7,zipp==0.6.0 - py37 run-test-pre: PYTHONHASHSEED='1615314833' - py37 runtests: commands[0] | coverage run --append -m py.test - ==================================== test session starts ===================================== - platform linux -- Python 3.7.5, pytest-5.2.3, py-1.8.0, pluggy-0.13.0 - cachedir: .tox/py37/.pytest_cache - rootdir: /src - collected 107 items - test_compileall2.py ............ss..................................................ss [ 61%] - ..............................ss......... [100%] - - =============================== 101 passed, 6 skipped in 7.40s =============================== - py37 runtests: commands[1] | coverage report -i '--omit=.tox/*' - Name Stmts Miss Cover - ----------------------------------------- - compileall2.py 232 48 79% - test_compileall2.py 621 8 99% - ----------------------------------------- - TOTAL 853 56 93% - __________________________________________ summary ___________________________________________ - py37: commands succeeded - congratulations :) - ``` - - ## License - - [PSF license v2](LICENSE) - -Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: Operating System :: POSIX :: Linux Classifier: Topic :: Software Development :: Compilers Description-Content-Type: text/markdown +License-File: LICENSE + +# compileall2 Python module + +Copy of `compileall` module from CPython source code with some new features, namely: + +* compatibility with Python >= 3.6 & PyPy 3 + +The following features were first implemented in this project and then included +into the standard libraty of CPython. + +* default recursion limit is now "unlimited" (actually limited by `sys.getrecursionlimit()`) + +* `-s` and `-p` command line options for manipulation of the path baked into + a compiled `*.pyc` file. + +* the `-o` command line option can be specified multiple times to compile for + multiple optimization levels in one run + +* the `-e` command line option for ignoring symlinks pointing outside a specific directory + +* the `--hardlink-dupes` command line option which creates hardlinks between + `.pyc` files with the same content + +## Installation + +* From [PyPI](https://pypi.org/project/compileall2/) via `pip install compileall2` + +* In Fedora Linux, compileall2.py is a part of python-srpm-macros RPM package. + +## Usage + +`compileall2` can be executed as a Python module or directly. + +Example usage: + +```shell +# Create some script (this one raises an exception to show tracebacks) +$ echo "1 / 0" > test.py + +# Compile it +$ compileall2 test.py +Compiling 'test.py'... + +# Try to execute compiled version directly +$ python __pycache__/test.cpython-37.pyc +Traceback (most recent call last): + File "test.py", line 1, in <module> + 1 / 0 +ZeroDivisionError: division by zero + +# Recompile it with changes path which will be visible in error message +$ compileall2 -f -p /foo/bar test.py +Compiling 'test.py'... +$ python __pycache__/test.cpython-37.pyc +Traceback (most recent call last): + File "/foo/bar/test.py", line 1, in <module> +ZeroDivisionError: division by zero + +# Same thing as above but executed as a Python module +$ python -m compileall2 -f -p /bar/baz test.py +Compiling 'test.py'... +$ python __pycache__/test.cpython-37.pyc +Traceback (most recent call last): + File "/bar/baz/test.py", line 1, in <module> +ZeroDivisionError: division by zero +``` + +## Testing + +You can test it locally with tox or unittest directly: + +```shell +$ python3 -m unittest test_compileall2.py +..............sss....ss.......................sss....ss.....................ss.............................---------------------------------------------------------------------- +Ran 107 tests in 3.714s + +OK (skipped=12) +``` + +but running in a container might be better because the superuser has privileges to write to `sys.path` which lowers the number of skipped tests. + +## License + +[PSF license v2](LICENSE) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/compileall2.egg-info/SOURCES.txt new/compileall2-0.8.0/compileall2.egg-info/SOURCES.txt --- old/compileall2-0.7.2/compileall2.egg-info/SOURCES.txt 2020-12-08 13:57:16.000000000 +0100 +++ new/compileall2-0.8.0/compileall2.egg-info/SOURCES.txt 2024-03-21 16:55:01.000000000 +0100 @@ -7,5 +7,4 @@ compileall2.egg-info/SOURCES.txt compileall2.egg-info/dependency_links.txt compileall2.egg-info/entry_points.txt -compileall2.egg-info/top_level.txt -test/test.py \ No newline at end of file +compileall2.egg-info/top_level.txt \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/compileall2.egg-info/entry_points.txt new/compileall2-0.8.0/compileall2.egg-info/entry_points.txt --- old/compileall2-0.7.2/compileall2.egg-info/entry_points.txt 2020-12-08 13:57:16.000000000 +0100 +++ new/compileall2-0.8.0/compileall2.egg-info/entry_points.txt 2024-03-21 16:55:01.000000000 +0100 @@ -1,3 +1,2 @@ [console_scripts] compileall2 = compileall2:main - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/compileall2.py new/compileall2-0.8.0/compileall2.py --- old/compileall2-0.7.2/compileall2.py 2020-03-03 15:04:04.000000000 +0100 +++ new/compileall2-0.8.0/compileall2.py 2024-03-21 16:51:21.000000000 +0100 @@ -4,7 +4,7 @@ given as arguments recursively; the -l option prevents it from recursing into directories. -Without arguments, if compiles all modules on sys.path, without +Without arguments, it compiles all modules on sys.path, without recursing into subdirectories. (Even though it should do so for packages -- for now, you'll have to deal with packages separately.) @@ -36,11 +36,11 @@ # introduced in Python 3.7. These cases are covered by variables here or by PY37 # variable itself. if PY37: - pyc_struct_format = '<4sll' + pyc_struct_format = '<4sLL' pyc_header_lenght = 12 pyc_header_format = (pyc_struct_format, importlib.util.MAGIC_NUMBER, 0) else: - pyc_struct_format = '<4sl' + pyc_struct_format = '<4sL' pyc_header_lenght = 8 pyc_header_format = (pyc_struct_format, importlib.util.MAGIC_NUMBER) @@ -106,7 +106,7 @@ workers: maximum number of parallel workers invalidation_mode: how the up-to-dateness of the pyc will be checked stripdir: part of path to left-strip from source file path - prependdir: path to prepend to beggining of original file path, applied + prependdir: path to prepend to beginning of original file path, applied after stripdir limit_sl_dest: ignore symlinks if they are pointing outside of the defined path @@ -120,23 +120,34 @@ stripdir = dir prependdir = ddir ddir = None - if workers is not None: - if workers < 0: - raise ValueError('workers must be greater or equal to 0') - elif workers != 1: - try: - # Only import when needed, as low resource platforms may - # fail to import it - from concurrent.futures import ProcessPoolExecutor - except ImportError: - workers = 1 + if workers < 0: + raise ValueError('workers must be greater or equal to 0') + if workers != 1: + # Check if this is a system where ProcessPoolExecutor can function. + from concurrent.futures.process import _check_system_limits + try: + _check_system_limits() + except NotImplementedError: + workers = 1 + else: + from concurrent.futures import ProcessPoolExecutor if maxlevels is None: maxlevels = sys.getrecursionlimit() files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels) success = True - if workers is not None and workers != 1 and ProcessPoolExecutor is not None: + if workers != 1 and ProcessPoolExecutor is not None: + mp_context_arg = {} + if PY37: + import multiprocessing + if multiprocessing.get_start_method() == 'fork': + mp_context = multiprocessing.get_context('forkserver') + else: + mp_context = None + mp_context_arg = {"mp_context": mp_context} + # If workers == 0, let ProcessPoolExecutor choose workers = workers or None - with ProcessPoolExecutor(max_workers=workers) as executor: + with ProcessPoolExecutor(max_workers=workers, + **mp_context_arg) as executor: results = executor.map(partial(compile_file, ddir=ddir, force=force, rx=rx, quiet=quiet, @@ -178,7 +189,7 @@ files each with one optimization level. invalidation_mode: how the up-to-dateness of the pyc will be checked stripdir: part of path to left-strip from source file path - prependdir: path to prepend to beggining of original file path, applied + prependdir: path to prepend to beginning of original file path, applied after stripdir limit_sl_dest: ignore symlinks if they are pointing outside of the defined path. @@ -190,10 +201,8 @@ "in combination with stripdir or prependdir")) success = True - if PY36 and quiet < 2 and isinstance(fullname, os.PathLike): - fullname = os.fspath(fullname) - else: - fullname = str(fullname) + fullname = os.fspath(fullname) + stripdir = os.fspath(stripdir) if stripdir is not None else None name = os.path.basename(fullname) dfile = None @@ -206,13 +215,13 @@ if stripdir is not None: fullname_parts = fullname.split(os.path.sep) stripdir_parts = stripdir.split(os.path.sep) - ddir_parts = list(fullname_parts) - for spart, opart in zip(stripdir_parts, fullname_parts): - if spart == opart: - ddir_parts.remove(spart) - - dfile = os.path.join(*ddir_parts) + if stripdir_parts != fullname_parts[:len(stripdir_parts)]: + if quiet < 2: + print("The stripdir path {!r} is not a valid prefix for " + "source path {!r}; ignoring".format(stripdir, fullname)) + else: + dfile = os.path.join(*fullname_parts[len(stripdir_parts):]) if prependdir is not None: if dfile is None: @@ -258,7 +267,7 @@ if not force: try: mtime = int(os.stat(fullname).st_mtime) - expect = struct.pack(*(pyc_header_format + (mtime,))) + expect = struct.pack(*(pyc_header_format + (mtime & 0xFFFF_FFFF,))) for cfile in opt_cfiles.values(): with open(cfile, 'rb') as chandle: actual = chandle.read(pyc_header_lenght) @@ -301,9 +310,8 @@ else: print('*** ', end='') # escape non-printable characters in msg - msg = err.msg.encode(sys.stdout.encoding, - errors='backslashreplace') - msg = msg.decode(sys.stdout.encoding) + encoding = sys.stdout.encoding or sys.getdefaultencoding() + msg = err.msg.encode(encoding, errors='backslashreplace').decode(encoding) print(msg) except (SyntaxError, UnicodeError, OSError) as e: success = False @@ -408,8 +416,8 @@ type=int, help='Run compileall concurrently') parser.add_argument('-o', action='append', type=int, dest='opt_levels', help=('Optimization levels to run compilation with. ' - 'Default is -1 which uses optimization level of ' - 'Python interpreter itself (specified by -O).')) + 'Default is -1 which uses the optimization level ' + 'of the Python interpreter itself (see -O).')) parser.add_argument('-e', metavar='DIR', dest='limit_sl_dest', help='Ignore symlinks pointing outsite of the DIR') parser.add_argument('--hardlink-dupes', action='store_true', @@ -456,7 +464,8 @@ # if flist is provided then load it if args.flist: try: - with (sys.stdin if args.flist=='-' else open(args.flist)) as f: + with (sys.stdin if args.flist=='-' else + open(args.flist, encoding="utf-8")) as f: for line in f: compile_dests.append(line.strip()) except OSError: @@ -464,9 +473,6 @@ print("Error reading file list {}".format(args.flist)) return False - if args.workers is not None: - args.workers = args.workers or None - if PY37 and args.invalidation_mode: ivl_mode = args.invalidation_mode.replace('-', '_').upper() invalidation_mode = py_compile.PycInvalidationMode[ivl_mode] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compileall2-0.7.2/setup.cfg new/compileall2-0.8.0/setup.cfg --- old/compileall2-0.7.2/setup.cfg 2020-12-08 13:57:16.250812000 +0100 +++ new/compileall2-0.8.0/setup.cfg 2024-03-21 16:55:01.669314400 +0100 @@ -1,6 +1,6 @@ [metadata] name = compileall2 -version = 0.7.2 +version = 0.8.0 description = Enhanced Python `compileall` module long_description = file:README.md long_description_content_type = text/markdown @@ -13,12 +13,14 @@ Development Status :: 4 - Beta Intended Audience :: Developers Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy License :: OSI Approved :: Python Software Foundation License ++++++ test_compileall2.py ++++++ --- /var/tmp/diff_new_pack.NNpWLb/_old 2024-04-07 22:14:00.476186629 +0200 +++ /var/tmp/diff_new_pack.NNpWLb/_new 2024-04-07 22:14:00.480186775 +0200 @@ -1,5 +1,6 @@ import sys import compileall2 as compileall +import contextlib import importlib.util import test.test_importlib.util import marshal @@ -16,10 +17,14 @@ import filecmp from unittest import mock, skipUnless +from concurrent.futures import ProcessPoolExecutor try: - from concurrent.futures import ProcessPoolExecutor + # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists + # and it can function. + from concurrent.futures.process import _check_system_limits + _check_system_limits() _have_multiprocessing = True -except ImportError: +except NotImplementedError: _have_multiprocessing = False from test import support @@ -122,7 +127,7 @@ self.directory = tempfile.mkdtemp() self.source_path = os.path.join(self.directory, '_test.py') self.bc_path = importlib.util.cache_from_source(self.source_path) - with open(self.source_path, 'w') as file: + with open(self.source_path, 'w', encoding="utf-8") as file: file.write('x = 123\n') self.source_path2 = os.path.join(self.directory, '_test2.py') self.bc_path2 = importlib.util.cache_from_source(self.source_path2) @@ -137,16 +142,34 @@ def add_bad_source_file(self): self.bad_source_path = os.path.join(self.directory, '_test_bad.py') - with open(self.bad_source_path, 'w') as file: + with open(self.bad_source_path, 'w', encoding="utf-8") as file: file.write('x (\n') def timestamp_metadata(self): with open(self.bc_path, 'rb') as file: data = file.read(compileall.pyc_header_lenght) mtime = int(os.stat(self.source_path).st_mtime) - compare = struct.pack(*(compileall.pyc_header_format + (mtime,))) + compare = struct.pack(*(compileall.pyc_header_format + (mtime & 0xFFFF_FFFF,))) return data, compare + def test_year_2038_mtime_compilation(self): + # Test to make sure we can handle mtimes larger than what a 32-bit + # signed number can hold as part of bpo-34990 + try: + os.utime(self.source_path, (2**32 - 1, 2**32 - 1)) + except (OverflowError, OSError): + self.skipTest("filesystem doesn't support timestamps near 2**32") + self.assertTrue(compileall.compile_file(self.source_path)) + + def test_larger_than_32_bit_times(self): + # This is similar to the test above but we skip it if the OS doesn't + # support modification times larger than 32-bits. + try: + os.utime(self.source_path, (2**35, 2**35)) + except (OverflowError, OSError): + self.skipTest("filesystem doesn't support large timestamps") + self.assertTrue(compileall.compile_file(self.source_path)) + def recreation_check(self, metadata): """Check that compileall recreates bytecode when the new metadata is used.""" @@ -211,6 +234,20 @@ quiet=2)) self.assertTrue(os.path.isfile(self.bc_path)) + def test_compile_file_pathlike_stripdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_file(pathlib.Path(self.source_path), + stripdir=pathlib.Path('stripdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + + def test_compile_file_pathlike_prependdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_file(pathlib.Path(self.source_path), + prependdir=pathlib.Path('prependdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + def test_compile_path(self): with test.test_importlib.util.import_state(path=[self.directory]): self.assertTrue(compileall.compile_path(quiet=2)) @@ -227,11 +264,19 @@ data_file = os.path.join(data_dir, 'file') os.mkdir(data_dir) # touch data/file - with open(data_file, 'w'): + with open(data_file, 'wb'): pass compileall.compile_file(data_file) self.assertFalse(os.path.exists(os.path.join(data_dir, '__pycache__'))) + + def test_compile_file_encoding_fallback(self): + # Bug 44666 reported that compile_file failed when sys.stdout.encoding is None + self.add_bad_source_file() + with contextlib.redirect_stdout(io.StringIO()): + self.assertFalse(compileall.compile_file(self.bad_source_path)) + + def test_optimize(self): # make sure compiling with different optimization settings than the # interpreter's creates the correct file names @@ -256,6 +301,21 @@ self.assertRegex(line, r'Listing ([^WindowsPath|PosixPath].*)') self.assertTrue(os.path.isfile(self.bc_path)) + def test_compile_dir_pathlike_stripdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_dir(pathlib.Path(self.directory), + stripdir=pathlib.Path('stripdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + + def test_compile_dir_pathlike_prependdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_dir(pathlib.Path(self.directory), + prependdir=pathlib.Path('prependdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + + @skipUnless(_have_multiprocessing, "requires multiprocessing") @mock.patch('concurrent.futures.ProcessPoolExecutor') def test_compile_pool_called(self, pool_mock): compileall.compile_dir(self.directory, quiet=True, workers=5) @@ -266,11 +326,13 @@ "workers must be greater or equal to 0"): compileall.compile_dir(self.directory, workers=-1) + @skipUnless(_have_multiprocessing, "requires multiprocessing") @mock.patch('concurrent.futures.ProcessPoolExecutor') def test_compile_workers_cpu_count(self, pool_mock): compileall.compile_dir(self.directory, quiet=True, workers=0) self.assertEqual(pool_mock.call_args[1]['max_workers'], None) + @skipUnless(_have_multiprocessing, "requires multiprocessing") @mock.patch('concurrent.futures.ProcessPoolExecutor') @mock.patch('compileall2.compile_file') def test_compile_one_worker(self, compile_file_mock, pool_mock): @@ -361,6 +423,29 @@ str(err, encoding=sys.getdefaultencoding()) ) + def test_strip_only_invalid(self): + fullpath = ["test", "build", "real", "path"] + path = os.path.join(self.directory, *fullpath) + os.makedirs(path) + script = script_helper.make_script(path, "test", "1 / 0") + bc = importlib.util.cache_from_source(script) + stripdir = os.path.join(self.directory, *(fullpath[:2] + ['fake'])) + compileall.compile_dir(path, quiet=True, stripdir=stripdir) + rc, out, err = script_helper.assert_python_failure(bc) + expected_not_in = os.path.join(self.directory, *fullpath[2:]) + self.assertIn( + path, + str(err, encoding=sys.getdefaultencoding()) + ) + self.assertNotIn( + expected_not_in, + str(err, encoding=sys.getdefaultencoding()) + ) + self.assertNotIn( + stripdir, + str(err, encoding=sys.getdefaultencoding()) + ) + def test_prepend_only(self): fullpath = ["test", "build", "real", "path"] path = os.path.join(self.directory, *fullpath) @@ -752,8 +837,7 @@ if not directory.is_dir(): directory.mkdir() directory_created = True - with path.open('w') as file: - file.write('# for test_compileall') + path.write_text('# for test_compileall', encoding="utf-8") except OSError: sys_path_writable = False break @@ -1037,7 +1121,7 @@ f2 = script_helper.make_script(self.pkgdir, 'f2', '') f3 = script_helper.make_script(self.pkgdir, 'f3', '') f4 = script_helper.make_script(self.pkgdir, 'f4', '') - with open(os.path.join(self.directory, 'l1'), 'w') as l1: + with open(os.path.join(self.directory, 'l1'), 'w', encoding="utf-8") as l1: l1.write(os.path.join(self.pkgdir, 'f1.py')+os.linesep) l1.write(os.path.join(self.pkgdir, 'f2.py')+os.linesep) self.assertRunOK('-i', os.path.join(self.directory, 'l1'), f4) @@ -1051,7 +1135,7 @@ f2 = script_helper.make_script(self.pkgdir, 'f2', '') f3 = script_helper.make_script(self.pkgdir, 'f3', '') f4 = script_helper.make_script(self.pkgdir, 'f4', '') - with open(os.path.join(self.directory, 'l1'), 'w') as l1: + with open(os.path.join(self.directory, 'l1'), 'w', encoding="utf-8") as l1: l1.write(os.path.join(self.pkgdir, 'f2.py')+os.linesep) self.assertRunOK('-i', os.path.join(self.directory, 'l1')) self.assertNotCompiled(f1) @@ -1121,7 +1205,7 @@ new=[sys.executable, self.directory, "-j0"]): compileall.main() self.assertTrue(compile_dir.called) - self.assertEqual(compile_dir.call_args[-1]['workers'], None) + self.assertEqual(compile_dir.call_args[-1]['workers'], 0) def test_strip_and_prepend(self): fullpath = ["test", "build", "real", "path"]