Комментарии 20
Почему это проблема? Менять внутрянку питона в обычных скриптах через грязные хаки будет не более полтора землекопа в вечность.
Я бы не сказал, что это какая-то настоящая большая проблема. Скорее, это просто падение интерпретатора, которого могло бы и не быть. И для того, чтобы в будущем его действительно не было, запланирован фикс, который ничего не ухудшает с точки зрения производительности и пользовательского опыта.
И на примере этого фикса немного рассказываю о том, как устроен CPython внутри - и код, и сообщество.
g.gi_frame.f_locals['.0'] = range(20)
Если залезть внутрь объекта и поменять его внутренне состяние, то он может сломаться. Сенсация? Не думаю.
Названия полей не начинаются с подчеркивания, а значит согласно питоновским же конвенциям — публичное API
Именно так, никаких "хаков" тут нет, это вполне валидное изменение объекта, согласно текущей документации и PEP.
Ссылочку на документацию в студию.
Я бы сказал полувалидное. Явно блокировать не стали, но и рекомендаций что это можно делать тоже не давали.
Найти и пофиксить такой баг это хороший шаг для вас, ваших знаний и вашей карьеры, но не большой для всего сообщества Питонистов.
Вы молодец, что сделали и написали. Мне лично статье не нарвится только заголовок, похоже на дёшёвые маркетинговые трюки.
Вы можете ознакомиться с PEP 667, там вполне рассматриваются примеры довольно похожего кода. Кроме того, можно заглянуть на страничку inspect, там и gi_frame
, и f_locals
, и co_code
упомянуты. Так что чисто формально, упоминания в документации про все эти объекты есть. Впрочем, соглашусь, что в полном смысле публичными их назвать трудно.
Я рад, что вам понравилось основное содержимое статьи. Является ли название "маркетинговым трюком"? Немного, возможно. Гиперболой оно точно является, "сломаны" - это громко сказано. Сделано ли это с целью привлечь чуть больше внимания к неинтересным для абсолютного большинства пользователей Хабра внутренностям Python? Конечно.
Объект
gi_frame
- это специальный внутренний объект интерпретатора,
А в статье это предсталенно несколько по другому.
Да и документация к это публичному API страдает. https://docs.python.org/3/search.html?q=gi_frame
На Python и других managed языках обычно всё-таки "сломаться" подразумевает некорректное поведение объекта (неверные ответы, кидание исключений, зависание), а не полное падение интерпретатора, которое нельзя поймать обычным try
/except
Если бы мне хотелось undefined behavior и падений — я бы писал на C++.
Эта ошибка больше выдаваться не будет, но аналогичная по сути ошибка проявится позже, в момент итерирования полученного генератора.
Разве это лучше?
Нет, само по себе это не лучше, но такое изменение поведения - side effect. В текущей реализации инструкция GET_ITER
вызывается и снаружи генераторного выражения, и внутри него. Соответственно, внешний вызов будет убран.
"Непонятная ошибка" превратилась в понятную ошибку, это хороший результат. Мне эта тенденция в Питоне нравится, с каждый релизом сообщения в среднем становятся лучше.
Эта ошибка больше выдаваться не будет, но аналогичная по сути ошибка проявится позже, в момент итерирования полученного генератора. Этих изменений в ветке main ещё нет, идет работа над Pull Request.
А что в этом хорошего, простите?
Это переносит проблему в другое место кода, ломает "раннее обнаружение" и может усложнить поиск бага. Ну и зачем так делать? Генератор может быть создан "за километр" от места использования. Представьте, что он был создан в библиотеке, автор не покрыл тестами, а пользователь библиотеки получает сломанный генератор, с багом, который выстрелит в момент использования, а не в момент создания.
Эта ошибка больше выдаваться не будет, но аналогичная по сути ошибка проявится позже, в момент итерирования полученного генератора
А давайте еще все линтеры отключим, а то чего они ошибки выдают. Лучше ошибка будет проявляться позже, в момент выполнения кода на проде \s
А в чем достижение-то? Замели проблему под коврик, она же от этого не исчезла
Настоящая проблема - возможность в Python мутэйтить все на свете. В данной статье один из примеров того, что делать , по сути, не нужно (причем, не только - "плохо", но и банально - "незачем"), но сам язык это любезно разрешает
Ну это и его приемущество. Можно например для обратной совместимости функцию подхачить, чтобы её можно было использовать как класс для наследования. Для обратной совместимости самое то.
В С вы вообще можете прямо писать в память программы что захотите.
Но возможность не значит, что её надо всюду использовать. Нужно строить культуру разработки, тогда будет нормально.
g.gi_frame.f_locals['.0'] = range(20)
Интересно узнать какая прикладная задача заставила вас делать такие вещи с генератором
Ваши генераторные выражения сломаны: чиним и разбираемся