2 # pyimportcan.pl -- Python imports canonical format filter
3 # Copyright (C) 2013-2025 Sergey Matveev (stargrave@stargrave.org)
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, version 3 of the License.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Python allows various different formats of how to make importing of
21 modules and functions:
25 from foo import bar, baz
37 from foo import bar, \
40 Everything can be unsorted at any place, thus making the task of
41 checking if import already exists rather hard. Moreover it complicates
42 just adding another import, because you have to find it first and deal
43 with the format it is already written.
45 Everything can use different indentation practices. Everything can be
46 doubled and you won't notice it:
55 Allowing multiple imports on one line leads to possibility of long lines
58 The whole import sections with various formats just can not be
59 technically sorted with the editor (no way to do "vip:sort<CR>" in Vim).
61 Merge conflict in the imports section can be not so trivial to resolve,
62 however in most cases just aggregating them will be enough.
64 If you want to find the code that imports bar from foo, then you can do
65 it with "from foo import bar", but can not with "import (\n" is most
66 cases. You are forced to use special Python-related software to deal
67 with it, but no grep or sed.
71 Use the very convenient simple single format. Single import per line,
72 period. Sorted and only identical ones. With git merge conflict lines
73 removed. This script reads stdin with import-lines and writes canonical
74 representation of them to stdout. For example you can select lines in
75 Vim and just enter ":!pyimportcan.pl".
77 From that kind of imports:
79 from waaccounts.models import OrgRole
81 from waaccounts.models import UserAccount
82 from waadv.filters import AdvCampaignFilterSet as foo1
83 from waadv.filters import AdvCampaignBidFilterSet
84 from waadv.filters import AdvCampaignUniqueShowFilterSet as foo2
85 from waadv.filters import VasttaskFilterSet
86 from waadv.forms import AdvCampaignCreateForm
87 from waadv.forms import PriceListTotalBudgetDiscountFormset
88 from waadv.models import Adv
89 from waadv.models import PriceListTotalBudgetDiscount
90 from waadv.models import VastTask
91 from wacontent.models import VrContractGroup
92 from wacatalog.models import AdvGroup
93 from wahelpers.counters import adv_campaign_click_counter_loader
94 from wahelpers.counters import adv_video_view_fact_counter_loader
95 from wahelpers.counters import adv_view_percent
96 from wahelpers.counters import ctr
97 from wahelpers.functions import get_json_rpc_proxy, get_return_url
99 from waorigin.kendo_menus.toolbar import KendoGridToolbar
100 from waorigin.kendo_menus.toolbar_button import KendoToolbarButton
102 from http_utils import JSONResponse
103 from wahelpers.counters import (
104 adv_campaign_click_counter_loader,
105 adv_campaign_click_fact_counter_loader,
109 from waorigin.kendo_menus.toolbar_button import (
110 AddKendoToolbarButton,
111 StatusKendoToolbarButton
113 from waorigin.models import Content, ContentCategory3 as foo4, ContentCategory2, Files
114 from waorigin.views import filter_view, model_autocompletion, \
115 create_update_with_auto_user, get_objects_for_edit_many
116 from wapartners.models import PrNomenclature, PrSite
117 >>>>>>> 1bf0b64... fixed view refs #11992
118 from waorigin.kendo_data_source import KendoDataSourceView
119 from waorigin.models import Content
120 from waorigin.models import ContentCategory2
121 from waorigin.models import ContentCategory3
122 from waorigin.models import Files
123 from waorigin.views import create_update_with_auto_user
124 from waorigin.views import filter_view
125 from waorigin.views import get_objects_for_edit_many
126 from waorigin.views import model_autocompletion
127 from wapartners.models import PrSite
128 from wapartners.models import PrNomenclature
130 it makes the following one (by feeding it to stdin and capturing on
134 from http_utils import JSONResponse
135 from waaccounts.models import OrgRole
136 from waaccounts.models import UserAccount
137 from waadv.filters import AdvCampaignBidFilterSet
138 from waadv.filters import AdvCampaignFilterSet as foo1
139 from waadv.filters import AdvCampaignUniqueShowFilterSet as foo2
140 from waadv.filters import VasttaskFilterSet
141 from waadv.forms import AdvCampaignCreateForm
142 from waadv.forms import PriceListTotalBudgetDiscountFormset
143 from waadv.models import Adv
144 from waadv.models import PriceListTotalBudgetDiscount
145 from waadv.models import VastTask
146 from wacatalog.models import AdvGroup
147 from wacontent.models import VrContractGroup
148 from wahelpers.counters import adv_campaign_click_counter_loader
149 from wahelpers.counters import adv_campaign_click_fact_counter_loader
150 from wahelpers.counters import adv_video_view_fact_counter_loader
151 from wahelpers.counters import adv_view_percent
152 from wahelpers.counters import ctr
153 from wahelpers.functions import get_json_rpc_proxy
154 from wahelpers.functions import get_return_url
155 from waorigin.kendo_data_source import KendoDataSourceView
156 from waorigin.kendo_menus.toolbar import KendoGridToolbar
157 from waorigin.kendo_menus.toolbar_button import AddKendoToolbarButton
158 from waorigin.kendo_menus.toolbar_button import KendoToolbarButton
159 from waorigin.kendo_menus.toolbar_button import StatusKendoToolbarButton
160 from waorigin.models import Content
161 from waorigin.models import ContentCategory2
162 from waorigin.models import ContentCategory3
163 from waorigin.models import ContentCategory3 as foo4
164 from waorigin.models import Files
165 from waorigin.views import create_update_with_auto_user
166 from waorigin.views import filter_view
167 from waorigin.views import get_objects_for_edit_many
168 from waorigin.views import model_autocompletion
169 from wapartners.models import PrNomenclature
170 from wapartners.models import PrSite
174 Sergey Matveev L<mailto:stargrave@stargrave.org>
186 # Collect strings and aggregate the splitted ones
188 next if /^[<=>]{2,}/;
191 $buf = ($con ? $buf : "") . $_;
192 $con = /[\\,\(]\s*$/ ? 1 : 0;
193 next if /^\s*\)*\s*$/;
197 # Consolidate information from where what is imported
201 next if /import\s*$/;
202 /^(.*)\s*import\s*(.*)$/;
203 my ($where, $what) = ($1, $2);
204 map { $parsed{$where}->{$_}++ } split /\s*,\s*/, $what;
207 foreach my $where (sort keys %parsed){
208 map { print $where . "import $_\n" } sort keys %{$parsed{$where}};