Verified Commit edccd5cc authored by Antoine Beaupré's avatar Antoine Beaupré
Browse files

initialize FeedFetcher session singleton properly

without this, the wayback plugin would fail because it
FeedFetcher._session is None. doing this in the constructor makes the
accessor faster as well, as we don't need to do another check.

this should resolve a bug I found in the last run, which we *can't*
write unit tests for (because we use betamax in tests, which properly
set the class-level session):

plugin generated exception: 'NoneType' object has no attribute 'head', skipping
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/feed2exec/plugins/__init__.py", line 96, in output
    return plugin.output(*args, feed=feed, item=item, lock=lock)
  File "/usr/local/lib/python3.5/dist-packages/feed2exec/plugins/wayback.py", line 28, in output
    res = session.head('%s/save/%s' % (WAYBACK_URL, item.get('link')))
AttributeError: 'NoneType' object has no attribute 'head'
parent 6ea2b27e
Loading
Loading
Loading
Loading
Loading
+18 −16
Original line number Diff line number Diff line
@@ -152,27 +152,29 @@ def parse(body, feed, lock=None, force=False):


class FeedFetcher(object):
    """a feed fetcher can be used to fetch multiple feeds.

    it is an abstract class that should be derived using another
    storage class that can be iterated open.

    on intialization, a new :class:`requests.Session` object is
    created to be used across all requests. therefore, as long as a
    first FeedFetcher() object was created, FeedFetcher._session can
    be used by plugins.
    """

    #: class :class:`request.Session` object that can be used by plugins
    #: to make HTTP requests. initialized in main() or the test suite.
    #: to make HTTP requests. initialized in __init__() or in test suite
    _session = None

    def __init__(self):
        # reuse class level session
        if FeedFetcher._session is None:
            FeedFetcher._session = self.session = requests.Session()

    @property
    def session(self):
        """the session property

        will initialize this to an preconfigured Session if not set
        yet. note that this won't work with the class-level parameter,
        as it requires a "self", so there are two options to set the
        session:

         1. work on an intialized FeedStorage object, or;

         2. explicitly set FeedFetcher._session manually - do not
            forget to also configure it with
            func:`feed2exec.feeds.FeedFetcher.sessionConfig`
        """
        if self._session is None:
            self.session = requests.Session()
        """the session property"""
        return self._session

    @session.setter