1

Тема: Видалення unused imports безпечним шляхом

Доброго часу доби.

Коли заходить мова про рефакторинг, перші кроки робляться з множини {"знайти дублі", "знайти зайві імпорти", "запхати все в класи"} і т.п. Сьогодні мова піде про видалення unused imports. Виявити їх легко - у PyCharm хвиляста лінія та напівпрозорий шрифт покажуть, що варто би прибрати. Чи не варто?..

Розглянемо навчальний приклад (спрощена версія кількох реальних систем):

код

"""Structure of the project:

project_dir/
    mypack/
        __init__.py
        lib/
            __init__.py
            parser.py
            utils.py
        models/
            __init__.py
            user.py
example_users.txt
main.py"""

# CONTENT OF THE FILES #

# mypack.lib.parser.py
from .utils import *
def parse_users_from_file(fname):
    with open(fname, 'r') as f:
        for line in f:
            name, surname = line.split(',')
            User(name=name, surname=surname).save()

# mypack.lib.utils.py
from mypack.models import User

def some_foo(some_arg): pass

"""Some years ago we removed some code related to User model,
but forgot to remove its import here."""

# mypack.models.__init__.py
from .user import User

# mypack.models.user.py
class User:
    def __init__(self, *args, **kwargs): pass
    def save(self): pass

# example_users.txt
Vasa,Pupkin
Ivan,Petrov

# main.py
from mypack.lib.parser import parse_users_from_file as pfn

pfn('example_users.txt')
print("OK\n")

У кількох словах: є модуль parser, який використовує модель User, імпортовану в модулі utils, з якого імпортовано "зірочку" у модулі parser. Інакше кажучи, User потрапив до глобального неймспейса у модулі parser, не будучи імпортованим явно.

Тим часом, PyCharm стабільно видає нам "unused import statement" у модулі utils, в якому дійсно цей імпорт не є потрібним. Певна річ, що перший крок при цьому - піти до автора цієї диво-архітектури і <s>наваляти по перше</s> з'ясувати причини і можливі виходи. А якщо й тут буде фейл?..

У пошуках можливої пігулки я пішов, по суті, напролом:

1. Грепнути проект на предмет використання "нелегального мігранта".
2. Якщо "мігрант" використовується у модулі, він має там імпортуватися.
3. Якщо явного імпорту немає - починаємо копати вглиб, знаходимо джерело неявного імпорту, робимо явний імпорт у знайденому модулі.
4. Якщо лишилися подібні імпорти, - переходимо до кроку 1, або закінчуємо.

Можливо, неоптимально та громіздко, але це діє. Даєш качину типізацію!

У кого є ідеї з надійної автоматизації даного процесу - пишіть.



Оригінал статті тут.

I belong to the Dead Generation.
Подякували: Chemist-i, Altair8800, 0xDADA11C7, leofun014

2

Re: Видалення unused imports безпечним шляхом

Є пару незрозумілих, принаймні мені, моментів:

є модуль parser, який використовує модель User, імпортовану в модулі utils, з якого імпортовано "зірочку" у модулі parser.

Для таких речей варто робити якусь схему, хай навіть примітивну нашвидкоруч в пейнті абощо. Пам'ятайте, що люди не здатні на двохходові комбінації, в код треба вчитуватись, в текст треба вчитуватись, а на картинку просто глянув, пояснення під нею почитав і вся ясно.

Грепнути проект на предмет використання "нелегального мігранта"

Самостійно переглядати кожен файл чи що?

Певна річ, що перший крок при цьому - піти до автора цієї диво-архітектури і <s>наваляти по перше</s> з'ясувати причини і можливі виходи. А якщо й тут буде фейл?..

Фейл в тому, що не вдасться наваляти зламати партизана?)

3

Re: Видалення unused imports безпечним шляхом

Altair8800 написав:

Є пару незрозумілих, принаймні мені, моментів:

є модуль parser, який використовує модель User, імпортовану в модулі utils, з якого імпортовано "зірочку" у модулі parser.

Для таких речей варто робити якусь схему, хай навіть примітивну нашвидкоруч в пейнті абощо. Пам'ятайте, що люди не здатні на двохходові комбінації, в код треба вчитуватись, в текст треба вчитуватись, а на картинку просто глянув, пояснення під нею почитав і вся ясно.

Грепнути проект на предмет використання "нелегального мігранта"

Самостійно переглядати кожен файл чи що?

Певна річ, що перший крок при цьому - піти до автора цієї диво-архітектури і <s>наваляти по перше</s> з'ясувати причини і можливі виходи. А якщо й тут буде фейл?..

Фейл в тому, що не вдасться наваляти зламати партизана?)


