1 |
On Sun, Jan 19, 2014 at 02:36:43PM -0800, Alec Warner wrote: |
2 |
> On Sat, Jan 18, 2014 at 7:07 PM, W. Trevor King <wking@×××××××.us> wrote: |
3 |
> > +def _get_file_uri_tuples(uris): |
4 |
> > + """Return a list of (filename, uri) tuples |
5 |
> > + """ |
6 |
> > |
7 |
> |
8 |
> As mike noted on another thread: |
9 |
> |
10 |
> ""Return a list of (filename, uri) tuples.""" |
11 |
|
12 |
I'd replaced this with: |
13 |
|
14 |
""" |
15 |
Return a list of (filename, uri) tuples |
16 |
""" |
17 |
|
18 |
in v2, but I'll queue the one-line form in v3. |
19 |
|
20 |
> > +def _expand_mirror(uri, custom_mirrors=(), third_party_mirrors=()): |
21 |
> > + """Replace the 'mirror://' scheme in the uri |
22 |
> > |
23 |
> |
24 |
> Sentence should end in a period. |
25 |
|
26 |
Ok. I'll do that for the other summaries as well, and uppercase URI, |
27 |
in v3. |
28 |
|
29 |
> > + writemsg(_("Invalid mirror definition in SRC_URI:\n"), |
30 |
> > + noiselevel=-1) |
31 |
> > + writemsg(" %s\n" % (uri), noiselevel=-1) |
32 |
> |
33 |
> |
34 |
> Is this a py3k thing? You should be able to write: |
35 |
> |
36 |
> writemsg(" %s\n" % uri, noiselevel=-1) |
37 |
> |
38 |
> The tuple is only needed for multiple arguments in py2k. |
39 |
|
40 |
1. I think I just copied and pasted it ;). |
41 |
2. (uri) is not actually a tuple: |
42 |
|
43 |
>>> type(('hello')) |
44 |
<type 'str'> |
45 |
|
46 |
To get a tuple, you need (uri,). |
47 |
|
48 |
I'm fine removing the parens in v3. |
49 |
|
50 |
> > +def _get_uris(uris, settings, custom_mirrors=(), locations=()): |
51 |
> > |
52 |
> |
53 |
> I want you to be careful here. This is bad style when you are |
54 |
> constructing mutable objects in parameter defaults: |
55 |
|
56 |
I used tuples instead of lists because they are not mutable (as you |
57 |
point out later on). |
58 |
|
59 |
> I'm not sure if I appreciate that more or less than the other form.... |
60 |
> |
61 |
> def _get_uris(uris, settings, custom_mirrors=None, locations=None): |
62 |
> if not custom_mirrors: |
63 |
> custom_mirrors = () |
64 |
> if not locations: |
65 |
> locations = () |
66 |
|
67 |
If you want me to do it that way, I'll queue it for v3. I think the |
68 |
default tuples are more readable. They are certainly shorter. |
69 |
|
70 |
> Another advisable way to write it is to simply not have default |
71 |
> arguments, and to force the caller to sync in an empty iterable: |
72 |
|
73 |
Meh. I don't have strong feelings about this, but custom_mirrors |
74 |
struck me as something that would not always be required ;). |
75 |
|
76 |
> > + third_party_mirrors = settings.thirdpartymirrors() |
77 |
> > |
78 |
> |
79 |
> Why pass in all of settings? |
80 |
|
81 |
We need other stuff too, see v2. The less settings parsing I need to |
82 |
do in fetch() itself, the happier I am. If that makes the helper |
83 |
functions a bit uglier, that's fine. Fewer people will have to read |
84 |
those. |
85 |
|
86 |
> Think about testing this function. |
87 |
|
88 |
Working on it for v3. |
89 |
|
90 |
> Do you really want to try to construct some sort of 'testing' |
91 |
> settings object, or simply construct a list? |
92 |
|
93 |
I was going to use a dict for testing, and stub out a |
94 |
thirdpartymirrors mock for _get_uris. |
95 |
> > + third_party_mirror_uris = {} |
96 |
> > + filedict = OrderedDict() |
97 |
> > + primaryuri_dict = {} |
98 |
> > + for filename, uri in _get_file_uri_tuples(uris=uris): |
99 |
> > + if filename not in filedict: |
100 |
> > + filedict[filename] = [ |
101 |
> > + os.path.join(location, 'distfiles', |
102 |
> > filename) |
103 |
> > + for location in locations] |
104 |
> > + if uri is None: |
105 |
> > + continue |
106 |
> > + if uri.startswith('mirror://'): |
107 |
> > + uris = _expand_mirror( |
108 |
> > |
109 |
> |
110 |
> too many uri / uris variables... |
111 |
> |
112 |
> can we called this 'expanded_uris'? |
113 |
|
114 |
Queued for v3. |
115 |
|
116 |
> I'm really having trouble tracking what is what. Remember that |
117 |
> 'uris' is already a parameter to this function. Are you shadowing it |
118 |
> here, or trying to overwrite it? |
119 |
|
120 |
Clobbering it. The original value is only used for the |
121 |
_get_file_uri_tuples call. |
122 |
|
123 |
> > + uri=uri, custom_mirrors=custom_mirrors, |
124 |
> > + third_party_mirrors=third_party_mirrors) |
125 |
> > + filedict[filename].extend(uri for group, uri in |
126 |
> > uris) |
127 |
> > |
128 |
> |
129 |
> group appears unused in your implicit iterable here. |
130 |
> |
131 |
> perhaps: |
132 |
> |
133 |
> filedict[filename].extend(uri for _, uri in uris) |
134 |
|
135 |
Queued for v3. |
136 |
|
137 |
> > + third_party_mirror_uris.setdefault(filename, |
138 |
> > []).extend( |
139 |
> > + uri for group, uri in uris |
140 |
> > + if group == 'third-party') |
141 |
> > |
142 |
> |
143 |
> I'm curious if this matters. We are iterator over 'uris' twice. Is it |
144 |
> cheaper to do it once and build the iterables once? |
145 |
> |
146 |
> third_party_uris = [] |
147 |
> for group, uri in uris: |
148 |
> if group == 'third_party': |
149 |
> third_party_uris.append(uri) |
150 |
> filedict[filename].append(uri) |
151 |
> |
152 |
> I'm guessing the iterable is so small it doesn't matter. |
153 |
|
154 |
My guess is that the speed gain from list comprehension outweighs the |
155 |
loss of double iterations, but I agree that it is probably doesn't |
156 |
matter ;). |
157 |
|
158 |
> > + if not filedict[filename]: |
159 |
> > + writemsg( |
160 |
> > + _("No known mirror by the name: |
161 |
> > %s\n") |
162 |
> > + % (mirror,)) |
163 |
> > + else: |
164 |
> > + if restrict_fetch or force_mirror: |
165 |
> > |
166 |
> |
167 |
> Are these globals or am I missing somethng? |
168 |
|
169 |
Fixed in v2. |
170 |
|
171 |
|
172 |
> > + # Only fetch from specific mirrors is |
173 |
> > allowed. |
174 |
> > + continue |
175 |
> > + primaryuris = primaryuri_dict.get(filename) |
176 |
> > + if primaryuris is None: |
177 |
> > + primaryuris = [] |
178 |
> > + primaryuri_dict[filename] = primaryuris |
179 |
> > + primaryuris.append(uri) |
180 |
> > + |
181 |
> > + # Order primaryuri_dict values to match that in SRC_URI. |
182 |
> > + for uris in primaryuri_dict.values(): |
183 |
> > + uris.reverse() |
184 |
> |
185 |
> Is there any guaranteed ordering for dict.values()? |
186 |
|
187 |
No. |
188 |
|
189 |
> I thought dict order was random (and they seriously make it random |
190 |
> in modern python versions, to detect bugs.) How does this |
191 |
> uris.reverse() match the SRC_URI ordering? |
192 |
|
193 |
No idea (copy-pasted code). I'd be happy to cut this out in v3. |
194 |
|
195 |
> > + |
196 |
> > + # Prefer third_party_mirrors over normal mirrors in cases when |
197 |
> > + # the file does not yet exist on the normal mirrors. |
198 |
> > + for filename, uris in third_party_mirror_uris.items(): |
199 |
> > + primaryuri_dict.setdefault(filename, []).extend(uris) |
200 |
> > + |
201 |
> > + # Now merge primaryuri values into filedict (includes mirrors |
202 |
> > + # explicitly referenced in SRC_URI). |
203 |
> > + if "primaryuri" in restrict: |
204 |
> > |
205 |
> |
206 |
> same questoin here about where 'restrict' comes from. |
207 |
|
208 |
Fixed in v2. |
209 |
|
210 |
Thanks, |
211 |
Trevor |
212 |
|
213 |
-- |
214 |
This email may be signed or encrypted with GnuPG (http://www.gnupg.org). |
215 |
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy |