Попробовал затащить к себе плагины. Что-то даже нашли. Поживу с ними посмотрю как будет работать.
В документации к flake8-commas==2.1.0 рекомендуют использовать black вместо него.
flake8-annotations-coverage==0.0.6 и flake8-annotations==2.9.1 конфликтуют. Первый плагин считает покрытие и не имеет настроек, а второй требует 100% для включённых опций. В flake8-annotations у меня отключена часть требований: ANN101 Missing type annotation for self in method ANN204 Missing return type annotation for special method Поэтому в flake8-annotations-coverage для себя не вижу смысла.
Я flake8 через pre-commit запускаю, поэтому не опубликованные в pip плагины не захотели работать, например git+https://github.com/c0ntribut0r/flake8-grug
У меня сразу в голове возникают вопросы - а что именно скрывается за этими "_" - и будьте уверены, я пойду ковырять этот get_many_params в попытке это понять.
А для других это возможность срезать и не читать лишние переменные.
Спасибо за статью, у меня похожий шаблон для flake8, обогащу его вашими находками.
Я использую совместно с black, это автоматом исключает многие ворнинги.
Сложные аннотации типов можно вынести в переменную. Часто вместо типа Generator можно указать Iterator так проще. Когда я хочу подчеркнуть, что dict который я возвращаю менять не надо, я использую аннотацию Mapping
Когнитивную сложность у себя я отключил. Цикломатическая и когнитивная на маленьких цифрах очень похожа, а так плагином меньше.
Они, наверно, супермены и всегда помнят, что надо закрывать файлы?
Если быть педантом, то нужно еще через try-finally
Для настраеваемых функций часто использую класс с __call__ . Его потом легко подменять в тестах.
Я почти не сомневаюсь, что вы сделали глупость, упустив того потенциального коллегу, который показал вам широту взглядов и умений вместо того, чтобы закапываться в очевидные для него вещи.
Но, на практике я вижу код, которые уже давно перестал быть линейным. Переменные объявяютя в одной части кода, а используются на 100 строк ниже, да и еще пару раз переопределяются.
Если не включать голову и так и так будет плохо. Но такой код можно быстро заинлайнить, а вот монолит на 300 строк разнести намного сложнее.
и разделенная на блоки комментариями
Вот тут и место для разделения, комментарий в название документацию метода, блок в тело.
А в выскоконагруженных задачах, где борешься за каждую ms так еще эти вызовы влияют на скорость.
Давайте говорить честно, такие задачи существуют, но они достаточно редки и их не поручают джунам. Джава машина кажется такие вещи может инлайнить сама.
Первый вариант который рекомендует pytest, мне привычнее, и кажется проще для разработки. Я локально гоняю только юниты, а всякие инсталляции можно сбросить на CI.
Вторая статья еще использует setup.py, но с тех пор появились новые инструменты например flit и poetry. Надо посмотреть, как они с такими структурами работают.
Компонентные тесты дороже в разработке и поддержке, чем интеграционные, т.к. требуют больше времени и большей внимательности к мелочам. И сложнее в отладке.
А что вы вкладываете в понятие интеграционные тесты? Почему они легче в отладке чем компонентные?
Имя src мне не нравится, это что-то техническое. Я предпочитаю использовать название проекта. То есть вместо src/gmaps_crawler/ просто gmaps_crawler/.
Есть еще и личная неприязнь к этому имени в контексте Питона, src ассоциируется с Джавой. Я пишу и на Питоне и на Джаве, но попытки притащить парадигмы из одного языка в другой мне не нравятся.
Двойное подчёркивание в имени локальной переменной несколько перебор. def __init__(self, db_image_name):
__engine = EngineFactory()
__engine.stand = 'localhost'
Синглтон тоже можно выкинуть, так как тесты это реализуют самостоятельно.
Комментарии дублируют код. Даже для обучающего кода это излишне.
# Тест метода processing.bookings.get_premium_psg_list()
# В текущих тестовых данных, для limit=10000, корректный результат == 4
def test_get_premium_psg_list(test_db):
assert len(get_premium_psg_list(limit=10000)) == 4
После выполнения всех тестов, testcontainers завершит работу созданного контейнера и удалит созданные данные. Бывает полезно "придержать" тестовую БД на некоторое время, чтобы можно было залезть в БД из обычной IDE, чтобы выполнить пару-тройку SQL-запросов. Для этого нужно просто раскомментировать тест test_debug(test_db)
Это считается помещающейся в 80 символов?
Попробовал затащить к себе плагины. Что-то даже нашли. Поживу с ними посмотрю как будет работать.
В документации к
flake8-commas==2.1.0
рекомендуют использовать black вместо него.flake8-annotations-coverage==0.0.6
иflake8-annotations==2.9.1
конфликтуют. Первый плагин считает покрытие и не имеет настроек, а второй требует 100% для включённых опций. Вflake8-annotations
у меня отключена часть требований:ANN101 Missing type annotation for self in method
ANN204 Missing return type annotation for special method
Поэтому в
flake8-annotations-coverage
для себя не вижу смысла.Я flake8 через pre-commit запускаю, поэтому не опубликованные в pip плагины не захотели работать, например
git+https://github.com/c0ntribut0r/flake8-grug
А для других это возможность срезать и не читать лишние переменные.
Go вообще запрещает объявлять неиспользуемые переменные на уровне компилятора. Но есть один способ обойти это https://go.dev/doc/effective_go#blank
Еще при чтении кода помогают.
Очень неплохое видео про оптимизации производительности Питона, про слоты там тоже есть.
https://www.youtube.com/watch?v=Ix04KpZiUA8
Спасибо за статью, у меня похожий шаблон для flake8, обогащу его вашими находками.
Я использую совместно с black, это автоматом исключает многие ворнинги.
Сложные аннотации типов можно вынести в переменную. Часто вместо типа
Generator
можно указатьIterator
так проще. Когда я хочу подчеркнуть, что dict который я возвращаю менять не надо, я использую аннотациюMapping
Когнитивную сложность у себя я отключил. Цикломатическая и когнитивная на маленьких цифрах очень похожа, а так плагином меньше.
Если быть педантом, то нужно еще через try-finally
Для настраеваемых функций часто использую класс с
__call__
. Его потом легко подменять в тестах.Я зависимости на 3 части разделяю.
- проект
- CI (pytest, линтеры, ...)
- dev, то что нужно на локальной машине, обычно там только pre-commit.
На poetry посматриваю.
Актуально для всех этапов собеседования.
Это тесты на API, там не должно быть сложности. Если всем дают одинаковое здание, то проверка должна занимать минут 10.
Если не времени сделать нормально, надо говорить Нет.
Возможно ему бы стало скучно писать просто тесты.
Генераторы не требуют памяти, но делают больше вычислений.
Создание списка меньше действий, но требует выделения памяти.
Разное железо, версия питона могут немного поменять позиции в списке для худшего случая.
Или можно так:
То, что хотят синьёра с зарплатой джуна - это не секрет. Но вот как часто находят, я не знаю.
Отсеивать уж точно, писать свою реализацию это довольно специфический опыт.
Вопрос который аппелирует к опыту, это требования к объекту, который складывают в эту мапу.
Мои знания об устройстве хэшмапа связанны с обучением, личным интересом и подготовкой к собеседонаниям. Ничего общего с эпытом это не имеет.
Ну если он линейный, то конечно да.
Но, на практике я вижу код, которые уже давно перестал быть линейным. Переменные объявяютя в одной части кода, а используются на 100 строк ниже, да и еще пару раз переопределяются.
Если не включать голову и так и так будет плохо. Но такой код можно быстро заинлайнить, а вот монолит на 300 строк разнести намного сложнее.
Вот тут и место для разделения, комментарий в название документацию метода, блок в тело.
Давайте говорить честно, такие задачи существуют, но они достаточно редки и их не поручают джунам. Джава машина кажется такие вещи может инлайнить сама.
Мне с сонаром как-то не пришлось плотно работать, его можно запустить на локальном коде?
Первый вариант который рекомендует pytest, мне привычнее, и кажется проще для разработки. Я локально гоняю только юниты, а всякие инсталляции можно сбросить на CI.
Вторая статья еще использует setup.py, но с тех пор появились новые инструменты например flit и poetry. Надо посмотреть, как они с такими структурами работают.
А что вы вкладываете в понятие интеграционные тесты? Почему они легче в отладке чем компонентные?
Имя src мне не нравится, это что-то техническое. Я предпочитаю использовать название проекта. То есть вместо
src/gmaps_crawler/
простоgmaps_crawler/
.Есть еще и личная неприязнь к этому имени в контексте Питона, src ассоциируется с Джавой.
Я пишу и на Питоне и на Джаве, но попытки притащить парадигмы из одного языка в другой мне не нравятся.
Двойное подчёркивание в имени локальной переменной несколько перебор.
def __init__(self, db_image_name): __engine = EngineFactory() __engine.stand = 'localhost'
Синглтон тоже можно выкинуть, так как тесты это реализуют самостоятельно.
Комментарии дублируют код. Даже для обучающего кода это излишне.
Я бы попробовал реализовать логику удаления как в фикстуре https://docs.pytest.org/en/6.2.x/reference.html#pytest.tmpdir.tmp_path
Ну ли просто не удалять по аргументу командной строки.