..
За останні кілька Ваших відповідей на мої форумі діагностую заочну ворожість до мене. :)

Щодо "пейнт-моделі": стаття не орієнтована на новачків, а міддл спокійно збудує в голові схему на основі того коду (його там дуже мало). Якщо ж джуну знадобилося вирішувати таку проблему - значить, це по роботі. І тут він має піти до свого ментора і питається "а можеш пояснити - не доганяю". Якщо ментора нема - то це еквівалент фріланса, і там уже або ти прогресуєш сам великими кроками, або не лізь у такі проекти - бери щось простіше.

Щодо "перегляду файлів":
Ctrl + Shift + F  - дає вікно пошуку з купою уточнень. Результатом буде вікно зі знайденими рядками. І там уже переглядаєте - та, кожен файл. Маєте інші варіанти? :)

Щодо "Фейлу":
Варіацій настільки багато, що мені просто лінь усі описувати (та й сенсу нема - все одно результат один).

I belong to the Dead Generation.

4

Re: Видалення unused imports безпечним шляхом

Bartash написав:
..
За останні кілька Ваших відповідей на мої форумі діагностую заочну ворожість до мене. :)
Прихований текст
Мною керує лише цікавість. Та й стаття без відгуків здається зроблена дарма, наскільки б корисну інформацію вона не несла.
Якщо моє влиття в комуну виявилось надто різким, здається, варто краще проникнуться атмосферою цього форуму.

Щодо "пейнт-моделі": стаття не орієнтована на новачків, а міддл спокійно збудує в голові схему на основі того коду (його там дуже мало). Якщо ж джуну знадобилося вирішувати таку проблему - значить, це по роботі. І тут він має піти до свого ментора і питається "а можеш пояснити - не доганяю". Якщо ментора нема - то це еквівалент фріланса, і там уже або ти прогресуєш сам великими кроками, або не лізь у такі проекти - бери щось простіше.

1. Ви недооцінюєте джунів.
2. Часто те, що здається очевидним, таким стає лише після того, як покажеш все покроково.
А ще є такі людські фактори як втома, "недобачив" і т.д., в той час коли візуальні речі краще сприймаються.
Можете не робити, якщо вам здається це зайвим - це більше як порада для оформлення статей, що якщо є можливість зробити схему, то краще таки зробити.

Маєте інші варіанти? :)

Ну наприклад

Щодо "Фейлу":
Варіацій настільки багато, що мені просто лінь усі описувати (та й сенсу нема - все одно результат один).

Насправді, просто хотілось підтримати жарт, що не дуже вдалось.
Всі варіації писати й не треба, хоча парою цікавих випадків поділитись не буде зайвим за наявності таких :)

5

Re: Видалення unused imports безпечним шляхом

Прихований текст

Altair8800 написав:
Bartash написав:
..
За останні кілька Ваших відповідей на мої форумі діагностую заочну ворожість до мене. :)
Прихований текст
Мною керує лише цікавість. Та й стаття без відгуків здається зроблена дарма, наскільки б корисну інформацію вона не несла.
Якщо моє влиття в комуну виявилось надто різким, здається, варто краще проникнуться атмосферою цього форуму.

Щодо "пейнт-моделі": стаття не орієнтована на новачків, а міддл спокійно збудує в голові схему на основі того коду (його там дуже мало). Якщо ж джуну знадобилося вирішувати таку проблему - значить, це по роботі. І тут він має піти до свого ментора і питається "а можеш пояснити - не доганяю". Якщо ментора нема - то це еквівалент фріланса, і там уже або ти прогресуєш сам великими кроками, або не лізь у такі проекти - бери щось простіше.

1. Ви недооцінюєте джунів.
2. Часто те, що здається очевидним, таким стає лише після того, як покажеш все покроково.
А ще є такі людські фактори як втома, "недобачив" і т.д., в той час коли візуальні речі краще сприймаються.
Можете не робити, якщо вам здається це зайвим - це більше як порада для оформлення статей, що якщо є можливість зробити схему, то краще таки зробити.

Маєте інші варіанти? :)

Ну наприклад

Щодо "Фейлу":
Варіацій настільки багато, що мені просто лінь усі описувати (та й сенсу нема - все одно результат один).

Насправді, просто хотілось підтримати жарт, що не дуже вдалось.
Всі варіації писати й не треба, хоча парою цікавих випадків поділитись не буде зайвим за наявності таких :)

Прихований текст
А, ну то добре, бо вже запідозрив смажене. :)

Я не склався як блогер, але бажання писати є, і є чим поділитись - от і кидаю такого роду замітки. Коменти - показник трекінгу у блогах. А на цьому форумі бува достатьно і подяк. :)

