Gentoo Archives: gentoo-python

From: Brian Harring <ferringb@×××××.com>
To: Micha?? G??rny <mgorny@g.o>
Cc: Mike Gilbert <floppym@g.o>, gentoo-python@l.g.o
Subject: Re: [gentoo-python] Re: [PATCH eselect-python 1/2] Store per-version interpreter preference in a file as well.
Date: Sat, 03 Nov 2012 03:35:51
Message-Id: 20121103033538.GI3299@localhost
In Reply to: Re: [gentoo-python] Re: [PATCH eselect-python 1/2] Store per-version interpreter preference in a file as well. by "Michał Górny"
1 On Fri, Nov 02, 2012 at 10:03:05AM +0100, Micha?? G??rny wrote:
2 > On Thu, 1 Nov 2012 15:42:42 -0700
3 > Brian Harring <ferringb@×××××.com> wrote:
4 >
5 > > On Thu, Nov 01, 2012 at 10:27:19PM +0100, Micha?? G??rny wrote:
6 > > > On Thu, 1 Nov 2012 14:48:55 -0400
7 > > > Mike Gilbert <floppym@g.o> wrote:
8 > > >
9 > > > > On Thu, Nov 1, 2012 at 11:44 AM, Mike Gilbert <floppymaster@×××××.com> wrote:
10 > > > > > On Thu, Nov 1, 2012 at 7:54 AM, Micha?? G??rny <mgorny@g.o> wrote:
11 > > > > >> The idea is very simple: /etc/env.d/python/python[23] with a one-line
12 > > > > >> value similar to the main interpreter /config file.
13 > > > > >>
14 > > > > >> That should be simpler & more reliable than reading a symlink. And at
15 > > > > >> some point we can replace the symlink with an $EPYTHON-aware wrapper
16 > > > > >> as well.
17 > > > > >
18 > > > > > I don't understand the point of this. Do we have some need to enable
19 > > > > > EPYTHON usages for scripts that have a python2 or python3 shebang?
20 > > > > >
21 > > > > > I also don't understand how a text file is more reliable than a
22 > > > > > symlink; they are basically the same thing, but the symlink has a
23 > > > > > different file mode.
24 > > >
25 > > > Ah, and I'd forget. I have the following dream:
26 > > >
27 > > > /etc/env.d/python/python2
28 > > > /etc/env.d/python/python3
29 > > > /etc/env.d/python/config -> python2
30 > > >
31 > > > So, python{2,3} keep the per-version interpreters, and config is just
32 > > > a symlink to one of them. Two bird with one stone -- readlink to get
33 > > > which group is enabled, cat to get the exact interpreter. I'm proud
34 > > > of myself!
35 > >
36 > > I too have a dream; git://pkgcore.org/eslect-python .
37 > >
38 > > That's a shebang based version of what I proposed a while back. It
39 > > works now and has tests. It's written to be basically a drop in for
40 > > existing python.eclass generation of shebangs, w/ the
41 > > hardlinking/de-duplication/farking-fast/fix python3.2
42 > > /usr/bin/sphinx-build scenario.
43 >
44 > Could you please provide an explanation of what it does? I mean, a few
45 > points of what happens when you run it in various scenarios. That's 600
46 > lines of C code, I think Python folks would appreciate not having to
47 > read that line by line.
48
49 Grumble. Don't think you read my commit messages at all, just
50 responded looking for points to claim "it sucks".
51
52 What I have written here is a python-shebang based solution. That
53 shebang target includes the EPYTHON's it supports.
54
55 For the usual sphinx-build example, sphinx-build-2.7 goes from
56 #!/usr/bin/python2.7
57
58 to
59
60 #!/usr/bin/python-shebang python2.7,python3.2
61
62 This means that sphinx-build-2.7 and sphinx-build-3.2 are now the same
63 content. They can be hardlinked together (space savings).
64
65 This additionally means that sphinx-build can be hardlinked to the
66 same underlying inode. Why? Because python-shebang is smart enough
67 to recognize the context it is invoked in.
68
69 This additionally means that the follow commands:
70
71 eselect python set 3.2
72 python2.7 /usr/bin/sphinx-build
73
74 properly work- invoking sphinx-bulid in a 2.7 context (for anyone
75 trying to write distutils/setup bits that aren't gentoo/EPYTHON
76 specific, this is fricking useful to say the least).
77
78 python-shebang does thus:
79
80 1) parse argv[1]; split it first on ' ' (everything following is split
81 by ' ', and used as args for the python interp invoked). The leftmost
82 is split on ','; this is the list of interpretter targets this script
83 was installed for.
84
85 2) identify the context it was invoked via. If invoked via an interp
86 specific pathway (aka, /usr/bin/sphinx-build-2.7; a forced python2.7
87 context) then it honors that, and re-execs to python2.7 $0 w/ the
88 additional interp args. That re-exec fail, it does the usual failure
89 return.
90
91 3) Making it here means it was invoked in a non forced interp context;
92 meaning /usr/bin/sphinx-build. If the installation required EPYTHON
93 to be honored always (this actually is used if you analyzed the tree),
94 w/in the interp targets there is a EPYTHON value- literally,
95 "EPYTHON". If EPYTHON env var is set, and EPYTHON is set, force that
96 interpretter or fail.
97
98 3) If EPYTHON is set but the script wasn't marked as "honor EPYTHON
99 always", check the list of interp targets, if we can the EPYTHON
100 target, re-exec to it.
101
102 4) Making it here means that env EPYTHON wasn't forced, nor can it be
103 honored. Grab the active python version, re-exec to that if it's a
104 support interpretter for this script.
105
106 5) If it ain't, loop over the list of supported targets, l->r, trying
107 to re-exec in that ordering.
108
109
110 > > The remaining work for that is thus:
111 > >
112 > > 1) If the EPYTHON targets aren't given via shebang arg, then it needs
113 > > to fallback to grabbing the targets from the file (easy enough).
114 > >
115 > > 2) Add a few helpers/wrappers to make it easier to do the
116 > > deduplication/shebang rewriting.
117 >
118 > How would you perform deduplication while you're at it? Could you
119 > measure or at least consider the benefits of it?
120
121 I described this in the original dev ml thread you responded to
122 bitching about symlinks; rewrite the shebang, md5 comparison, what's
123 the same is hardlinked; if all are the same, hardlink the wrapper
124 (meaning if sphinx-build-{2.7,3.2} are the same md5, hardlink
125 sphinx-build to the same underlying inode).
126
127 It's pretty simple.
128
129
130 > > Frankly, you should be looking at this imo, rather than trying
131 > > standalone files. Yes, files is simpler- but you'll wind up sooner or
132 > > later rebuilding it into what I already built out here.
133 >
134 > I think you are missing the point I'm raising here. Mostly because your
135 > python-wrapper doesn't handle per-version preferences like python-exec
136 > does, unless I'm missing something.
137
138 You're misunderstanding what was written; hell, I even referenced
139 that it supports EPYTHON preference in #5 (java-config cycle
140 breaking).
141
142
143 > > """
144 > > Add a python-shebang utility, slave python-wrapper to it.
145 > >
146 > > Going forward, the intent is to push the PYTHON_ABIs of a given
147 > > script down into it's shebang, pointing the shebang at python-shebang.
148 > >
149 > > In this way, all known/supported abi's are available at the time of
150 > > execution; further, if the target is told to respect-EPYTHON (meaning
151 > > no searching for something to execute, either active python version or
152 > > EPYTHON var), we can push this down into that list and have that code
153 > > handle it.
154 > >
155 > > [...]
156 > >
157 > > to the simpler form of:
158 > > for x in sphinx{,-{2.7,3.2}}; do echo > $x <<EOF
159 > > #!/usr/bin/python-shebang python2.7,python3.2
160 > > <code>
161 > > EOF
162 > > done
163 >
164 > Hmm, are you assuming that /usr/bin/sphinx carries the actual code?
165 > Or some special wrapper code?
166 >
167 > Not to mention you still bind the whole thing to installed package.
168 > If you need to fix those files, you need to reinstall all packages
169 > installing them.
170
171 This critique makes no sense... and I'm pretty sure that any point you
172 may manage to come up with, will apply directly to python-exec just as
173 equally.
174
175 Either clarify your claim, or drop the noise there.
176
177
178 > > The gains of this are thus:
179 >
180 > Could you please compare it to the modern solution (python-exec) rather
181 > than the deprecated one? You are no longer on the uncharted waters.
182
183 Respectfully, your 'modern solution' (vs deprecated) is purely in your
184 head; distutils/python eclasses of your making aren't the tree.
185
186 They're your playground right now- one that you're pushing, but I've
187 yet to see real traction on. That's just reality; you may think it's
188 a done deal (or will be), but the on the ground reality right now-
189 including the pushback you've been getting from people in certain
190 cases- makes me unwilling to pin my hopes on your work.
191
192
193 Either way, you asked, so here's the list of python-exec con's in
194 comparison to python-shebang:
195
196 1) Your solution actually doesn't work as a fricking wrapper for a
197 core usage case; `python /usr/bin/sphinx-build`. That perfectly
198 innocuous/valid invocation would result in the interpretter trying
199 to execute an elf binary. That pretty much renders your solution as a
200 no go right from the get go. Your only way to fix that is to have
201 sphinx-build be a python implementation that does wrapping, and use a
202 shebang of python-exec (so you can maintain speed for direct
203 /usr/bin/sphinx-build invocations); meaning once you spotted that
204 flaw, you'd evolve your attempt into something nearing what I wrote.
205
206 2) Everytime there is a new python interpretter, python-exec has to
207 be re-built updating it's hardcoded list of interpretters. Goes without
208 saying, this sucks a fair bit; your solution there likely would be
209 walk env.d/python/* in some fashion extracting the list of targets (or
210 walk /usr/bin/python* and run into problems w/ the names used there
211 now matching EPYTHON usage). End result, you'd evolve it into
212 something nearing what I did w/ shebangs.
213
214 3) It's a hardcoded lookup list that is forced for all scripts; if
215 that list is python3.2,python3.1,python2.7, and the active python
216 version doesn't intersect that (say jython-2.5), your approach forces
217 3.2. My solution actually allows the script, in the absense of an
218 enforcement via active python or EPYTHON, to use it's own preferred
219 ordering. Using pkgcore as an example, we prefer py2k execution over
220 py3k- py2k is faster since the extensions are enabled. This
221 capability doesn't exist in your solution, nor the existing wrapper;
222 it's a useful byproduct of how my solution is structured. Etc etc,
223 you know the response; where you'll go with this sooner or later is
224 where python-shebang is already.
225
226 5) Via going with a standalone package from eselect-python, you're
227 introducing the potential for the two to be out of sync/incompatible.
228 Addressable via folding it inline into eselect-python (as I did), but
229 it's a con against your solution in it's current claimed form. Same
230 thing, you'll do what I did sooner or later since it's the better
231 approach.
232
233 6) With N=# of python implementations, you're forcing N copies of that
234 script. My solution will de-dupe it down to where the content is the
235 same; most scripts, that means all script-* and script collapses down
236 to one single inode. If py3k content differs from py2k, and it's
237 installed for py2k/py3k, this means in that case 3 inodes. Your
238 solution has no way to avoid the inode/space overhead, not w/out
239 switching the shebang.
240
241 7) My solution doesn't hardcode /usr/bin/* pathways. User sticks a
242 python2.7 into /usr/local/ (for whatever reason they choose to do so),
243 it will honor that.
244
245 8) Your solution doesn't work in the context of being used for
246 /usr/bin/python wrapper; it's close, but as you yourself said, it
247 requires symlinks (python-python2.7).
248
249 9) No tests. Every. Fucking. Pathway. is tested with what I wrote.
250 Python-exec lacks that, else issue #1 would've been spotted up front.
251
252
253 What you've got only works for direct invocation of a target via
254 /usr/bin/sphinx-build; python /usr/bin/sphinx-build won't fly; nor can
255 it be used as the the python wrapper w/out changing how we install the
256 interpretter.
257
258
259 Python shebang however works all existing scenarios, and fixes the
260 core scenario that got me started here; `python2.7
261 /usr/bin/sphinx-build`.
262
263 The only flaws with it at this point are thus:
264
265 1) There is a 127 char limit on shebang length. This is addressable
266 via having python-shebang reach grab the list from the target itself
267 if that limit is encountered.
268
269 2) fleshing out the tools for doing de-duplication; it's easy enough,
270 I've just been busy with other things, and this code was done as a
271 side project for entertainment. I'll finish it soon enough (else if
272 someone wants to sort the remaining issues, I can detail exactly how).
273
274
275 The nice part about my solution here is that it's not something that
276 is hinged mgorny's python/distutils eclasses becoming the norm; it's
277 usable now for existing python eclass (simple enough to plug it in),
278 and any followup solution would be insane not to use it.
279
280 ~harring

Replies