Un traceback aparece cando se inicia un comando de xestión de VPN, e o primeiro impulso é instalar outro Python ou apuntar o valor predeterminado do sistema a outro sitio. Ese impulso mestura dous contornos de execución que non teñen nada que ver entre si. Un pertence ao sistema operativo e ás súas ferramentas empaquetadas; o outro pertence a calquera proxecto que estea a construír. Cambiar o primeiro para satisfacer o segundo é como un escritorio que funciona perde o seu xestor de paquetes.

A comparación que paga a pena facer é entre o compoñente que realmente fallou e o contorno de execución que ten dereito a cambiar. Case nunca son o mesmo obxecto.

Dúas preguntas sobre Python que parecen unha

A primeira pregunta é: que intérprete executou o programa que imprimiu o traceback? A segunda é: que intérprete debería usar o meu proxecto? Parecen idénticas nunha terminal porque a ambas se responde escribindo python3, e teñen propietarios distintos, camiños de actualización distintos e radios de impacto distintos.

Unha ferramenta do sistema está ligada ao intérprete co que se distribúe a súa distribución, xunto cos módulos compilados construídos contra a ABI dese intérprete. Un proxecto está ligado ao contorno que cree para el. Mover o valor predeterminado do sistema cambia o primeiro para todas as ferramentas da máquina á vez; crear un contorno cambia o segundo para un directorio.

Só unha desas accións é reversible nun minuto. Non é a primeira.

Que compoñente produciu o erro

Lea a primeira liña do traceback e o executábel que o produciu antes de ler calquera outra cousa. O frontend de liña de ordes, o servizo privilexiado e as ligazóns da API son pezas separadas, e só algunhas delas son Python.

command -v openvpn3
head -n 1 "$(command -v openvpn3)"
dpkg -S "$(command -v openvpn3)" 2>/dev/null
systemctl status openvpn3-service-client --no-pager

A primeira liña dun script nomea o intérprete que usará, e é o intérprete do que veu o traceback. A consulta do paquete dille quen posúe o ficheiro, o que decide quen pode cambialo. O estado do servizo responde unha pregunta completamente distinta: se se está executando o backend privilexiado que realmente establece sesións.

Un erro de importación de módulo, un rexeitamento de activación de D-Bus e unha credencial rexeitada son tres etapas distintas. Un erro de importación ocorre antes de que exista sesión algunha, así que ningunha configuración de VPN o arranxará, e un servizo que funcione tampouco o arranxará. Clasificar a mensaxe nunha desas tres etapas é o primeiro paso real.

Que pode arranxar un contorno de proxecto e que non

Un contorno de proxecto resolve un problema de proxecto: as versións exactas das bibliotecas que necesita unha aplicación, illadas de todo o demais. Iso é realmente útil, e é a ferramenta correcta cando o programa que falla é un script seu.

uv run --python 3.11 app.py
python3 -c 'import openvpn3; print(openvpn3.__file__)'

O segundo comando mostra que copia das ligazóns pode ver un intérprete dado, que é a forma máis rápida de distinguir un paquete ausente dun ensombrecido. Execúteo co intérprete que usa o script que falla, non con outro que funcione por casualidade.

O que un contorno de proxecto non pode facer é reparar un frontend empaquetado pola distribución. As dependencias dese programa construíronse para o intérprete que escolleu o xestor de paquetes, e executalo dentro do contorno do seu proxecto ou ben falla ou ben produce unha mestura que ninguén admite. Inxectarlle camiños cunha variable de contorno é o mesmo erro con pasos extra: cambiou o que a ferramenta carga sen cambiar aquilo contra o que se probou. Ese intercambio parece unha solución exactamente ata que chega a seguinte importación.

Por que redirixir o intérprete do sistema é unha trampa

Cambiar o intérprete predeterminado é atractivo porque parece arranxar o traceback cun só comando. Tamén rompe a suposición sobre a que se construíu cada ferramenta de Python empaquetada do equipo, e as fallas aparecen máis tarde e en lugares sen relación.

Os mecanismos de selección de alternativas deseñáronse para cambiar entre implementacións equivalentes, non para instalar unha linguaxe máis nova baixo módulos compilados máis antigos. As extensións compiladas constrúense para unha ABI concreta, así que un módulo que se importaba onte pode non cargarse hoxe sen que se eliminase un só paquete.

Tamén hai unha trampa de nome no consello que atopa a xente. O comando python sen versión non ten un significado universal entre distribucións e contornos, e tratalo como sinónimo fixo dunha versión principal concreta produce correccións que só funcionan na máquina onde se escribiron. Lea a política do sistema que ten diante, non a do artigo do blog.

Probas de aceptación separadas

Ao final deben ir dúas probas, e pasar unha non di nada da outra. A primeira é que o comando de cliente admitido funciona co intérprete para o que se empaquetou. A segunda é que o servizo privilexiado establece unha sesión e o túnel transporta tráfico.

openvpn3 sessions-list
openvpn3-service-client --help 2>/dev/null | head -n 3
ip -4 addr show tun0

Manteña unha vía independente cara á máquina mentres traballa, sobre todo se a VPN leva o seu único acceso administrativo. Un cambio no intérprete do sistema é xusto o tipo de edición que pode quitar ese acceso a metade de camiño.

Se a falla é un módulo ausente para unha ferramenta do sistema, a corrección é unha operación de paquete a través do fluxo de traballo admitido. Se a falla é un conflito de versións no seu propio proxecto, a corrección é un contorno. Escoller entre eses dous é toda a decisión, e decídea que programa imprimiu o traceback.

Artigos relacionados