Років 5 тому я би і схемку спаяв, і файну картинку пришльопав. Однак далеко не завжди візуалізація є настільки необхідною. Реально - тут коду рядків на 30-40 разом з коментами. Якби приклад був з модулем на сотню-дві, то, звісно, була би й модель. і потрібні коменти. Це навіть не стаття, а так, замітка радше.

Плагін не тестив - подивлюся у вільну хвильку, дякую.

Варіації... Скажімо, такі:
- CoderIsNotAccessible (фрілансер, колишній працівник)
- CoderIsYourChief (тімлід абощо)
- CoderIsCommunity (OpenStack)
і т.д.

До джунів я ставлюся нормально і навіть сам менторив - не подумайте, що по цей бік екрану консервативний дядько, що вважає себе новим Гвідо :). Безперечно, джунів теж може зацікавити рефакторинг, вилизування коду, "дайтє мнє ісходнікі міра" і т.д. Але по тасках їм тре розбиратися з новим стеком, специфікою задачі, абощо, а сучасні проекти на ринку робляться хиткими, тому знайти проект, де тімлід скаже "хлопці, ану чистити стайні!", майже нереально (або недоцільно), та й ніхто джуну таке не довірить. Якщо ж у джуна буде додатковий час на вивчення подібних заміток, то, скоріш за все, десь у загальній організації його роботи є провтик (варіантів теж багато, але то оффтоп).

I belong to the Dead Generation.

6 Востаннє редагувалося Altair8800 (30.12.2017 20:58:00)

Re: Видалення unused imports безпечним шляхом

Bartash написав:

Плагін не тестив - подивлюся у вільну хвильку, дякую.

Не забудьте відписатись про результати :)

- CoderIsNotAccessible (фрілансер, колишній працівник)

Трішки (не трішки) життєво.

- CoderIsCommunity (OpenStack)

Давати будь-кому писати говнокод і при цьому слідкувати за чистотою проекту - так собі заняття. Хіба що вам нічим зайнятись.
Зрозуміло, все стандартно.

7

Re: Видалення unused imports безпечним шляхом

Altair8800 написав:

- CoderIsCommunity (OpenStack)

Давати будь-кому писати говнокод і при цьому слідкувати за чистотою проекту - так собі заняття. Хіба що вам нічим зайнятись.
Зрозуміло, все стандартно.

Можемо окрему тему створити - тут тема надовго розтягнеться, якщо вглиб пірнати. :)

I belong to the Dead Generation.

8

Re: Видалення unused imports безпечним шляхом

І з льоту відповідаю щодо плагіну: не фуричить дана штука: фактично, "Optimize imports" що на файлі, що на всьому проекті дає видалення непотрібних імпортів, не враховуючи "мігрантів", звідки отримуємо NameError при запуску прикладу. Такі пироги. :)

I belong to the Dead Generation.

9

Re: Видалення unused imports безпечним шляхом

Bartash написав:

І з льоту відповідаю щодо плагіну: не фуричить дана штука: фактично, "Optimize imports" що на файлі, що на всьому проекті дає видалення непотрібних імпортів, не враховуючи "мігрантів", звідки отримуємо NameError при запуску прикладу. Такі пироги. :)

Ну так з помилкою стало видніше що потрібно видалити/переписати, хіба ні?

10

Re: Видалення unused imports безпечним шляхом

Bartash написав:
Altair8800 написав:

- CoderIsCommunity (OpenStack)

Давати будь-кому писати говнокод і при цьому слідкувати за чистотою проекту - так собі заняття. Хіба що вам нічим зайнятись.
Зрозуміло, все стандартно.

Можемо окрему тему створити - тут тема надовго розтягнеться, якщо вглиб пірнати. :)

А давайте.

11

Re: Видалення unused imports безпечним шляхом

А в принципі, я тут подумав, що неможливо повністю автоматизувати те, що ви хочете зробити.
Такі речі як автоматичне оголошення змінної, коли забув її оголосити, виправлення помилок в написанні стандартних мовних назв, те ж автоматичне видалення зайвих імпортів - це все "кометичні" дії, які можуть бути вбудованими в програмне середовище задля полегшення роботи програміста.
А от, інший приклад, коли мерджаться дві гілки гіта і потрібно обрати яку версію файлу використовувати, то тут потрібна людина, яка б робила це в ручну, бо програма не може знати який з двох варіантів краще залишити. Те саме з "мігрантами" - без людського втручання тут не обійтись.
Максимум, що можна зробити - щоб проблемні ділянки автоматично підтягувались, а потім змінювати їх на власний розсуд.