[MRG+1] Backwards compatible per key priorities #1586
Conversation
@jdemaeyer there is a failure in docs check, could you please fix it? |
1a35a0c
to
0c97a75
Current coverage is
|
ugh damnit, thanks, fixed. |
@jdemaeyer yes, our code works as expected on this PR. Thanks. |
if name not in self:
return None
return self.attributes[name].priority |
Yep, it's supported and got lost while I reverted the docs to "with _BASE", will put it back in. They're disabled by setting their class to
Nope. Though with this PR we could support it again (although it has been deprecated for over two years).
Hm, calling
Looks good, we should update |
Do we have use cases for a public |
Ok, I'm fine with dropping support for ITEM_PIPELINE as a list, but we should remember to add it to the release notes. It is easy to miss because this change was not in a separate PR. |
All done. Instead of |
is the one closer to the spider. | ||
|
||
To decide which order to assign to your middleware see the | ||
:setting:`SPIDER_MIDDLEWARES_BASE` setting and pick a value according to where | ||
middleware performs a different action and your middleware could depend on some |
curita
Nov 11, 2015
Member
Line 34 from the original version got deleted (https://github.com/scrapy/scrapy/pull/1586/files#diff-17a393aa4b57b33782da9b32c3422e73L34). It should be "<...> and pick a value according to where you want to insert the middleware. The order does matter because each middleware performs <...>".
Line 34 from the original version got deleted (https://github.com/scrapy/scrapy/pull/1586/files#diff-17a393aa4b57b33782da9b32c3422e73L34). It should be "<...> and pick a value according to where you want to insert the middleware. The order does matter because each middleware performs <...>".
kmike
Nov 11, 2015
Member
i also noticed that, but the sentence reads fine without this line :)
i also noticed that, but the sentence reads fine without this line :)
There's a remaining |
Not sure what's the long term plan for *_BASE settings now, but if we plan to keep them for good we could implement |
:type name: string | ||
""" | ||
compdict = self.get(name + '_BASE', {}).copy() | ||
compdict.update(self.get(name, {})) |
curita
Nov 11, 2015
Member
Wanted to point out here that since we're promoting <name>_BASE
settings to BaseSettings instances, .copy()
does a deep copy of <name>_BASE
, but we're passing <name>
as it is when updating that copy. We could be consistent and use self.get(name, {}).copy()
but doesn't matter too much since we don't have mutable values in default dict settings.
Wanted to point out here that since we're promoting <name>_BASE
settings to BaseSettings instances, .copy()
does a deep copy of <name>_BASE
, but we're passing <name>
as it is when updating that copy. We could be consistent and use self.get(name, {}).copy()
but doesn't matter too much since we don't have mutable values in default dict settings.
if priority >= self.priority: | ||
if isinstance(self.value, BaseSettings): | ||
self.value.clear() | ||
self.value.update(value, priority=priority) |
curita
Nov 11, 2015
Member
It could be a little odd having a reference for value
(gotten from .get()
for example) and having it changed when setting something new, as set()
was supposed to override the value, not change it. Maybe we could create a new BaseSettings instance?
It could be a little odd having a reference for value
(gotten from .get()
for example) and having it changed when setting something new, as set()
was supposed to override the value, not change it. Maybe we could create a new BaseSettings instance?
kmike
Nov 11, 2015
Member
good catch, +1
good catch, +1
Pointed out some minor issues, but after reviewing these changes I still kind of prefer the approach in #1149. Here are some of my (truly subjective) thoughts about it:
Well, having explained myself, I don't think it's worth of a discussion really, this PR seems the way to go. Probably we should try to follow any backward compatible option if there is one, and the magic helper for updating dictionaries you were talking about is just what I'm looking for. So +1 on my side once the nitpicks I commented before get fixed |
Damnit! :/ thanks alot for the catches/feedback everyone! I've implemented Julia's feedback. There is now no deep-copying at all in I'll squash commits once you've looked at the changes. |
9176af4
to
4f36476
Perfect! Thank you both @jdemaeyer and @kmike :) I'll be merging it now. |
…key-priorities [MRG+1] Backwards compatible per key priorities
This is a partial reversal of #1149 that provides per-key priorities in a backwards compatible fashion.
The backwards incompatible API change in #1149 was that when writing to dictionary settings, their contents were updated, not completely overwritten. This PR brings back the old behaviour of completely discarding the previous contents of the dictionary. If the dictionary setting written to is a
BaseSettings
instance, it is not overwritten but cleared and then updated (resulting in the same contents, but conserving per-key priorities).The price for this is:
_BASE
settingscustom_settings
(because disabling a single component requires writing down the complete dictionary without that component). @kmike had the idea that we could add some helper magic for updating (not overwriting) dictionaries, e.g. allow people to doscrapy ... -s update:EXTENSIONS={"blah": null}
, orcustom_settings: { "update:EXTENSIONS": {"blah": None}}
. I'll implement that in a follow-up PR to discuss it and see if it makes unforeseen trouble.As a bonus, I added backwards compatibility to the
build_component_list()
utility function, albeit it not being public. @rolando maybe you could check whether it is indeed backwards compatible with how you use it? Also take a look at the now-publicBaseSettings.getcomposite()
method. It helps in separating a utility function that's meant to convert a dictionary into a sorted list from how that dictionary is created.