Diretrizes de Empacotamento Python
Esta versão das Diretrizes de Empacotamento Python está em vigor desde 2021 e representa uma grande reescrita e mudança de paradigma. Nem todos os pacotes são atualizados para refletir isso. As diretrizes mais antigas ainda estão sendo atualizadas e os pacotes existentes PODEM usá-las em vez deste documento:
-
As diretrizes de empacotamento do Python “da era 201x” (Pacotes que os usam geralmente usam a macro
%py3_install
ou%py3_install_wheel
ou chamamsetup.py install
.) -
AApêndice do Python 2 Observe que os pacotes Python 2 requerem uma exceção do FESCo.
Estas diretrizes suportam apenas as versões atuais do Fedora. Para versões mais antigas (como no EPEL 8), consulte diretrizes da era 201x. |
As duas diretrizes para toda a distribuição abaixo se aplicam a todos os softwares no Fedora que usam Python em tempo de compilação ou execução.
O restante das Diretrizes se aplica a pacotes que enviam código que pode ser importado com a instrução import
do Python. Especificamente, são todos os pacotes que instalam arquivos em /usr/lib*/python*/
.
Exceto pelas duas “diretrizes para toda a distribuição”, estas Diretrizes não se aplicam a scripts ou utilitários simples de um arquivo, especialmente se estes estiverem incluídos em software não escrito em Python. No entanto, se um aplicativo (por exemplo, ferramenta CLI, script ou aplicativo GUI) precisar de uma biblioteca Python mais complexa, RECOMENDA-SE que a biblioteca seja empacotada como uma biblioteca importável de acordo com estas diretrizes.
Um dos principais objetivos do empacotamento Python no Fedora é harmonizar-se com o ecossistema Python mais amplo, ou seja, os padrões Python Packaging Authority (PyPA) e o Python Package Índice (PyPI). RECOMENDA-SE que os empacotadores estejam preparados para se envolver em projetos upstream para estabelecer as melhores práticas conforme descrito aqui. Queremos melhorar tanto o Fedora quanto o ecossistema Python mais amplo.
Algumas ferramentas de construção (como CMake ou autotools) podem ainda não funcionar com os padrões PyPA mais recentes. (Por exemplo, eles podem gerar diretórios .egg-info em vez de .dist-info .) Embora os pontos normativos deste documento (RECOMENDA-SE/DEVE) sejam independentes de ferramentas, muitas das dicas práticas e macros auxiliares serão não ser aplicável. Se isso afetar você, considere entrar em contato com Python SIG para orientação e/ou seguir o diretrizes mais antigas por enquanto.
|
O Python SIG do Fedora não apenas desenvolve essas diretrizes, mas também está envolvido nos padrões PyPA e nas melhores práticas de empacotamento do Python. Confira o wiki ou a lista de discussão se você precisar de ajuda ou deseja ajudar. |
Diretrizes para toda a distribuição
Build-time dependency on python3-devel
Every package that uses Python (at run-time and/or build-time)
and/or installs Python modules
MUST have a build-time dependency on python3-devel
,
even if Python is not actually invoked during build-time.
Such a package MUST use one of the following in its .spec
file:
-
%pyproject_buildrequires
in the%generate_buildrequires
section -
BuildRequires: python3-devel
Only having a transitive build-time dependency on python3-devel
is not sufficient. If the package uses an alternate Python interpreter instead of python3
(e.g. pypy
, jython
, python2.7
), it MAY instead require the corresponding *-devel
package.
O pacote *-devel
traz macros RPM relevantes. Também pode permitir verificações automatizadas ou manuais: por exemplo, os mantenedores do Python usam esse requisito para listar pacotes que usam o Python de alguma forma e podem ser afetados por mudanças planejadas.
Macros obrigatórias
As macros a seguir DEVEM ser usadas quando aplicável.
As expansões entre parênteses são fornecidas apenas como referência/exemplos.
As macros são definidas para você em todas as versões suportadas do Fedora e EPEL.
-
%{python3}
(/usr/bin/python3
): O interpretador Python. Por exemplo, esta macro deve ser usada para invocar Python a partir de um script de arquivospec
, passada para scriptsconfigure
para selecionar um executável Python ou usada como%{python3} -m pip
para executar uma ferramenta baseada no Python.Se o software empacotado invocar o Python em tempo de execução (em vez de executar o Python para compilá-lo/testá-lo), pode ser necessário passar sinalizadores para
%{python3}
para isolá-lo dos pacotes instalados pelo usuário. Veja Shebangs para detalhes. -
%{python3_version}
(por exemplo,3.9
,3.10
): versão do interpretador Python. -
%{python3_version_nodots}
(por exemplo39
,310
): Versão do interpretador Python sem o ponto. -
%{python3_sitelib}
(por exemplo,/usr/lib/python3.9/site-packages
): onde os módulos Python puros são instalados. -
%{python3_sitearch}
(por exemplo,/usr/lib64/python3.9/site-packages
): onde os módulos de extensão Python (código nativo, por exemplo, compilado de C) são instalados.
O restante deste documento usa essas macros, junto com %{_bindir}
(/usr/bin/
), em vez dos nomes de caminho brutos.
Suporte à implementação Python
O Fedora tem como alvo principal CPython, a implementação de referência da linguagem Python. Geralmente usamos “Python” para significar CPython.
Implementações alternativas como pypy
estão disponíveis, mas atualmente carecem de ferramentas e diretrizes abrangentes para empacotamento. Ao direcioná-los, não existem regras rígidas (exceto as diretrizes gerais de empacotamento do Fedora). Mas, por favor, tente respeitar o espírito destas diretrizes. Em caso de dúvida, considere consultar o Python SIG.
Suporte a versões do Python
Os pacotes do Fedora NÃO DEVEM depender de outras versões do interpretador CPython além do atual python3
.
No Fedora, as bibliotecas Python são empacotadas para uma única versão do Python, chamada python3
. Por exemplo, no Fedora 32, python3
é Python 3.8.
No passado, havia várias pilhas Python, por exemeplo python3.7
e python2.7
, instaláveis juntos na mesma máquina. Esse também é o caso de alguns projetos construídos em cima do Fedora, como RHEL, EPEL e CentOS. O Fedora pode reintroduzir pilhas instaláveis em paralelo no futuro (por exemplo, se uma mudança para uma nova versão do Python precisar de um período de transição, ou se de alguma forma aparecerem mantenedores interessados suficientes).
O Fedora inclui versões alternativas de intérpretes, por exemplo python2.7
ou python3.5
, mas estes são destinados apenas para desenvolvedores que precisam testar o código upstream. Correções de bugs e segurança para esses interpretadores cobrem apenas este caso de uso. Pacotes como pip
ou tox
, que permitem configurar ambientes isolados e instalar pacotes de terceiros neles, PODE, como exceção à regra acima, usar esses interpretadores desde que isso seja coordenado com os mantenedores do interpretador Python relevante.
Nomenclatura
Os pacotes Python têm vários nomes diferentes, que devem ser mantidos sincronizados, mas às vezes podem diferir por razões históricas ou práticas. Eles são:
Alguns exemplos (bons e piores):
Componente Fedora | RPM construído | Nome do projeto | Nome importável |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Em outra parte deste texto, as metavariáveis SRPMNAME
, RPMNAME
, PROJECTNAME
, MODNAME
referem-se a esses nomes, respectivamente.
Nome canônico do projeto
A maioria desses nomes são identificadores amigáveis à máquina que diferenciam maiúsculas de minúsculas, mas o nome do projeto tem uma semântica amigável: não diferencia maiúsculas de minúsculas e trata alguns conjuntos de caracteres (como ._-
) especialmente. Para uso automatizado, ele precisa ser normalizado para um formato canônico usado por ferramentas e serviços Python, como setuptools, pip e PyPI. Por exemplo, o nome canônico do projeto Django
é django
(em letras minúsculas). Esta normalização é definida em PEP 503 e a macro %{py_dist_name}
implementa para empacotamento do Fedora. O nome canônico é obtido mudando o nome do projeto para minúsculas e convertendo todas as execuções de caracteres não alfanuméricos em caracteres “-” únicos. Exemplo: “A árvore $$$” se torna “a-arvore”.
Em outra parte deste texto, a metavariável DISTNAME
refere-se à forma canônica do nome do projeto.
Observe que em alguns lugares, o nome do projeto original e não normalizado deve ser usado. Por exemplo, a macro %pypi_source
e a macro %autosetup
precisam de Django
, não de django
.
Limitações de nome
O caractere +
em nomes de pacotes construídos (ou seja, não SRPM) que incluem os diretórios .dist-info
ou .egg-info
é reservado para Extras e NÃO DEVE ser usado para qualquer outro fim.
Como exceção, os caracteres +
PODEM aparecer no final de tais nomes.
O caractere +
aciona o gerador automático de dependência para extras.
Substitua qualquer sinal +
no nome upstream por -
. Omita os sinais +
no início do nome. Considere adicionar Provides
ao nome original com caracteres +
para tornar o pacote mais fácil de ser encontrado pelos usuários.
Nomenclatura de biblioteca
Um pacote compilado (ou seja, não SRPM) para uma biblioteca Python DEVE ser nomeado com o prefixo python3-
. Um pacote fonte contendo principalmente uma biblioteca Python DEVE ser nomeado com o prefixo python-
.
RECOMENDA-SE que o nome do pacote Fedora contenha o Nome canônico do projeto. Se possível, RECOMENDA-SE que o nome do projeto seja igual ao nome do módulo principal importável, em letras minúsculas, com sublinhados (_
) substituídos por traços (-
).
Se o nome do módulo importável e o nome do projeto não corresponderem, os usuários frequentemente ficarão confusos. Neste caso, RECOMENDA-SE que os empacotadores garantam que o upstream esteja ciente do problema e (especialmente para novos pacotes onde a renomeação é viável) se esforçar para renomear o pacote. O Python SIG está disponível para assistência.
Uma biblioteca Python é um pacote destinado a ser importado em Python, como import requests
. Ferramentas como Ansible ou IDLE, cujo código é importável, mas não se destina principalmente a ser importado de outro software, não são consideradas bibliotecas neste sentido. Portanto, esta seção não se aplica a eles. (Consulte diretrizes gerais de bibliotecas e aplicativos para obter orientação geral.)
O nome do componente Fedora (pacote fonte) para uma biblioteca deve ser formado pegando o nome canônico do projeto e acrescentando python-
se ainda não começar com python-
. Isso pode levar a conflitos (por exemplo, entre bugzilla e python-bugzilla). Nesse caso, certifique-se de que o upstream esteja ciente da nomenclatura potencialmente confusa e aplique o melhor julgamento.
Nomenclatura de aplicativo
Para pacotes que forneçam principalmente aplicativos, serviços ou qualquer tipo de executável É RECOMENDÁVEL que sejam nomeados de acordo com as diretrizes de nomenclatura do Fedora gerais (por exemplo, ansible
).
Considere adicionar um "provides" virtual de acordo com Nomenclatura de biblioteca acima (por exemplo, python3-PROJECTNAME
), se isso ajudar os usuários a encontrar o pacote.
Arquivos para incluir
Arquivos fonte e cache de bytecode
Os pacotes DEVEM incluir o arquivo fonte (*.py
) E o cache de bytecode (*.pyc
) para cada módulo importável em Python puro. Os arquivos fonte DEVEM ser incluídos no mesmo pacote que o cache de bytecode.
Para scripts que não são importáveis (normalmente aqueles em %{_bindir}
ou %{_libexecdir}
) É RECOMENDÁVEL que NÃO sejam compilados em bytes.
Os arquivos de cache são encontrados em um diretório __pycache__
e possuem um sufixo dependente do interpretador como .cpython-39.pyc
.
O cache não é necessário para executar o software, mas se não for encontrado, o Python tentará criá-lo quando um módulo for importado. Se isso for bem-sucedido, o arquivo não será rastreado pelo RPM e permanecerá no sistema após a desinstalação. Se não tiver êxito, os usuários podem obter negações falsas de SELinux AVC nos logs.
Normalmente, a compilação de bytes (gerando os arquivos de cache) é feita para você pelo brp-python-bytecompile
script BRP, que é executado automaticamente após a seção %install
do arquivo spec foi processado. Ele compila qualquer arquivo .py
que encontrar em %{python3_sitelib}
ou %{python3_sitearch}
.
Você deve incluir esses arquivos do seu pacote (ou seja, na seção %files
).
Se o código estiver em um subdiretório (pacote importável), inclua o diretório inteiro:
%files
%{python3_sitelib}/foo/
Adicionar a barra final é uma prática recomendada para diretórios.
No entanto, isso não pode ser usado para módulos de nível superior (aqueles diretamente em, por exemplo, %{python3_sitelib}
), porque ambos %{python3_sitelib}
e %{python3_sitelib}/__pycache__/
são de propriedade do próprio Python. Aqui, a macro %pycached
pode ajudar. Ele se expande para o arquivo fonte *.py
fornecido e seus arquivos de cache correspondentes. Por exemplo:
%files
%pycached %{python3_sitelib}/foo.py
expande aproximadamente para:
%files
%{python3_sitelib}/foo.py
%{python3_sitelib}/__pycache__/foo.cpython-3X{,.opt-?}.pyc
Compilação manual para bytes
Se você precisar compilar coisas fora de %{python3_sitelib}
/%{python3_sitearch}
, use a macro %py_byte_compile
.
Por exemplo, se o seu software adiciona %{_datadir}/meupacote
ao caminho de importação do Python e importa o pacote foo
de lá, você precisará compilar foo
com:
%py_byte_compile %{python3} %{buildroot}%{_datadir}/meupacote/foo/
Metadados de dist-info
Cada pacote Python DEVE incluir Metadados de distribuição de pacotes em conformidade com especificações do PyPA (especificamente, Gravação de projetos instalados).
RECOMENDA-SE que os metadados sejam incluídos no mesmo subpacote que o módulo principal importável, se houver.
Isso se aplica a bibliotecas (por exemplo, python-requests
), bem como a ferramentas (por exemplo, ansible
).
Quando o software é dividido em vários subpacotes, não há problema em enviar metadados apenas em um RPM construído. Neste caso, considere trabalhar com o upstream para também dividir o projeto upstream.
Os metadados assumem a forma de um diretório .dist-info
instalado em %{python3_sitelib}
ou %{python3_sitearch}
e contém informações que ferramentas como importlib.metadata
usado para examinar bibliotecas instaladas.
Por exemplo, um projeto chamado MyLib
com pacote importável mylib
poderia ser empacotado com:
%files -p python3-mylib
%{python3_sitelib}/mylib/
%{python3_sitelib}/MyLib-%{version}.dist-info/
%doc README.md
%license LICENSE.txt
Observe que algumas ferramentas mais antigas colocam metadados em um diretório .egg-info
ou até mesmo em um único arquivo. Isso não acontecerá se você usar a macro %pyproject_wheel
. Se o seu pacote usa um sistema de construção que gera um diretório ou arquivo .egg-info
, entre em contato com a Python SIG.
Como exceção, a biblioteca padrão Python PODE ser enviada sem esses metadados.
Listas explícitas
Os pacotes NÃO DEVEM possuir diretórios compartilhados pertencentes ao próprio Python, como os diretórios __pycache__
de nível superior (%{python3_sitelib}/__pycache__
, %{python3_sitearch}/__pycache__
).
Da mesma forma que a regra geral, RECOMENDA-SE que os empacotadores simplesmente agrupem tudo em um diretório compartilhado.
Além da lista geral, RECOMENDA-SE que o seguinte NÃO seja usado em %files
:
-
%{python3_sitelib}/*
-
%{python3_sitearch}/*
-
%{python_sitelib}/*
-
%{python_sitearch}/*
-
%pyproject_save_files '*'
-
%pyproject_save_files +auto
Esta regra serve como uma verificação contra erros comuns que, de outra forma, seriam difíceis de detectar. Isso limita algumas possibilidades de automação.
Os erros mais comuns que esta regra evita são:
-
instalar um conjunto de testes em todo o sistema como um módulo importável chamado
test
, que entraria em conflito com outros pacotes, e -
upstream adicionando novos módulos importáveis inesperados - você deve sempre verificar essas alterações em conflicts e manter a lista de tais arquivos explícita e auditável.
Paridade com PyPI
RECOMENDA-SE que cada pacote Python no Fedora também esteja disponível em o Índice de Pacotes Python (PyPI).
O comando pip install PROJECTNAME
DEVE instalar o mesmo pacote (possivelmente em uma versão diferente), não instalar nada ou falhar com uma mensagem de erro razoável.
Se este não for o caso, RECOMENDA-SE que o empacotador entre em contato com o upstream sobre isso. O objetivo é registrar ou bloquear o nome do projeto no PyPI ou, de outra forma, garantir que a regra seja seguida.
Se o seu pacote não for ou não puder ser publicado no PyPI, você poderá:
-
Pedir ao upstream para publicá-lo
-
Se desejar: publique você mesmo no PyPI e mantenha-o
-
Peça ao Python SIG para bloquear o nome no PyPI para você
-
Envie um e-mail para o admins do PyPI para bloquear o nome para você, fornecendo o nome do projeto e explicando a situação (por exemplo: o pacote atualmente não pode ser instalado via
pip
). Você pode fazer perguntas e discutir o processo em Discourse do Python.
Nomes de projetos que estavam no Fedora, mas não no PyPI quando essas diretrizes foram propostas, estão bloqueados de serem carregados no PyPI. Isso evita que trolls em potencial os capturem, mas também bloqueia proprietários legítimos. Se o seu pacote for afetado, entre em contato com o Python SIG ou relate um problema ao PyPA e mencione @encukou .
|
Se o nome do projeto do seu pacote entrar em conflito com um pacote diferente no PyPI, altere o nome do projeto. Por mais doloroso que seja, precisamos usar um único espaço de nomes global em todo o ecossistema Python. Software que não foi escrito especificamente para o Fedora já espera que os nomes dos projetos usem o espaço de nomes PyPI: por exemplo, se uma biblioteca de terceiros identifica uma dependência pelo nome, não queremos que essa dependência seja satisfeita por um pacote Fedora não relacionado.
Como sempre, exceções específicas podem ser concedidas pelo Comitê de Empacotamento.
Provides e requisitos
Provides módulos importáveis
Para qualquer módulo destinado a ser usado em Python 3 com import MODNAME
, RECOMENDA-SE que o pacote que o inclui forneça python3-MODNAME
, com sublinhados (_
) substituídos por traços (-
).
É claro que este é sempre o caso se o pacote for denominado python3-MODNAME
. Se o subpacote tiver algum outro nome, adicione %py_provides python3-MODNAME
explicitamente. Consulte a seção a seguir para aprender sobre %py_provides
.
Provides automático para python- e python3.X-
Para qualquer FOO
, RECOMENDA-SE que um pacote que fornece python3-FOO
use %py_provides
ou um gerador automático para fornecer também python-FOO
e python3.X-FOO
, onde X
é a versão secundária do interpretador.
RECOMENDA-SE que o provide NÃO seja adicionado manualmente: se um gerador ou macro não for usado, não adicione os provides python-FOO
/ python3.X-FOO
.
Isso é feito automaticamente para nomes de pacotes por um gerador. Se for absolutamente necessário, o gerador pode ser desativado indefinindo a macro %__pythonname_provides
.
Para provides que não sejam nomes de pacotes ou (por motivos técnicos) para pacotes sem arquivos, o gerador não funcionará. Para estes casos, a seguinte invocação fornecerá python3-FOO
, python-FOO
e python3.X-FOO
:
%py_provides python3-FOO
Usar o gerador ou macro é importante, pois a forma específica de fornecimento pode mudar no futuro.
Provides legível por máquina
Todo pacote Python DEVE fornecer python3dist(DISTNAME)
e python3.Xdist(DISTNAME)
, onde X
é a versão secundária do interpretador e DISTNAME
é o Nome canônico do projeto correspondente aos [metadados Dist-info]. Por exemplo, python3-django
forneceria python3dist(django)
e python3.9dist(django)
.
Isso é gerado automaticamente a partir dos metadados dist-info. RECOMENDA-SE que o provide NÃO seja adicionado manualmente: se o gerador não conseguir adicioná-lo, os metadados DEVEM ser corrigidos.
Esses Provides são usados para Requires gerados automaticamente.
Se for absolutamente necessário, o gerador automático pode ser desativado indefinindo a macro %{?__pythondist_provides}
. Considere discutir seu caso de uso com o Python SIG se você precisar fazer isso.
Dependências
Como mencionado acima, cada pacote Python DEVE explicitamente ter BuildRequire python3-devel
.
RECOMENDA-SE que os pacotes NÃO tenham dependências (em tempo de construção ou tempo de execução) com o prefixo não versionado python-
se a dependência python3-
correspondente puder ser usada em seu lugar.
RECOMENDA-SE que os pacotes NÃO tenham dependências explícitas (em tempo de construção ou tempo de execução) com um prefixo de versão secundária, como python3.8-
ou python3.8dist(
. RECOMENDA-SE que essas dependências sejam automaticamente geradas ou uma macro deve ser usada para obter a versão.
RECOMENDA-SE que os pacotes NÃO tenham uma dependência explícita de tempo de execução em python3
.
Em vez de depender de python3
, os pacotes têm uma dependência automática de python(abi) = 3.X
quando instalam arquivos em %{python3_sitelib}
ou %{python3_sitearch}
, ou eles têm uma dependência automática de /usr/bin/python3
se tiverem scripts Python executáveis, ou têm uma dependência automática de libpython3.X.so.1.0()
se incorporarem Python.
Essas regras ajudam a garantir um caminho de atualização tranquilo quando python3
é atualizado em novas versões do Fedora.
Dependências geradas automaticamente
Os pacotes DEVEM usar o gerador automático de dependência em tempo de execução do Python.
RECOMENDA-SE que os pacotes usem o gerador de dependência de construção opcional, se possível.
O empacotador DEVE inspecionar os requisitos gerados quanto à correção. Todas as dependências DEVEM ser resolvidas na versão alvo do Fedora.
Quaisquer alterações necessárias DEVEM ser feitas por patches ou modificação da fonte (por exemplo, com sed
), em vez de desabilitar o gerador. RECOMENDA-SE que a mudança resultante seja oferecida ao upstream. Como exceção, filtrado PODE ser usada para soluções alternativas temporárias e bootstrapping.
Dependencies covered by the generators SHOULD NOT be repeated in the .spec
file. (For example, if the generator finds a requests
dependency, then Requires: python3-requests
is redundant.)
The automatically generated requirements are in the form python3.Xdist(DISTNAME)
, potentially augmented with version requirements or combined together with rich dependencies. Any .0
suffixes are removed from version numbers to match the behavior of Python tools. (PEP 440 specifies that X.Y
and X.Y.0
are treated as equal.)
Note that the generators only cover Python packages. Other dependencies, often C libraries like openssl-devel
, must be specified in the .spec
file manually.
Where the requirements are specified in the source depends on each project’s build system and preferences. Common locations are pyproject.toml
, setup.py
, setup.cfg
, config.toml
.
Run-time dependency generator
The automatic runtime dependency generator uses package metadata (as recorded in installed *.dist-info
directories) to determine what the package depends on.
In an emergency, you can opt-out from running the requires generator by adding %{?python_disable_dependency_generator}
to the package (usually, just before the main package’s %description
).
Build-time dependency generator
The opt-in (but strongly recommended) build-time dependency generator gathers information from pyproject.toml
build-system information (with fallback to setuptools
) plus a standardized build-system hook to gather further requirements. See the %pyproject_buildrequires
macro for more details.
Note that without the -R
flag, the generator will include run-time requirements in BuildRequires. This is useful for running tests and for checking that the dependencies are available in Fedora.
Test dependencies
See the Tests section.
Extras
Python extras are a way for Python projects to declare that extra dependencies are required for additional functionality.
For example, requests
has several standard dependencies (e.g. urllib3
). But it also declares an extra named requests[security]
, which lists additional dependencies (e.g. cryptography
). Unlike RPM subpackages, extras can only specify additional dependencies, not additional files. The main package will work if the optional dependency is not installed, but it might have limited functionality.
Python tools treat extras as virtual packages. For example, if a user runs pip install 'requests[security]'
, or installs a project that depends on requests[security]
, both requests
and cryptography
will be installed.
In Fedora, extras are usually provided by packages with no files. Instead of square brackets, Fedora package names conventionally use the +
character (which is valid in RPM package names, but not in Python canonical project names nor in extras identifiers).
Handling extras
Python packages SHOULD have Provides for all extras the upstream project specifies, except:
-
those that are not useful for other packages (for example build/development requirements, commonly named
dev
,doc
ortest
), and -
those that have requirements that are not packaged in Fedora.
A package that provides a Python extra MUST provide python3dist(DISTNAME[EXTRA])
and python3.Xdist(DISTNAME[EXTRA])
, where X
is the minor version of the interpreter, DISTNAME
is the [Canonical project name], and EXTRA
is the name of a single extra. For example, python3.9dist(requests[security])
. These requirements SHOULD be generated using the automatic dependency generator.
A package that provides a Python extra MUST require the extra’s main package with exact NEVR.
A subpackage that primarily provides one Python extra SHOULD be named by appending +
and the extra name to the main package name. For example, python3-requests+security
.
The most straightforward way to provide an extra is with a dedicated subpackage containing no files (a “metapackage”). This case can be automated with the %pyproject_extras_subpkg
macro or the %python_extras_subpkg
macro.
This is not the only way: when some extra is always useful in a distro, it can be provided by the main package; when several extras are related, they may be provided by a single subpackage. However, having one dedicated subpackage per extra allows you to use the automatic dependency generator to ensure that the extras’ requirements will stay in sync with upstream. If you create a dedicated subpackage and want it to be always/usually installed, you can Require/Recommend/Suggest it from the main package.
The dependency generator for extras activates if the following holds:
-
The package name must end with
+EXTRA
(whereEXTRA
is the extra name). -
The package must contain the
.dist-info
directory, usually as%ghost
.
Example and convenience macros
The extra subpackage for setuptools_scm[toml]
can be specified using the %pyproject_extras_subpkg
convenience macro as follows. The macro takes the main package name and name(s) of the extra(s):
%pyproject_extras_subpkg -n python3-setuptools_scm toml
If not using %pyproject_install
, you will instead need to use %python_extras_subpkg
and pass a path to the dist-info
directory:
%python_extras_subpkg -n python3-setuptools_scm -i %{python3_sitelib}/*.dist-info toml
For this case, the extras dependency generator will read upstream metadata from the .dist-info
directory. If it finds that the extra requires on toml
, it will generate Requires: python3.Xdist(toml)
and Provides: python3dist(setuptools-scm[toml])
(and the corresponding python3.Xdist
provide).
If you need additional features that the *_extras_subpkg
macros do not cover, you will need to write the subpackage sections manually. Such features can be, for example:
-
Obsoleting/providing other names (e.g. obsoleted extras packages)
-
Manual strong or weak dependencies on other (possibly non-Python) packages
As an example of what you need to write in these cases, both of the *_extras_subpkg
macro invocations above expand to the following:
%package -n python3-setuptools_scm+toml
Summary: Metapackage for python3-setuptools_scm: toml extra
Requires: python3-setuptools_scm = %{?epoch:%{epoch}:}%{version}-%{release}
%description -n python3-setuptools_scm+toml
This is a metapackage bringing in toml extra requires for python3-setuptools_scm.
It contains no code, just makes sure the dependencies are installed.
%files -n python3-setuptools_scm+toml
%ghost %{python3_sitelib}/*.dist-info
Note that the dependency generator does not add a dependency on the main package (the Requires: python3-setuptools_scm = ...
above). If you are not using the %python_extras_subpkg
macro, you need to add it manually.
Removing extras
If an existing extra is removed from an upstream project, the Fedora maintainer SHOULD try to convince upstream to re-introduce it (with an empty list of dependencies). If that fails, the extra SHOULD be Obsoleted from either the main package or another extras subpackage.
Note that removing extras is discouraged in setuptools documentation (see the Tip box near the end of the Optional dependencies section).
Automatic Requires for extras
The automatic Run-time dependency generator will generate Requires on python3.Xdist(DISTNAME[EXTRA])
from upstream Requires-Dist
metadata.
If the required package does not yet provide metadata for the extra, contact the Fedora maintainer to add it.
In an emergency, you can define the %_python_no_extras_requires
macro to avoid automatically generating all extras requirements.
Interpreter invocation
Shebangs
Shebang lines to invoke Python MUST use %{python3}
as the interpreter.
Shebang lines to invoke Python SHOULD be #!%{python3} -%{py3_shebang_flags}
and they MAY include extra flags.
If (some of) the default flags from the %{py3_shebang_flags}
macro are not desirable, packages SHOULD explicitly redefine the macro to remove them by undefining the relevant %{_py3_shebang_...}
macro.
Using #!%{python3}
(#!/usr/bin/python3
) rather than e.g. #!/usr/bin/env python
ensures that the system-wide Python interpreter is used to run the code, even if the user modifies $PATH
(e.g. by activating a virtual environment).
By default, -%{py3_shebang_flags}
expands to -sP
(or just -s
on Python version lower than 3.11 and Fedora Linux older than 37).
The -s
flag, stored in the %{_py3_shebang_s}
macro, means don’t add user site directory to sys.path
. That ensures the user’s Python packages (e.g. installed by pip install --user
, or just placed in the current directory) don’t interfere with the RPM installed software. Sometimes, such content is desirable, such as with plugins.
The -P
flag, stored in the %{_py3_shebang_P}
macro, means don’t add the script’s directory to sys.path
. Sometimes, adding the script’s directory to sys.path
is desirable, such as with executable Python scripts installed in a custom directory, importing each other.
Removing the undesired flag(s) from the %{py3_shebang_flags}
macro rather than not using the macro at all, ensures that existing or future automation won’t add the flag.
# Remove -s from Python shebang - ensure that extensions installed with pip
# to user locations are seen and properly loaded
%undefine _py3_shebang_s
# Don't add -P to Python shebangs
# The executable Python scripts in /usr/share/opt-viewer/ import each other
%undefine _py3_shebang_P
The %pyproject_install
macro automatically changes all Python shebangs in %{buildroot}%{_bindir}/*
to use %{python3}
and add contents of the %{py3_shebang_flags}
macro to the existing flags. If you’re not using that macro or you need to change a shebang in a different directory, you can use the %py3_shebang_fix
macro as follows:
%py3_shebang_fix SCRIPTNAME …
Invokable Python modules
Every executable TOOL
for which the current version of Python matters SHOULD also be invokable by python3 -m TOOL
.
If the software doesn’t provide this functionality, packagers SHOULD ask the upstream to add it.
This applies to tools that modify the current Python environment (like installing or querying packages), use Python for configuration, or use Python to run plugins. It does not apply to tools like GIMP or Bash which support plugins in multiple languages and/or have other means to specify the interpreter.
For example, pip
can be invoked as python3 -m pip
.
This allows users to accurately specify the Python version used to run the software. This convention works across different environments that might not always set $PATH
or install scripts consistently.
Using Cython
Tightening the general Fedora policy, packages MUST NOT use files pre-generated by Cython. These MUST be deleted in %prep
and regenerated during the build.
As an exception, these sources MAY be used temporarily to prevent build time circular dependencies by following the bootstrapping guidelines.
Generated files (the ones that must be deleted) have a generic .c
or .cpp
extension. Cython source files (which should stay) usually have the .pyx
or .pxd
extension.
Cython is a popular tool for writing extension modules for Python. If compiles a Python-like language to C, which is then fed to the C compiler. Historically, Cython was hard to use upstream as a build-time dependency. Many projects include pre-generated C files in source distributions to avoid users from needing to install the tool.
Cython uses CPython’s fast-changing internal API for performance reasons. For a new release of Python, Cython generally needs to be updated and the C files regenerated. In Fedora, this is frequently needed before upstreams release re-generated sources (e.g. for Alpha versins of Python). Since we do not have a problem with build-time dependencies, we always want to run the Cython step.
For example, PyYAML
removes a generated C file with:
rm -rf ext/_yaml.c
For another example, in python-lxml
all C files are generated with Cython, which allows removing them with:
# Remove pregenerated Cython C sources
find -type f -name '*.c' -print -delete
Some upstreams mix generated and hand-written C files. In such cases a grep like this one from scipy
helps (but might not be entirely future proof):
# Remove pregenerated Cython C sources
rm $(grep -rl '/\* Generated by Cython')
Tests
Running tests
If a test suite exists upstream, it SHOULD be run in the %check
section. If that is not possible with reasonable effort, at least a basic smoke test (such as importing the packaged module) MUST be run in %check
.
You MAY exclude specific failing tests. You MUST NOT disable the entire testsuite or ignore its result to solve a build failure.
As an exception, you MAY disable tests with an appropriate %if
conditional (e.g. bcond) when bootstrapping.
Most errors in Python happen at run-time, so tests are extremely important to root out issues, especially when mass rebuilds are required.
Common reasons for skipping tests in %check
include requiring network access, dependencies not packaged in Fedora, and/or specialized hardware or resources.
In these cases, you can use the %pyproject_check_import
or the %py3_check_import
macro to test that installed modules are importable.
Tox
A popular testing tool, and one which is well integrated in Fedora, is tox
. Upstream, it is commonly used to test against multiple Python versions. In a Fedora package, BuildRequire test dependencies via %pyproject_buildrequires -t
or -e
(see Test dependencies below) and run tox
with:
%tox
This sets up the environment ($PATH
, $PYTHONPATH
, $TOX_TESTENV_PASSENV
) and instructs tox
to use the current environment rather than create new ones. For more options, see Build macros.
pytest
When upstream doesn’t use tox
, the tests need to be run directly depending on upstream choice of a test runner. A popular runner is pytest
, which can be invoked using %pytest
.
Use positional arguments to specify the test directory. See python3 -m pytest --help
for how to select tests. For example, if network-related tests are marked “network”, you might use -m
to deselect them:
%pytest -m "not network"
The %pytest
macro sets several environment variables appropriate for %check
:
-
Locations in the buildroot are added to
$PATH
and$PYTHONPATH
. -
$PYTHONDONTWRITEBYTECODE
is set to avoid writing pytest-specific cache files to buildroot -
$PYTEST_XDIST_AUTO_NUM_WORKERS
is set to%{_smp_build_ncpus}
-
If unset,
$CFLAGS
and$LDFLAGS
are set to match the build flags
Other test runners
If upstream doesn’t use tox
or pytest
, other test runners can be invoked with the %{py3_test_envvars}
macro, available since Fedora Linux 38.
This macro sets several environment variables similarly to %pytest
, but requires the actual test runner to be invoked after the macro, for example:
%{py3_test_envvars} %{python3} -m unittest
Or:
%{py3_test_envvars} %{python3} tests/run_tests.py
Test dependencies
One part of the Python packaging ecosystem that is still not standardized is specifying test dependencies (and development dependencies in general).
A good, common way for upstreams to specify test dependencies is using an extra like [test]
, [testing]
or [dev]
. In this case, upstream’s instructions to install test dependencies might look like $ pip install -e.[test]
.
Another way to specify test dependencies is using a dedicated dependency group (PEP 735).
Projects using tox
usually specify test dependencies in a tox
-specific format: a requires key in the configuration.
These three forms are handled by the %pyproject_buildrequires
macro.
If upstream does not use either form, list test dependencies as manual BuildRequires in the spec
file, for example:
# Test dependencies:
BuildRequires: python3dist(pytest)
If you need to do this, consider asking upstream to add a [test]
extra or a test
dependency group.
Linters
In %check
, packages SHOULD NOT run “linters”: code style checkers, test coverage checkers and other tools that check code quality rather than functionality.
Tools like black
, pylint
, flake8
, or mypy
are often “opinionated” and their “opinions” change frequently enough that they are nuisance in Fedora, where the linter is not pinned to an exact version. Furthermore, some of these tools take a long time to adapt to new Python versions, preventing early testing with Alpha and Beta releases of Python. And they are just not needed: wrongly formatted code is not important enough for the Fedora packager to bug the upstream about it. Making such an issue break a package build is entirely unreasonable.
Linters do make sense in upstream CI. But not in Fedora.
If a linter is used, disable it and remove the dependency on it. If that is not easy, talk to upstream about making it easy (for example with a configuration option or a separate tox
environment).
For packages that contain such linters, use them at runtime or extend them, you will usually need to run the linter in %check
. Run it to test functionality, not code quality of the packaged software.
Source files from PyPI
Packages MAY use sources from PyPI.
However, packages SHOULD NOT use an archive that omits test suites, licenses and/or documentation present in other source archives.
For example, as of this writing pip
provides a source tarball (“sdist”) which omits the relatively large tests
and docs
directories present in the source on GitHub. In this case, the tarball from GitHub should be used. (See the Git tags section of Fedora SourceURL guidelines.)
When using sources from PyPI, you can use the the %pypi_source
macro to generate the proper URL.
Some Python packages use metadata from git (or a similar version control system) to construct their version string, for example via setuptools_scm. When publishing a package to PyPI, this version metadata is usually stored and included in a file, so the version control history is no longer needed to construct it. However, when using tarballs from a git forge directly, this version information is missing and must be manually provided by the packager. For example, the SETUPTOOLS_SCM_PRETEND_VERSION environment variable can be set to the desired value in the %generate_buildrequires and %build scripts in the spec file for packages that use setuptools_scm for this purpose.
|
Example spec file
The following is a viable spec file for a Python library called Pello
that follows packaging best practices.
Note that the project name Pello
normalizes to the lowercase pello
. The example spec shows where each variant is typically used.
The project has an extra color
, which enables colorized output when installed. Since the required dependency is quite minimal and color improves the user experience, the extra is Recommended from the main package.
Name: python-pello
Version: 1.0.4
Release: 1%{?dist}
Summary: Example Python library
License: MIT-0
URL: https://github.com/fedora-python/Pello
Source: %{url}/archive/v%{version}/Pello-%{version}.tar.gz
BuildArch: noarch
BuildRequires: python3-devel
%global _description %{expand:
A python module which provides a convenient example.
This description provides some details.}
%description %_description
%package -n python3-pello
Summary: %{summary}
Recommends: python3-pello+color
%description -n python3-pello %_description
%pyproject_extras_subpkg -n python3-pello color
%prep
%autosetup -p1 -n Pello-%{version}
%generate_buildrequires
%pyproject_buildrequires -t
%build
%pyproject_wheel
%install
%pyproject_install
# Here, "pello" is the name of the importable module.
%pyproject_save_files -l pello
%check
%tox
# Note that there is no %%files section for
# the unversioned python module, python-pello.
# For python3-pello, %%{pyproject_files} handles code files and %%license,
# but executables and documentation must be listed in the spec file:
%files -n python3-pello -f %{pyproject_files}
%doc README.md
%{_bindir}/pello_greeting
%changelog
Empty spec file
The following is an unfinished spec file template to copy, paste and edit.
Name: python-...
Version: ...
Release: 0%{?dist}
Summary: ...
License: ...
URL: https://...
Source: %{url}/archive/v%{version}/...-%{version}.tar.gz / %{pypi_source ...}
BuildArch: noarch / BuildRequires: gcc
BuildRequires: python3-devel
%global _description %{expand:
...}
%description %_description
%package -n python3-...
Summary: %{summary}
%description -n python3-... %_description
%prep
%autosetup -p1 -n ...-%{version}
%generate_buildrequires
%pyproject_buildrequires -x... / -g... / -t
%build
%pyproject_wheel
%install
%pyproject_install
%pyproject_save_files ...
%check
%tox / %pytest / %pyproject_check_import ...
%files -n python3-... -f %{pyproject_files}
%doc README.*
%{_bindir}/...
%changelog
Macro Reference
This section documents macros that are available to help with Python packaging. The expansions in parentheses are provided only as reference/examples.
See the [Mandatory macros] section above for:
-
%{python3}
(/usr/bin/python3
) -
%{python3_version}
(e.g.3.9
) -
%{python3_version_nodots}
(e.g.39
) -
%{python3_sitelib}
(e.g./usr/lib/python3.9/site-packages
) -
%{python3_sitearch}
(e.g./usr/lib64/python3.9/site-packages
)
Shebang macros
-
%{py3_shebang_flags}
(sP
ors
before Fedora Linux 37)Flags for
%{python3}
to use in shebangs. See Shebangs for details. Includes flags from several%{_py3_shebang_...}
macros listed here.
-
%{_py3_shebang_s}
(s
)Undefine this macro to drop
s
from%{py3_shebang_flags}
.
-
%{_py3_shebang_P}
(P
)Undefine this macro to drop
P
from%{py3_shebang_flags}
. Introduced in Fedora Linux 37.
-
%py3_shebang_fix PATHS
(pathfix.py ... PATHS
)A macro to fix shebangs in specified
PATHS
. Only shebangs that already havepython
in them are changed. If a directory is given, all.py
files in it are fixed, recursively. (So, if you need to fix shebangs in files not named*.py
, you need to list each file separately or use a Shell glob, such as%{buildroot}%{_libexecdir}/mytool/*
.) Existing flags are preserved and%{py3_shebang_flags}
are added.For example,
#! /usr/bin/env python
will be changed to#! /usr/bin/python3 -s
and#! /usr/bin/python -u
will be changed to#! /usr/bin/python3 -su
.This macro is called automatically by
%pyproject_install
on%{buildroot}%{_bindir}/*
.
Convenience macros
-
%{pypi_source PROJECTNAME [VERSION [EXT]]}
(e.g.https://.../Django-3.0.5.tar.gz
)Evaluates to the appropriate URL for source archive hosted on PyPI. Accepts the project name and up to two optional arguments:
-
The version of the PyPI project. Defaults to
%version
(the package version) with any~
removed. -
The file extension to use. Defaults to
tar.gz
.
In most cases it is not necessary to specify those two arguments.
For backward compatibility, the first argument is technically optional as well, but omitting it is deprecated. (It defaults to
%srcname
if defined, or to%pypi_name
if defined, or to%name
.) -
-
%{python3_platform}
(e.g.linux-x86_64
)The platform name. Used in some Python build systems. This corresponds to
sysconfig.get_platform()
.
-
%{python3_ext_suffix}
(e.g..cpython-39-x86_64-linux-gnu.so
)Filename extension for Python extension modules. This corresponds to the
EXT_SUFFIX
sysconfig variable.
-
%{python3_platform_triplet}
(e.g.x86_64-linux-gnu
)A string identifying the architecture/platform. This corresponds to the
MULTIARCH
sysconfig variable.
-
%{python3_cache_tag}
(e.g.cpython-311
)Part of the bytecode cache filename that identifies the interpreter. This corresponds to the
sys.implementation.cache_tag
value.
Build macros
The “pyproject macros” are most useful for packaging Python projects that use the pyproject.toml
file defined in PEP 518 and PEP 517, which specifies the package’s build dependencies (including the build system, such as setuptools
, flit
or poetry
).
If pyproject.toml
is not found, the macros automatically fall backs to using setuptools
with configuration in setup.cfg
/setup.py
.
A full tutorial and discussion for the macros is available in the macros’ README.
-
%pyproject_buildrequires
Generate BuildRequires for the package. Used in the
%generate_buildrequires
section of thespec
file. The macro has these options:-
-R
: Don’t include run-time requirements (e.g. if the build backend does not support this). -
-r
: Include run-time requirements (this flag is not needed and exists for backward-compatibility reasons only, run-time requirements are included by default). -
-x EXTRA
: Include dependencies given by the given extra. Cannot be used with-R
. -
-g GROUP
: Include dependencies specified in the given dependency group (PEP 735). -
-p
: Read run-time dependencies from pyproject.toml [project] table. This reads also the [optional-dependencies] for the given extra. Cannot be used with-R
. -
-t
: Include dependencies for the default tox environment. Cannot be used with-R
. -
-e ENV
: Include dependencies for the given tox environment, and save theENV
name as%{toxenv}
. Cannot be used with-R
. Multiple comma separated values can be given, for example:%pyproject_buildrequires -e %{toxenv}-unit,%{toxenv}-integration
-
-
%pyproject_wheel
Build the package. Commonly, this is the only macro needed in the
%build
section.This macro needs BuildRequires generated by
%pyproject_buildrequires
.
-
%pyproject_install
Install the package built by
%pyproject_wheel
. Calls%py3_shebang_fix %{_buildroot}%{_bindir}/*
.This macro needs BuildRequires generated by
%pyproject_buildrequires
.
-
%pyproject_save_files MODNAME …
Generate a list of files corresponding to the given importable module(s) and save it as
%{pyproject_files}
.Note that README file is not included. The LICENSE file is included when it is specified in the metadata. Also, while the macro allows including executable and other files (using the
+auto
flag), this feature MUST NOT be used in Fedora.The
MODNAME
may be a glob pattern, which should be specific to your package. To prevent Shell from expanding the globs, put them in''
, e.g.%pyproject_save_files '*pytest'
. As mentioned in the [Explicit lists] section, expressions like%pyproject_save_files '*'
are not acceptable.The macro has these options:
-
-l
: Declare that a missing license should terminate the build. Packagers are encouraged to use this flag when the%license file
is not manually listed in%files
to avoid accidentally losing the file in a future version. -
-L
: Explicitly disable the check for a missing license file. When the%license
file is manually listed in%files
, packagers can use this flag to ensure future compatibility in case the-l
behavior eventually becomes a default.
-
-
%{pyproject_files}
Path of the file written by
%pyproject_save_files
, to be used as:%files -n python3-DISTNAME -f %{pyproject_files}
Test macros
-
%tox
Run tests using
tox
.This macro needs BuildRequires generated by the
-t
or-e
option of the%pyproject_buildrequires
macro.Different environments may be specified with
-e
, for example:%check %tox %{?with_integration_tests:-e %{toxenv},%{toxenv}-integration}
Flags for the
tox
command can be specified after--
:%tox -- --parallel 0
Additional arguments for the test runner may be specified after another
--
:%tox -- --parallel 0 -- --verbose tests/*
-
%{toxenv}
The tox environment(s) used by the
%tox
macro. Multiple environments are separated by commas. Can be overridden manually or with%pyproject_buildrequires -t ENV1,ENV2
.
-
%{default_toxenv}
(e.g.py39
)The system-wide default value of
%{toxenv}
.
-
%pytest
Run
%__pytest
with environment variables appropriate for tests in%check
. See Running tests for details.
-
%__pytest
(/usr/bin/pytest
)The command that
%pytest
uses. May be redefined.
-
%py3_test_envvars
(PATH=... PYTHONPATH=... PYTHONDONTWRITEBYTECODE=1 ...
)The environment variables used by
%pytest
and%tox
. It may be used to invoke custom test runners in%check
. See Other test runners for details. Introduced in Fedora Linux 38.
-
%py3_check_import
Imports all provided modules. If running an upstream test suite is not feasible, use this macro in
%check
to test that public Python modules are importable.Takes these arguments:
-
-f
: path to file containing qualified module names (separated by newlines). Optional, can be used multiple times. -
-e
: glob to exclude the matching module names. Optional, can be used multiple times. -
-t
: if set, import only top-level module names -
Positional arguments (separated by spaces or commas) specify the module name(s) to check.
The macro sets various environment variables such as
PATH
andPYTHONPATH
to ensure the packaged versions of modules are imported. -
-
%pyproject_check_import
Imports all public modules found by the
%pyproject_save_files
macro whose names match any of the providedMODNAME
globs.This macro needs to be used with
%pyproject_save_files
(use%py3_check_import
in other cases).The macro takes
-e
/-t
as well as positional arguments for%py3_check_import
above.
Extras macros
-
%pyproject_extras_subpkg
Generates a simple subpackage for a Python extra. See Extras for more information.
This macro needs to be used with
%pyproject_install
(use%python_extras_subpkg
in other cases).Required arguments:
-
-n
: name of the “base” package (e.g.python3-requests
) -
Positional arguments (separated by spaces or commas): the extra name(s). Multiple metapackages are generated when multiple names are provided.
The macro also takes
-i
/-f
/-F
arguments for%python_extras_subpkg
below, but if they are not given, a filelist written by%pyproject_install
is used.Similarly, the
-a
/-A
flags are passed to%python_extras_subpkg
.This macro generates all the subpackage definition sections (
%package
including theSummary
andRequires
on the base package,%description
and, by default,%files
). Hence, it cannot be extended with custom Provides/Obsoletes/Requires/etc. This macro is designed to fit only the most common uses. For more complicated uses, construct the subpackage manually as shown in the Extras section.The
%files
section is last. It can be continued to add files that only make sense with the extra and the base package does not fail without them. For example, the following macro will package the extracli
for the projecta-cool-tool
and include ana-cool-tool
command:%pyproject_extras_subpkg -n a-cool-tool cli %{_bindir}/a-cool-tool
Due to technical limitations, the macro never generates requirements on the arched
BASE_PACKAGE%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
. It only addsRequires: BASE_PACKAGE = %{?epoch:%{epoch}:}%{version}-%{release})
because a macro cannot reliably detect if the subpackage is arched or not. So far, this has not been a problem in practice. -
-
%python_extras_subpkg
Generates a simple subpackage for a Python extra. See Extras for more information. Takes these arguments:
-
-n
: name of the “base” package (e.g.python3-requests
) -
-i
: the%files %ghost
path (glob) to the.dist-info
directory -
Positional arguments (separated by spaces or commas) specify the extra name(s) — multiple metapackages are generated when multiple names are provided.
-
-f
: Relative path to the filelist for this metapackage (which should contain the%files %ghost
path (glob) to the the metadata directory). Conflicts with-i
and-F
. -
-F
: Skip the %files section entirely (if the packager wants to construct it manually). Conflicts with-i
and-f
. -
-a
: IncludeBuildArch: noarch
in the package definition, to be used only when the package is archful, but the “base” package passed to-n
is not. -
-A
: Explicitly disables-a
(does nothing at the moment).
As with
%pyproject_extras_subpkg
:-
This macro generates all the subpackage definition sections, with only
%files
being customizable. For more complicated uses, construct the subpackage manually as shown in the Extras section. -
It never generates requirements on the arched
BASE_PACKAGE%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
.
-
Manual generation
The following macros are available for cases where automatic generation is turned off. They can also be useful for handling files in non-standard locations where the generators don’t look.
-
%pycached MODNAME.py
Given a Python file, lists the file and the files with its bytecode cache. See Source files and bytecode cache for more information.
-
%py_provides python3-MODNAME
Generates
Provides
forpython3-MODNAME
,python3.X-MODNAME
andpython-MODNAME
. See Provides automático para python- e python3.X- for more details.
-
%py_byte_compile INTERPRETER PATH
Byte-compile a Python file into a
__pycache__/*.pyc
.If the
PATH
argument is a directory, the macro will recursively byte compile all*.py
files in the directory. (So, if you need to compile files not named*.py
, you need to use the macro on each file separately.)The
INTERPRETER
determines the compiled file name’s suffix and the magic number embedded in the file. These muct match the interpreter that will import the file. Usually, theINTERPRETER
should be set to%{python3}
. If you are compiling for a non-default interpreter, use that interpreter instead and add aBuildRequires
line for it.
-
%{py_dist_name PROJECTNAME}
Given a project name (e.g.
PyYAML
) it will convert it to the canonical format (e.g.pyyaml
). See [Canonical project name] for more information.
-
%{py3_dist PROJECTNAME …}
Given one or more project names, it will convert them to the canonical format and evaluate to
python3dist(DISTNAME)
, which is useful when listing dependencies. See Provides legível por máquina for more information.
Configurações do sistema
The following macros can be redefined for special use cases.
-
%{__python}
(errors by default if not redefined)Defining this macro sets the meaning of all “unversioned” Python macros such as
%{python}
or%{python_sitelib}
. Don’t use these macros without redefining%{__python}
.
-
%{__python3}
(/usr/bin/python3
)The python 3 interpreter. Redefining this macro changes all the
%{python3...}
macros, e.g.%{python3}
or%{python3_sitelib}
.
-
%{python3_pkgversion}
(3
)Distro-wide Python version, i.e. the
3
inpython3
. Projects that build on top of Fedora might define it to e.g.3.9
to try allowing multiple Python stacks installable in parallel. Packages in Fedora MAY use it (e.g. in package names:python%{python3_pkgversion}-requests
), but MUST NOT redefine it.
Comparing Python versions
When comparing Python versions (e.g. to ask: is %{python3_version}
greater than 3.8?), using naïve %if %{python3_version} > 3.8
or %if "%{python3_version}" > "3.8"
is not possible, because the comparison is performed alphabetically on strings. Hence it is true that "3.10" < "3.8"
(which is not desired).
It is possible to explicitly compare version literals by using the v
prefix, similar to the Python string prefixes:
%if v"0%{?python3_version}" > v"3.8"
...
%endif
As a workaround for compatibility with RPM releases up to 4.16 (EPEL 9),
This will work with Python 3.10 (310 > 39), but eventually break with Python 4.0 (40 < 310). |
Disabling automation
The following macros can turn off Python-specific automation.
Consider contacting the Python SIG if you need to do this.
-
%{?python_disable_dependency_generator}
Disables the automatic dependency generator. See Dependências geradas automaticamente for details.
-
%undefine __pythonname_provides
Disables automatic generation of unversioned/versioned provides for package names, e.g.
python-FOO
andpython3.9-FOO
forpython3-foo
. See Provides automático para python- e python3.X- for more details.
-
%undefine __pythondist_provides
Disables automatic generation of machine-readable Provides, e.g.
python3dist(foo)
. See Provides legível por máquina for more details.
-
%global _python_no_extras_requires 1
If defined, Automatic Requires for extras will not be generated.
-
%global _python_dist_allow_version_zero 1
From Fedora Linux 38 on, it is no longer possible to build a Python package with version 0 to prevent an accidental loss of the actual version information. If defined, the macro will allow to build such package.
Deprecated Macros
The following macros are deprecated. See the 201x-era Python Packaging guidelines for how some of them were used.
Want to help? Learn how to contribute to Fedora Docs ›