Python
Setuptools 59
O Fedora Linux 36 fornece python-setuptools 59. Isso inclui a remoção do comando de configuração use_2to3
. Para obter mais detalhes, consulte log de alterações upstream.
Novo esquema de instalação de pacotes Python
No Fedora Linux 36, o Python muda a forma como os caminhos de instalação dos pacotes Python são tratados. Essas mudanças afetam o Python principal no Fedora 36, Python 3.10, bem como qualquer versão mais recente do Python incluída. A maioria dos usuários do Fedora Linux não deve ser afetada pela mudança, mas há situações em que podem haver pequenas diferenças.
Quando os pacotes Python são instalados por sudo pip
, sudo python setup.py install
ou métodos semelhantes, os pacotes Python são instalados em /usr/local/lib(64)/python3.10/site-packages/
. Isso já vem acontecendo desde o Fedora Linux 27. No entanto, a maneira como isso é alcançado foi significativamente reimplementada no Fedora Linux 36 e isso criou várias pequenas diferenças.
The sysconfig
Python module from the standard library defines several installation schemes. By default, the installation scheme used on Fedora 36 when installing Python packages using root privileges (for example via sudo
) is {prefix}/lib(64)/python3.10/site-packages/
, where {prefix}
is defined as /usr/local
by default. When building RPM packages, {prefix}
is defined as /usr
by default. When Python itself runs from a Python virtual environment, {prefix}
is defined as the path for the virtual environment.
Previously, the /local/
part was only artificially added when installing packages via distutils
, now it is also defined in sysconfig
. This was changed to be more consistent with what other Python distributors are doing, so that the scheme is more likely to be accepted in upstream Python and to work well with upstream tools like setuptools or pip, which we cannot modify when they are installed or upgraded using pip directly from the Python Package Index.
Aqui estão as diferenças que podem ser observadas com a nova abordagem:
sysconfig.get_path(key)
retorna caminhos com /local/
Previously, on Fedora Linux 35 outside of a virtual environment:
>>> import sysconfig
>>> for key in sysconfig.get_path_names():
... print(f'{key} = {sysconfig.get_path(key)}')
...
stdlib = /usr/lib64/python3.10
platstdlib = /usr/lib64/python3.10
purelib = /usr/lib/python3.10/site-packages
platlib = /usr/lib64/python3.10/site-packages
include = /usr/include/python3.10
scripts = /usr/bin
data = /usr
Agora, no Fedora Linux 36 (exceto durante a compilação RPM):
>>> import sysconfig
>>> for key in sysconfig.get_path_names():
... print(f'{key} = {sysconfig.get_path(key)}')
...
stdlib = /usr/lib64/python3.10
platstdlib = /usr/lib64/python3.10
purelib = /usr/local/lib/python3.10/site-packages
platlib = /usr/local/lib64/python3.10/site-packages
include = /usr/include/python3.10
scripts = /usr/local/bin
data = /usr/local
Os valores agora refletem a realidade de onde os pacotes serão realmente instalados com pip, setuptools, distutils, etc. No entanto, se seu código Python usar os valores para determinar de onde carregar os pacotes Python de, ele não verá dnf -installed pacotes, que são instalados em /usr/lib(64)/python3.10/site-packages/
. Geralmente, sysconfig.get_path(key)
fornece resultados que determinam onde os pacotes Python devem ser instalados para. Para corrigir o código afetado, evite suposições de que "onde instalar pacotes para" é o mesmo que "onde carregar módulos Python de".
Correções de exemplo de projetos de código aberto afetados:
If you need to restore the previous behavior of sysconfig.get_path(key)
, you may explicitly set the {base}
and {platbase}
variables to /usr
:
>>> for key in sysconfig.get_path_names():
... print(f'{key} = {sysconfig.get_path(key, vars={"base": "/usr", "platbase": "/usr"})}')
...
stdlib = /usr/lib64/python3.10
platstdlib = /usr/lib64/python3.10
purelib = /usr/lib/python3.10/site-packages
platlib = /usr/lib64/python3.10/site-packages
include = /usr/include/python3.10
scripts = /usr/bin
data = /usr
Advertências relacionadas à compilação de RPM
When Python runs during RPM build, it sets the defaults for {base}
and {platbase}
variables to /usr
. This behavior is triggered when the $RPM_BUILD_ROOT
environment variable is set. That has several caveats:
Executando Python no subprocesso do Python
If the Python code that runs in RPM build (for example in %check
) executes another Python instance via a subprocess, it is relatively easy to inadvertently unset all environment variables. When this happens, the inner Python will not know it runs within RPM build and will return paths with the /usr/local/
prefix.
No exemplo mais trivial, as variáveis de ambiente circundantes são passadas implicitamente para o subprocesso e tudo funciona conforme o esperado:
>>> import os, subprocess, sys
>>> 'RPM_BUILD_ROOT' in os.environ
True
>>> command = [sys.executable, '-c', 'import sysconfig; print(sysconfig.get_path("purelib"))']
>>> subprocess.check_output(command)
b'/usr/lib/python3.10/site-packages\n'
Mas quando um ambiente personalizado é passado, ele interrompe a detecção, porque $RPM_BUILD_ROOT
não está mais definido:
>>> subprocess.check_output(command, env={'FOO': 'bar'})
b'/usr/local/lib/python3.10/site-packages\n'
Uma solução é sempre fazer uma cópia do ambiente ao redor, depois editá-la e passá-la para o subprocesso. Esse é um conselho Python geralmente válido.
>>> env = os.environ | {'FOO': 'bar'}
>>> subprocess.check_output(command, env=env)
b'/usr/lib/python3.10/site-packages\n'
Correções de exemplo de projetos de código aberto afetados:
Macros RPM %(…)
Quando macros RPM na forma de %(command …)
são expandidas, $RPM_BUILD_ROOT
ainda não está definido. Portanto, o Python não sabe que é invocado da compilação RPM e os caminhos retornados por sysconfig.get_path(…)
contêm /local/
. Para corrigir isso, defina $RPM_BUILD_ROOT
na definição da macro (para qualquer valor, mesmo vazio). Por exemplo, uma macro definida assim:
%global python3_scripts_dir %(python3 "import sysconfig; print(sysconfig.get_path('scripts'))")
Precisa ser alterada para isso:
%global python3_scripts_dir %(RPM_BUILD_ROOT= python3 "import sysconfig; print(sysconfig.get_path('scripts'))")
As macros RPM afetadas fornecidas pelos pacotes python-rpm-macros
do Fedora foram todas https://src.fedoraproject.org/rpms/python-rpm-macros/pull-request/110 [alteradas de acordo].
Caminhos para inicializar ambientes virtuais Python
Se o seu código Python usa esquemas de instalação para determinar os caminhos a serem usados em ambientes virtuais criados e o interpretador Python que executa esse código não é executado a partir de um ambiente virtual Python em si, os caminhos não corresponderão.
Para inicializar ambientes virtuais Python, o código deve usar o esquema de instalação venv
(mas apenas se existir).
>>> scheme = 'venv' if 'venv' in sysconfig.get_scheme_names() else None
>>> sysconfig.get_path('purelib', scheme=scheme, vars={'base': '<venv>'})
'<venv>/lib/python3.10/site-packages'
>>> sysconfig.get_path('scripts', scheme=scheme, vars={'base': '<venv>'})
'<venv>/bin'
The venv
scheme is currently Fedora specific, but other Python distributors (such as Ubuntu Deadsnakes) may define it as well. The venv
scheme is generally available starting with Python 3.11. Due to checking if the venv
install scheme exists the code is functional on other operating systems as well, as it falls back to a backwards compatible behavior.
Correções de exemplo de projetos de código aberto afetados:
Django 4.0
Fedora Linux 36 provides the latest version of Django 4.0. Few highlights of this version are:
-
The new RedisCache backend provides built-in support for caching with Redis.
-
To ease customization of Forms, Formsets, and ErrorList they are now rendered using the template engine.
-
The Python standard library’s zoneinfo is now the default timezone implementation in Django.
For more details, see the upstream release notes.
Want to help? Learn how to contribute to Fedora Docs ›