Skip to content

Commit

Permalink
Remove Python 2.7 support (#8760)
Browse files Browse the repository at this point in the history
* mvt remove ext2 packages

* update readme

* rm ext2 folder

* Update main readme

* Stop testing Python 2.7, add Python 3.9

* Update feedparser
  • Loading branch information
medariox committed Nov 24, 2020
1 parent ccc0e2a commit 1fd5d6c
Show file tree
Hide file tree
Showing 330 changed files with 2,184 additions and 66,947 deletions.
12 changes: 6 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ jobs:
- yarn lint-css
- yarn test
- yarn coverage
# backend tests (py2.7) start here
- name: 'Backend tests (py2.7)'
python: '2.7'
env:
- TOXENV=py27
<<: *_backend_tests
# backend tests (py3.6) start here
- name: 'Backend tests (py3.6)'
python: '3.6'
Expand All @@ -80,6 +74,12 @@ jobs:
env:
- TOXENV=py38
<<: *_backend_tests
# backend tests (py3.9) start here
- name: 'Backend tests (py3.9)'
python: '3.9'
env:
- TOXENV=py39
<<: *_backend_tests
# dredd tests (py3.7) start here
- name: 'Dredd tests (py3.7)'
python: '3.7'
Expand Down
14 changes: 6 additions & 8 deletions ext/feedparser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2010-2015 Kurt McKee <contactme@kurtmckee.org>
# Copyright 2010-2020 Kurt McKee <contactme@kurtmckee.org>
# Copyright 2002-2008 Mark Pilgrim
# All rights reserved.
#
Expand All @@ -25,22 +25,20 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE."""

from __future__ import absolute_import, unicode_literals
from .api import parse
from .datetimes import registerDateHandler
from .exceptions import *
from .util import FeedParserDict

__author__ = 'Kurt McKee <contactme@kurtmckee.org>'
__license__ = 'BSD 2-clause'
__version__ = '5.2.1'
__version__ = '6.0.2'

# HTTP "User-Agent" header to send to servers when downloading feeds.
# If you are embedding feedparser in a larger application, you should
# change this to your application name and URL.
USER_AGENT = "feedparser/%s +https://github.com/kurtmckee/feedparser/" % __version__

from . import api
from .api import parse
from .datetimes import registerDateHandler
from .exceptions import *

# If you want feedparser to automatically resolve all relative URIs, set this
# to 1.
RESOLVE_RELATIVE_URIS = 1
Expand Down
84 changes: 34 additions & 50 deletions ext/feedparser/api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The public API for feedparser
# Copyright 2010-2015 Kurt McKee <contactme@kurtmckee.org>
# Copyright 2010-2020 Kurt McKee <contactme@kurtmckee.org>
# Copyright 2002-2008 Mark Pilgrim
# All rights reserved.
#
Expand All @@ -26,27 +26,10 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

from __future__ import absolute_import, unicode_literals

import io
import urllib.parse
import xml.sax

try:
from io import BytesIO as _StringIO
except ImportError:
try:
from cStringIO import StringIO as _StringIO
except ImportError:
from StringIO import StringIO as _StringIO

try:
import urllib.parse
except ImportError:
from urlparse import urlparse

class urllib(object):
class parse(object):
urlparse = staticmethod(urlparse)

from .datetimes import registerDateHandler, _parse_date
from .encodings import convert_to_utf8
from .exceptions import *
Expand All @@ -58,17 +41,9 @@ class parse(object):
from .parsers.strict import _StrictFeedParser
from .sanitizer import replace_doctype
from .sgml import *
from .urls import _convert_to_idn, _makeSafeAbsoluteURI
from .urls import convert_to_idn, make_safe_absolute_uri
from .util import FeedParserDict

bytes_ = type(b'')
unicode_ = type('')
try:
unichr
basestring
except NameError:
unichr = chr
basestring = str

# List of preferred XML parsers, by SAX driver name. These will be tried first,
# but if they're not installed, Python will keep searching through its own list
Expand Down Expand Up @@ -96,6 +71,7 @@ class parse(object):
'cdf': 'CDF',
}


def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, handlers, request_headers, result):
"""URL, filename, or string --> stream
Expand Down Expand Up @@ -127,13 +103,13 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
if request_headers is supplied it is a dictionary of HTTP request headers
that will override the values generated by FeedParser.
:return: A :class:`StringIO.StringIO` or :class:`io.BytesIO`.
:return: A bytes object.
"""

if hasattr(url_file_stream_or_string, 'read'):
return url_file_stream_or_string.read()

if isinstance(url_file_stream_or_string, basestring) \
if isinstance(url_file_stream_or_string, str) \
and urllib.parse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp', 'file', 'feed'):
return http.get(url_file_stream_or_string, etag, modified, agent, referrer, handlers, request_headers, result)

Expand All @@ -142,7 +118,7 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
with open(url_file_stream_or_string, 'rb') as f:
data = f.read()
except (IOError, UnicodeEncodeError, TypeError, ValueError):
# if url_file_stream_or_string is a unicode object that
# if url_file_stream_or_string is a str object that
# cannot be converted to the encoding returned by
# sys.getfilesystemencoding(), a UnicodeEncodeError
# will be thrown
Expand All @@ -154,19 +130,26 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
return data

# treat url_file_stream_or_string as string
if not isinstance(url_file_stream_or_string, bytes_):
if not isinstance(url_file_stream_or_string, bytes):
return url_file_stream_or_string.encode('utf-8')
return url_file_stream_or_string

LooseFeedParser = type(str('LooseFeedParser'), (
_LooseFeedParser, _FeedParserMixin, _BaseHTMLProcessor, object
), {})
StrictFeedParser = type(str('StrictFeedParser'), (
_StrictFeedParser, _FeedParserMixin, xml.sax.handler.ContentHandler, object
), {})

LooseFeedParser = type(
'LooseFeedParser',
(_LooseFeedParser, _FeedParserMixin, _BaseHTMLProcessor, object),
{},
)

StrictFeedParser = type(
'StrictFeedParser',
(_StrictFeedParser, _FeedParserMixin, xml.sax.handler.ContentHandler, object),
{},
)


def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=None, request_headers=None, response_headers=None, resolve_relative_uris=None, sanitize_html=None):
'''Parse a feed from a URL, file, stream, or string.
"""Parse a feed from a URL, file, stream, or string.
:param url_file_stream_or_string:
File-like object, URL, file path, or string. Both byte and text strings
Expand Down Expand Up @@ -210,7 +193,8 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
:data:`feedparser.SANITIZE_HTML`, which is ``True``.
:return: A :class:`FeedParserDict`.
'''
"""

if not agent or sanitize_html is None or resolve_relative_uris is None:
import feedparser
if not agent:
Expand All @@ -221,10 +205,10 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
resolve_relative_uris = feedparser.RESOLVE_RELATIVE_URIS

result = FeedParserDict(
bozo = False,
entries = [],
feed = FeedParserDict(),
headers = {},
bozo=False,
entries=[],
feed=FeedParserDict(),
headers={},
)

data = _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, handlers, request_headers, result)
Expand All @@ -243,10 +227,10 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
# Ensure that baseuri is an absolute URI using an acceptable URI scheme.
contentloc = result['headers'].get('content-location', '')
href = result.get('href', '')
baseuri = _makeSafeAbsoluteURI(href, contentloc) or _makeSafeAbsoluteURI(contentloc) or href
baseuri = make_safe_absolute_uri(href, contentloc) or make_safe_absolute_uri(contentloc) or href

baselang = result['headers'].get('content-language', None)
if isinstance(baselang, bytes_) and baselang is not None:
if isinstance(baselang, bytes) and baselang is not None:
baselang = baselang.decode('utf-8', 'ignore')

if not _XML_AVAILABLE:
Expand All @@ -266,20 +250,20 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
saxparser.setContentHandler(feedparser)
saxparser.setErrorHandler(feedparser)
source = xml.sax.xmlreader.InputSource()
source.setByteStream(_StringIO(data))
source.setByteStream(io.BytesIO(data))
try:
saxparser.parse(source)
except xml.sax.SAXException as e:
result['bozo'] = 1
result['bozo_exception'] = feedparser.exc or e
use_strict_parser = 0
if not use_strict_parser and _SGML_AVAILABLE:
if not use_strict_parser:
feedparser = LooseFeedParser(baseuri, baselang, 'utf-8', entities)
feedparser.resolve_relative_uris = resolve_relative_uris
feedparser.sanitize_html = sanitize_html
feedparser.feed(data.decode('utf-8', 'replace'))
result['feed'] = feedparser.feeddata
result['entries'] = feedparser.entries
result['version'] = result['version'] or feedparser.version
result['namespaces'] = feedparser.namespacesInUse
result['namespaces'] = feedparser.namespaces_in_use
return result
43 changes: 36 additions & 7 deletions ext/feedparser/datetimes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
from __future__ import absolute_import
# Copyright 2010-2020 Kurt McKee <contactme@kurtmckee.org>
# Copyright 2002-2008 Mark Pilgrim
# All rights reserved.
#
# This file is a part of feedparser.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

from .asctime import _parse_date_asctime
from .greek import _parse_date_greek
Expand All @@ -10,18 +35,21 @@
from .w3dtf import _parse_date_w3dtf

_date_handlers = []


def registerDateHandler(func):
'''Register a date handler function (takes string, returns 9-tuple date in GMT)'''
"""Register a date handler function (takes string, returns 9-tuple date in GMT)"""
_date_handlers.insert(0, func)

def _parse_date(dateString):
'''Parses a variety of date formats into a 9-tuple in GMT'''
if not dateString:

def _parse_date(date_string):
"""Parses a variety of date formats into a 9-tuple in GMT"""
if not date_string:
return None
for handler in _date_handlers:
try:
date9tuple = handler(dateString)
except (KeyError, OverflowError, ValueError):
date9tuple = handler(date_string)
except (KeyError, OverflowError, ValueError, AttributeError):
continue
if not date9tuple:
continue
Expand All @@ -30,6 +58,7 @@ def _parse_date(dateString):
return date9tuple
return None


registerDateHandler(_parse_date_onblog)
registerDateHandler(_parse_date_nate)
registerDateHandler(_parse_date_greek)
Expand Down
45 changes: 42 additions & 3 deletions ext/feedparser/datetimes/asctime.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,48 @@
from __future__ import absolute_import, unicode_literals
# Copyright 2010-2020 Kurt McKee <contactme@kurtmckee.org>
# Copyright 2002-2008 Mark Pilgrim
# All rights reserved.
#
# This file is a part of feedparser.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

from .rfc822 import _parse_date_rfc822

_months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',
'jul', 'aug', 'sep', 'oct', 'nov', 'dec']
_months = [
'jan',
'feb',
'mar',
'apr',
'may',
'jun',
'jul',
'aug',
'sep',
'oct',
'nov',
'dec',
]


def _parse_date_asctime(dt):
"""Parse asctime-style dates.
Expand Down
Loading

0 comments on commit 1fd5d6c

Please sign in to comment.