Gentoo Archives: gentoo-dev

From: Mike Gilbert <floppym@g.o>
To: "Michał Górny" <mgorny@g.o>
Cc: gentoo-dev@l.g.o, python@g.o
Subject: [gentoo-dev] Re: [PATCH] Check for USE_PYTHON <-> PYTHON_TARGETS sync.
Date: Sat, 17 Nov 2012 16:59:47
Message-Id: CAJ0EP41SmfbkKbsCJd1=wcDK8hnBz0-cUgR4BJxsmMi+fXDE0g@mail.gmail.com
In Reply to: [gentoo-dev] [PATCH] Check for USE_PYTHON <-> PYTHON_TARGETS sync. by "Michał Górny"
1 On Fri, Nov 16, 2012 at 1:44 PM, Michał Górny <mgorny@g.o> wrote:
2 > This is much more complex than the previous version.
3 >
4
5 The inline comments and debug-print statements are helpful.
6
7 Do we have a way to test this with various combinations of
8 PYTHON_COMPAT, PYTHON_TARGETS, eselect python, and USE_PYTHON?
9
10 I have some suggestions on the actual warning text below.
11
12 > If user doesn't have USE_PYTHON set, it tries to solve the issue using
13 > eselect-python only, suggesting user to switch the active
14 > implementation.
15 >
16 > If eselect-python won't help or user has USE_PYTHON set, it nicely
17 > suggests a new value, highlighting added and listing removed entries.
18 >
19 > The basic issue here is that the package can only check PYTHON_TARGETS
20 > values in IUSE, so only the implementations supported by the package. It
21 > tries hard to help and not to do any damage, so user may need to modify
22 > his USE_PYTHON more than once.
23 >
24 > For example, consider the following:
25 >
26 > - installed: 2.6, 2.7, 3.1, 3.2, pypy1.8
27 > - active: 2.6, 3.2
28 > - USE_PYTHON not set
29 > - PYTHON_TARGETS: 2.7, 3.1, 3.2, pypy1.8
30 >
31 > Package 1 supports Python 2 only. The eclass can't access Python 3
32 > PYTHON_TARGETS, thus it can only suggest user to switch active Python
33 > interpreter to Python 2.7. This solves the Python2 packages only.
34 >
35 > Package 2 supports both Python 2 & 3. The eclass notices two Python 3
36 > versions and suggests user to add USE_PYTHON='2.7 3.1 3.2'.
37 >
38 > Package 3 supports PyPy additionally. The eclass notices that, and
39 > suggests user to add '2.7-pypy-1.8' to USE_PYTHON.
40 >
41 > Of course, that assumes building one-by-one. If more packages get pulled
42 > into the dep tree, the results of checks may look even contradictory.
43 > Hopefully, after a few changes and rebuilds user will finally get
44 > the correct value.
45 > ---
46 > gx86/eclass/python-r1.eclass | 198 +++++++++++++++++++++++++++++++++++++++++++
47 > 1 file changed, 198 insertions(+)
48 >
49 > diff --git a/gx86/eclass/python-r1.eclass b/gx86/eclass/python-r1.eclass
50 > index 0d6ef4c..61edf94 100644
51 > --- a/gx86/eclass/python-r1.eclass
52 > +++ b/gx86/eclass/python-r1.eclass
53 > @@ -363,6 +363,202 @@ python_copy_sources() {
54 > done
55 > }
56 >
57 > +# @FUNCTION: _python_check_USE_PYTHON
58 > +# @INTERNAL
59 > +# @DESCRIPTION:
60 > +# Check whether USE_PYTHON and PYTHON_TARGETS are in sync. Output
61 > +# warnings if they are not.
62 > +_python_check_USE_PYTHON() {
63 > + debug-print-function ${FUNCNAME} "${@}"
64 > +
65 > + if [[ ! ${_PYTHON_USE_PYTHON_CHECKED} ]]; then
66 > + _PYTHON_USE_PYTHON_CHECKED=1
67 > +
68 > + # python-exec has profile-forced flags.
69 > + if [[ ${CATEGORY}/${PN} == dev-python/python-exec ]]; then
70 > + return
71 > + fi
72 > +
73 > + _try_eselect() {
74 > + # The eselect solution will work only with one py2 & py3.
75 > +
76 > + local impl py2 py3 dis_py2 dis_py3
77 > + for impl in "${PYTHON_COMPAT[@]}"; do
78 > + if use "python_targets_${impl}"; then
79 > + case "${impl}" in
80 > + python2_*)
81 > + if [[ ${py2+1} ]]; then
82 > + debug-print "${FUNCNAME}: -> more than one py2: ${py2} ${impl}"
83 > + return 1
84 > + fi
85 > + py2=${impl/_/.}
86 > + ;;
87 > + python3_*)
88 > + if [[ ${py3+1} ]]; then
89 > + debug-print "${FUNCNAME}: -> more than one py3: ${py3} ${impl}"
90 > + return 1
91 > + fi
92 > + py3=${impl/_/.}
93 > + ;;
94 > + *)
95 > + return 1
96 > + ;;
97 > + esac
98 > + else
99 > + case "${impl}" in
100 > + python2_*)
101 > + dis_py2=1
102 > + ;;
103 > + python3_*)
104 > + dis_py3=1
105 > + ;;
106 > + esac
107 > + fi
108 > + done
109 > +
110 > + # The eselect solution won't work if the disabled Python version
111 > + # is installed.
112 > + if [[ ! ${py2+1} && ${dis_py2} ]]; then
113 > + debug-print "${FUNCNAME}: -> all py2 versions disabled"
114 > + if has_version '=dev-lang/python-2*'; then
115 > + debug-print "${FUNCNAME}: ---> but =python-2* installed!"
116 > + return 1
117 > + fi
118 > + fi
119 > + if [[ ! ${py3+1} && ${dis_py3} ]]; then
120 > + debug-print "${FUNCNAME}: -> all py3 versions disabled"
121 > + if has_version '=dev-lang/python-3*'; then
122 > + debug-print "${FUNCNAME}: ---> but =python-3* installed!"
123 > + return 1
124 > + fi
125 > + fi
126 > +
127 > + local warned
128 > +
129 > + # Now check whether the correct implementations are active.
130 > + if [[ ${py2+1} ]]; then
131 > + local sel_py2=$(eselect python show --python2)
132 > +
133 > + debug-print "${FUNCNAME}: -> py2 built: ${py2}, active: ${sel_py2}"
134 > + if [[ ${py2} != ${sel_py2} ]]; then
135 > + ewarn "Building package for ${py2} only while ${sel_py2} is active."
136 > + ewarn "Please consider switching the active Python 2 interpreter:"
137 > + ewarn
138 > + ewarn " eselect python set --python2 ${py2}"
139 > + warned=1
140 > + fi
141 > + fi
142 > +
143 > + if [[ ${py3+1} ]]; then
144 > + local sel_py3=$(eselect python show --python3)
145 > +
146 > + debug-print "${FUNCNAME}: -> py3 built: ${py3}, active: ${sel_py3}"
147 > + if [[ ${py3} != ${sel_py3} ]]; then
148 > + [[ ${warned} ]] && ewarn
149 > + ewarn "Building package for ${py3} only while ${sel_py3} is active."
150 > + ewarn "Please consider switching the active Python 3 interpreter:"
151 > + ewarn
152 > + ewarn " eselect python set --python3 ${py3}"
153 > + warned=1
154 > + fi
155 > + fi
156 > +
157 > + if [[ ${warned} ]]; then
158 > + ewarn
159 > + ewarn "Please note that after switching the active Python interpreter,"
160 > + ewarn "you may need to run 'python-updater' to ensure the system integrity."
161
162 Change "ensure the system integrity" to something like "rebuild
163 affected packages". The former statement is awkward and doesn't really
164 explain anything.
165
166 > + ewarn
167 > + ewarn "For more information on python.eclass compatibility, please see"
168 > + ewarn "the appropriate python-r1 User's Guide chapter [1]."
169 > + ewarn
170 > + ewarn "[1] http://www.gentoo.org/proj/en/Python/python-r1/user-guide.xml#doc_chap2"
171 > + fi
172 > + }
173 > +
174 > + # If user has no USE_PYTHON, try to avoid it.
175 > + if [[ ! ${USE_PYTHON} ]]; then
176 > + debug-print "${FUNCNAME}: trying eselect solution ..."
177 > + _try_eselect && return
178 > + fi
179 > +
180 > + debug-print "${FUNCNAME}: trying USE_PYTHON solution ..."
181 > + debug-print "${FUNCNAME}: -> USE_PYTHON=${USE_PYTHON}"
182 > +
183 > + local impl old=${USE_PYTHON} new=() removed=()
184 > +
185 > + for impl in "${PYTHON_COMPAT[@]}"; do
186 > + local abi
187 > + case "${impl}" in
188 > + python*)
189 > + abi=${impl#python}
190 > + ;;
191 > + jython*)
192 > + abi=${impl#jython}-jython
193 > + ;;
194 > + pypy*)
195 > + abi=2.7-pypy-${impl#pypy}
196 > + ;;
197 > + *)
198 > + die "Unexpected Python implementation: ${impl}"
199 > + ;;
200 > + esac
201 > + abi=${abi/_/.}
202 > +
203 > + has "${abi}" ${USE_PYTHON}
204 > + local has_abi=${?}
205 > + use "python_targets_${impl}"
206 > + local has_impl=${?}
207 > +
208 > + # 0 = has, 1 = does not have
209 > + if [[ ${has_abi} == 0 && ${has_impl} == 1 ]]; then
210 > + debug-print "${FUNCNAME}: ---> remove ${abi}"
211 > + # remove from USE_PYTHON
212 > + old=${old/${abi}/}
213 > + removed+=( ${abi} )
214 > + elif [[ ${has_abi} == 1 && ${has_impl} == 0 ]]; then
215 > + debug-print "${FUNCNAME}: ---> add ${abi}"
216 > + # add to USE_PYTHON
217 > + new+=( ${abi} )
218 > + fi
219 > + done
220 > +
221 > + if [[ ${removed[@]} || ${new[@]} ]]; then
222 > + old=( ${old} )
223 > +
224 > + debug-print "${FUNCNAME}: -> old: ${old[@]}"
225 > + debug-print "${FUNCNAME}: -> new: ${new[@]}"
226 > + debug-print "${FUNCNAME}: -> removed: ${removed[@]}"
227 > +
228 > + if [[ ${USE_PYTHON} ]]; then
229 > + ewarn "It seems that your USE_PYTHON setting does list different Python"
230
231 Drop "It seems that"; it softens the statement for no reason. This
232 also applies to a few statements below.
233 The phrase "does list" looks odd in English.
234 Replace with "Your USE_PYTHON setting lists different Python ...".
235
236 > + ewarn "implementations than your PYTHON_TARGETS variable. Please consider"
237 > + ewarn "using the following value instead:"
238 > + ewarn
239 > + ewarn " USE_PYTHON='\033[35m${old[@]}${new[@]+ \033[1m${new[@]}}\033[0m'"
240 > +
241 > + if [[ ${removed[@]} ]]; then
242 > + ewarn
243 > + ewarn "(removed \033[31m${removed[@]}\033[0m)"
244 > + fi
245 > + else
246 > + ewarn "It seems that you need to set USE_PYTHON to make sure that legacy"
247
248 s/It seems that you need/You should/
249
250 > + ewarn "packages will be built with respect to PYTHON_TARGETS correctly:"
251 > + ewarn
252 > + ewarn " USE_PYTHON='\033[35;1m${new[@]}\033[0m'"
253 > + fi
254 > +
255 > + ewarn
256 > + ewarn "Please note that after changing the USE_PYTHON variable, you may need"
257 > + ewarn "to run 'python-updater' to ensure the system integrity."
258
259 Again, s/ensure the system integrity/rebuild affected packages/.
260
261 > + ewarn
262 > + ewarn "For more information on python.eclass compatibility, please see"
263 > + ewarn "the appropriate python-r1 User's Guide chapter [1]."
264 > + ewarn
265 > + ewarn "[1] http://www.gentoo.org/proj/en/Python/python-r1/user-guide.xml#doc_chap2"
266 > + fi
267 > + fi
268 > +}
269 > +
270 > # @FUNCTION: python_foreach_impl
271 > # @USAGE: <command> [<args>...]
272 > # @DESCRIPTION:
273 > @@ -376,6 +572,8 @@ python_copy_sources() {
274 > python_foreach_impl() {
275 > debug-print-function ${FUNCNAME} "${@}"
276 >
277 > + _python_check_USE_PYTHON
278 > +
279 > local impl
280 > local bdir=${BUILD_DIR:-${S}}
281 >
282 > --
283 > 1.8.0
284 >

Replies