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