diff --git a/scrapy/contrib/feedexport.py b/scrapy/contrib/feedexport.py index 941f9633e..92664220c 100644 --- a/scrapy/contrib/feedexport.py +++ b/scrapy/contrib/feedexport.py @@ -10,7 +10,7 @@ from datetime import datetime from six.moves.urllib.parse import urlparse from ftplib import FTP -from zope.interface import Interface, implements +from zope.interface import Interface, implementer from twisted.internet import defer, threads from w3lib.url import file_uri_to_path @@ -35,10 +35,9 @@ class IFeedStorage(Interface): """Store the given file stream""" +@implementer(IFeedStorage) class BlockingFeedStorage(object): - implements(IFeedStorage) - def open(self, spider): return TemporaryFile(prefix='feed-') @@ -49,10 +48,9 @@ class BlockingFeedStorage(object): raise NotImplementedError +@implementer(IFeedStorage) class StdoutFeedStorage(object): - implements(IFeedStorage) - def __init__(self, uri, _stdout=sys.stdout): self._stdout = _stdout @@ -62,9 +60,9 @@ class StdoutFeedStorage(object): def store(self, file): pass -class FileFeedStorage(object): - implements(IFeedStorage) +@implementer(IFeedStorage) +class FileFeedStorage(object): def __init__(self, uri): self.path = file_uri_to_path(uri) @@ -78,6 +76,7 @@ class FileFeedStorage(object): def store(self, file): file.close() + class S3FeedStorage(BlockingFeedStorage): def __init__(self, uri): @@ -131,6 +130,7 @@ class SpiderSlot(object): self.uri = uri self.itemcount = 0 + class FeedExporter(object): def __init__(self, settings): diff --git a/tests/py3-ignores.txt b/tests/py3-ignores.txt index ea69e21de..05adb9429 100644 --- a/tests/py3-ignores.txt +++ b/tests/py3-ignores.txt @@ -5,7 +5,6 @@ tests/test_command_shell.py tests/test_commands.py tests/test_command_version.py tests/test_contrib_exporter.py -tests/test_contrib_feedexport.py tests/test_contrib_linkextractors.py tests/test_contrib_loader.py tests/test_crawl.py @@ -92,7 +91,6 @@ scrapy/contrib/downloadermiddleware/cookies.py scrapy/contrib/downloadermiddleware/ajaxcrawl.py scrapy/contrib/statsmailer.py scrapy/contrib/memusage.py -scrapy/contrib/feedexport.py scrapy/commands/deploy.py scrapy/commands/bench.py scrapy/telnet.py diff --git a/tests/test_contrib_feedexport.py b/tests/test_contrib_feedexport.py index bf4943bfa..7e2fc0f66 100644 --- a/tests/test_contrib_feedexport.py +++ b/tests/test_contrib_feedexport.py @@ -41,10 +41,11 @@ class FileFeedStorageTest(unittest.TestCase): def _assert_stores(self, storage, path): spider = Spider("default") file = storage.open(spider) - file.write("content") + file.write(b"content") yield storage.store(file) self.failUnless(os.path.exists(path)) - self.failUnlessEqual(open(path).read(), "content") + with open(path, 'rb') as fp: + self.failUnlessEqual(fp.read(), b"content") class FTPFeedStorageTest(unittest.TestCase): @@ -65,10 +66,12 @@ class FTPFeedStorageTest(unittest.TestCase): file.write(b"content") yield storage.store(file) self.failUnless(os.path.exists(path)) - self.failUnlessEqual(open(path).read(), b"content") + with open(path, 'rb') as fp: + self.failUnlessEqual(fp.read(), b"content") # again, to check s3 objects are overwritten yield storage.store(BytesIO(b"new content")) - self.failUnlessEqual(open(path).read(), b"new content") + with open(path, 'rb') as fp: + self.failUnlessEqual(fp.read(), b"new content") class S3FeedStorageTest(unittest.TestCase):