Merge pull request #1746 from redapple/shell-settings-logging

[MRG+1] Remove __str__ and __repr__ from settings, introduce copy_to_dict()
This commit is contained in:
Mikhail Korobov 2016-02-03 19:59:24 +05:00
commit 43a53aca12
4 changed files with 49 additions and 14 deletions

View File

@ -1,5 +1,8 @@
from __future__ import print_function
import json
from scrapy.commands import ScrapyCommand
from scrapy.settings import BaseSettings
class Command(ScrapyCommand):
@ -28,7 +31,11 @@ class Command(ScrapyCommand):
def run(self, args, opts):
settings = self.crawler_process.settings
if opts.get:
print(settings.get(opts.get))
s = settings.get(opts.get)
if isinstance(s, BaseSettings):
print(json.dumps(s.copy_to_dict()))
else:
print(s)
elif opts.getbool:
print(settings.getbool(opts.getbool))
elif opts.getint:

View File

@ -4,6 +4,7 @@ import copy
import warnings
from collections import MutableMapping
from importlib import import_module
from pprint import pformat
from scrapy.utils.deprecate import create_deprecated_class
from scrapy.exceptions import ScrapyDeprecationWarning
@ -368,11 +369,31 @@ class BaseSettings(MutableMapping):
def __len__(self):
return len(self.attributes)
def __str__(self):
return str(self.attributes)
def _to_dict(self):
return {k: (v._to_dict() if isinstance(v, BaseSettings) else v)
for k, v in six.iteritems(self)}
def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, self.attributes)
def copy_to_dict(self):
"""
Make a copy of current settings and convert to a dict.
This method returns a new dict populated with the same values
and their priorities as the current settings.
Modifications to the returned dict won't be reflected on the original
settings.
This method can be useful for example for printing settings
in Scrapy shell.
"""
settings = self.copy()
return settings._to_dict()
def _repr_pretty_(self, p, cycle):
if cycle:
p.text(repr(self))
else:
p.text(pformat(self.copy_to_dict()))
@property
def overrides(self):

View File

@ -68,4 +68,4 @@ class CmdlineTest(unittest.TestCase):
settingsstr = settingsstr.replace(char, '"')
settingsdict = json.loads(settingsstr)
six.assertCountEqual(self, settingsdict.keys(), EXTENSIONS.keys())
self.assertIn('value=200', settingsdict[EXT_PATH])
self.assertEquals(200, settingsdict[EXT_PATH])

View File

@ -302,6 +302,21 @@ class BaseSettingsTest(unittest.TestCase):
self.assertListEqual(copy.get('TEST_LIST_OF_LISTS')[0],
['first_one', 'first_two'])
def test_copy_to_dict(self):
s = BaseSettings({'TEST_STRING': 'a string',
'TEST_LIST': [1, 2],
'TEST_BOOLEAN': False,
'TEST_BASE': BaseSettings({1: 1, 2: 2}, 'project'),
'TEST': BaseSettings({1: 10, 3: 30}, 'default'),
'HASNOBASE': BaseSettings({3: 3000}, 'default')})
self.assertDictEqual(s.copy_to_dict(),
{'HASNOBASE': {3: 3000},
'TEST': {1: 10, 3: 30},
'TEST_BASE': {1: 1, 2: 2},
'TEST_BOOLEAN': False,
'TEST_LIST': [1, 2],
'TEST_STRING': 'a string'})
def test_freeze(self):
self.settings.freeze()
with self.assertRaises(TypeError) as cm:
@ -343,14 +358,6 @@ class BaseSettingsTest(unittest.TestCase):
self.assertEqual(self.settings.defaults.get('BAR'), 'foo')
self.assertIn('BAR', self.settings.defaults)
def test_repr(self):
settings = BaseSettings()
self.assertEqual(repr(settings), "<BaseSettings {}>")
attr = SettingsAttribute('testval', 15)
settings['testkey'] = attr
self.assertEqual(repr(settings),
"<BaseSettings {'testkey': %s}>" % repr(attr))
class SettingsTest(unittest.TestCase):