This page permanently redirects to gemini://gronkiewicz.dev/python-tooling/.

Środowisko w Pythonie to nieład — jak staram się go okiełznać?

2023-08-08 Patryk Gronkiewicz

W tym wpisiue po dłuższej przerwie chciałbym wam przedstawić jak sam pracuję z projektami w Pythonie. Oczywiście setup czasem się trochę różni, ale "główna" część pozostaje zawsze taka sama.

Zarządzanie zależnościami (i nie tylko...)

Pierwszą rzeczą, która stanowi trzon mojego workflow jest asdf[1]. Co do zasady nie lubię korzystać z condy, bo zajmuje ona niebotyczne ilości miejsca na dysku (w tym miejscu chciałbym pozdrowić Piotrka[2]), który stosunkowo niedawno usuwał ponad 100 GB środowisk). asdf pozwala na używanie ponownie tych samych instalacji Pythona, ale nie tylko --- możemy dzięki niemu wymusić wersje różnych innych programów jak Elixir, Erlang, Nim, Zig, czy nawet mc będący klientem Min.io.

W ten sposób oszczędzam sporo przestrzeni, którą można spożytkować na dalszą część konfiguracji ;).

=> [1] Strona główna asdf | [2] Profil Piotrka na GitHubie

Następnym elementem, który już stricte zarządza zależnościami jest Poetry --- mam świadomość, że ma swoje problemy, wiele osób go nie lubi i nie trzyma się (jeszcze) PEP-621, ale hej --- jeszcze nie spotkałem przyjemniejszego narzędzia do opanowania zależności w Pythonie. Pozwala nam na zdefiniowanie "twardych" zależności, deweloperskich, testowych i jakie tylko sobie wymyślicie, dzięki konfiguracji grup zależności. Często używam tej funkcji do zdefiniowania paczek, które służą do lintingu, formatowania i testów, o czym za chwilę. Każda z tych grup nie jest koniecznie potrzebna "na produkcji", więc jest u mnie oznaczona jako opcjonalna i trzeba jasno i klarownie powiedzieć Poetry, że chcemy je u siebie. Ma to dodatkowy plus w postaci trochę mniejszych obrazków OCI (czy jak ktoś, niepoprawnie, woli --- Dockera).

Formatowanie kodu

Parafrazując Henry'ego Forda

Możesz dowolnie formatować swój kod w Pythonie, pod warunkiem, że będzie sformatowany Blackiem.

Tej maksymy trzymam się z całych sił, mimo, że kilka osób próbowało mi wmówić, że nie jest to dobra opcja. Moim zdaniem styl formatowania, który jest uniwersalny między wieloma repozytoriami, nie zależy w zupełności od jakichkolwiek konfiguracji jest dobry z jednego względu --- jest przewidywalny.

Linting

Z linterami mam dość krótką historię, ale staram się ich używać jak najczęściej. Ostatnio na fali "blazing fast" zacząłem korzystać z ruff[3]. Nawet nie ze względu na to, że jest szybki (co niewątpliwie jest na plus w przypadku pipeline CI, gdzie każda sekunda kosztuje), a ze względu na to, że dobrze integruje wiele zasad z różnych silników pod jedną prostą komendą. Jeszcze się na nim nie zawiodłem, ale służy mi dopiero w jednym projekcie.

Alternatywnym projektem, z którego korzystałem wcześniej jest pylint --- nie jest tak szybki, nie "krzyczy" w tak wielu momentach, ale działa i pilnuje największych głupot.

=> [3] Dokumentacja Ruffa

Testy

Jest to jeden z elementów na temat których nie mam bardzo silnej opinii --- zwykle pada na wybór pytest, jednak kusząca jest wizja testów przez dowody, którą oferuje hypothesis[4]. Pewnie znalazłoby się kilka alternatyw jak unittest w bibliotece standardowej, jednak nie miałem potrzeby z niego korzystać. Zwykle takżde nie używam tox, nox ani żadnych im podobnych ze względu na brak potrzeby.

=> [4] Kod paczki hypothesis

Typowanie

Sprawdzanie typów u mnie bardziej wynika z edytora, którego używam, niż wyboru narzędzia --- w Emacsie mam skonfigurowanego Pyrighta od Microsoftu w trybie "strict", aby na każdy problem z typami zwracał uwagę. Pomaga to też w lepszym autouzupełnianiu przez LSP, więc tutaj są same plusy.

Jeśli nie Pyright, to używałbym mypy.

Zmienne środowiskowe

Jest to dość krótki temat, jednak zadziwiająco przydatny. Aktualnie w pracy piszemy aplikację, która jest konfigurowana na podstawie zmiennych środowiskowych, co może być problematyczne, gdy musimy wielokrotnie eksportować różne wartości w wielu terminalach i łatwo się w nich zgubić.

Tu z pomocą przychodzi direnv[5], zazwyczaj ustawiony z pomocą asdf. Wystarczy pozwolić mu działać w danym katalogu i już możemy się cieszyć stałą konfiguracją naszych zmiennych między terminalami. Oczywiście nic nie przeszkadza nam w nadpisaniu zmiennej tymczasowo, jednak w przypadku edycji zmiennej w pliku .envrc, który służy do konfiguracji direnv właśnie, musimy ponownie pozwolić na załadowanie tego pliku. Jest to zabezpieczenie przed zdalną zmianą i wprowadzeniu dziwnych wartości do naszego terminala, np. przez kolegę, który pracował na innym branchu, a my na niego weszliśmy.

=> [5] Strona główna direnv

Proxy Information
Original URL
gemini://gronkiewicz.dev/python-tooling
Status Code
Success (20)
Meta
text/gemini
Capsule Response Time
338.814602 milliseconds
Gemini-to-HTML Time
0.744918 milliseconds

This content has been proxied by September (ba2dc).