Skip to content
Permalink
Browse files

Merge pull request #2649 from iKevinY/py2-sunset

Remove Python 2 support
  • Loading branch information
justinmayer committed Nov 26, 2019
2 parents bae6de5 + 1696883 commit 772005f431e85abe9e4b09ad5bba9f87fe5a5b5e
Showing with 203 additions and 627 deletions.
  1. +0 −1 .gitignore
  2. +0 −1 .travis.yml
  3. +2 −0 THANKS
  4. +0 −1 docs/conf.py
  5. +5 −22 pelican/__init__.py
  6. +0 −1 pelican/__main__.py
  7. +4 −9 pelican/cache.py
  8. +17 −27 pelican/contents.py
  9. +6 −14 pelican/generators.py
  10. +10 −55 pelican/log.py
  11. +1 −4 pelican/paginator.py
  12. +21 −43 pelican/readers.py
  13. +1 −4 pelican/rstdirectives.py
  14. +7 −10 pelican/server.py
  15. +11 −21 pelican/settings.py
  16. +0 −1 pelican/signals.py
  17. +0 −1 pelican/tests/default_conf.py
  18. +4 −6 pelican/tests/support.py
  19. +0 −1 pelican/tests/test_cache.py
  20. +10 −19 pelican/tests/test_contents.py
  21. +0 −2 pelican/tests/test_generators.py
  22. +0 −2 pelican/tests/test_importer.py
  23. +1 −2 pelican/tests/test_paginator.py
  24. +4 −9 pelican/tests/test_pelican.py
  25. +3 −8 pelican/tests/test_readers.py
  26. +0 −1 pelican/tests/test_rstdirectives.py
  27. +1 −2 pelican/tests/test_server.py
  28. +0 −1 pelican/tests/test_settings.py
  29. +0 −1 pelican/tests/test_testsuite.py
  30. +0 −1 pelican/tests/test_urlwrappers.py
  31. +2 −7 pelican/tests/test_utils.py
  32. +8 −37 pelican/tools/pelican_import.py
  33. +37 −61 pelican/tools/pelican_quickstart.py
  34. +0 −1 pelican/tools/pelican_themes.py
  35. +0 −1 pelican/tools/templates/pelicanconf.py.jinja2
  36. +0 −1 pelican/tools/templates/publishconf.py.jinja2
  37. +7 −11 pelican/urlwrappers.py
  38. +25 −93 pelican/utils.py
  39. +2 −9 pelican/writers.py
  40. +7 −119 poetry.lock
  41. +2 −5 pyproject.toml
  42. +0 −1 samples/pelican.conf.py
  43. +0 −1 samples/pelican.conf_FR.py
  44. +4 −8 setup.py
  45. +1 −2 tox.ini
@@ -11,7 +11,6 @@ tags
.tox
.coverage
htmlcov
six-*.egg/
*.orig
venv
samples/output
@@ -11,7 +11,6 @@ env:
matrix:
- TOX_ENV=docs
- TOX_ENV=flake8
- TOX_ENV=py27
- TOX_ENV=py35
- TOX_ENV=py36
matrix:
2 THANKS
@@ -92,6 +92,7 @@ Joshua Adelman
Julian Berman
Justin Mayer
Kevin Deldycke
Kevin Yap
Kyle Fuller
Laureline Guerin
Leonard Huang
@@ -117,6 +118,7 @@ Nico Di Rocco
Nicolas Duhamel
Nicolas Perriault
Nicolas Steinmetz
Paolo Melchiorre
Paul Asselin
Pavel Puchkin
Perry Roper
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import os
import sys
@@ -1,21 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals

import argparse
try:
import collections.abc as collections
except ImportError:
import collections
import locale
import logging
import multiprocessing
import os
import pprint
import sys
import time
import traceback

import six
from collections.abc import Iterable

# pelican.log has to be the first pelican module to be loaded
# because logging.setLoggerClass has to be called before logging.getLogger
@@ -76,11 +69,10 @@ def init_plugins(self):
sys.path.insert(0, pluginpath)
for plugin in self.settings['PLUGINS']:
# if it's a string, then import it
if isinstance(plugin, six.string_types):
if isinstance(plugin, str):
logger.debug("Loading plugin `%s`", plugin)
try:
plugin = __import__(plugin, globals(), locals(),
str('module'))
plugin = __import__(plugin, globals(), locals(), 'module')
except ImportError as e:
logger.error(
"Cannot load plugin `%s`\n%s", plugin, e)
@@ -189,7 +181,7 @@ def get_generator_classes(self):
for pair in signals.get_generators.send(self):
(funct, value) = pair

if not isinstance(value, collections.Iterable):
if not isinstance(value, Iterable):
value = (value, )

for v in value:
@@ -375,15 +367,6 @@ def get_config(args):
config['BIND'] = args.bind
config['DEBUG'] = args.verbosity == logging.DEBUG

# argparse returns bytes in Py2. There is no definite answer as to which
# encoding argparse (or sys.argv) uses.
# "Best" option seems to be locale.getpreferredencoding()
# http://mail.python.org/pipermail/python-list/2006-October/405766.html
if not six.PY3:
enc = locale.getpreferredencoding()
for key in config:
if key in ('PATH', 'OUTPUT_PATH', 'THEME'):
config[key] = config[key].decode(enc)
return config


@@ -397,7 +380,7 @@ def get_instance(args):
settings = read_settings(config_file, override=get_config(args))

cls = settings['PELICAN_CLASS']
if isinstance(cls, six.string_types):
if isinstance(cls, str):
module, cls_name = cls.rsplit('.', 1)
module = __import__(module)
cls = getattr(module, cls_name)
@@ -1,7 +1,6 @@
"""
python -m pelican module entry point to run via python -m
"""
from __future__ import absolute_import

from . import main

@@ -1,11 +1,9 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import hashlib
import logging
import os

from six.moves import cPickle as pickle
import pickle

from pelican.utils import mkdir_p

@@ -82,9 +80,7 @@ def __init__(self, settings, cache_name, caching_policy, load_policy):
and base path for filestamping operations
"""

super(FileStampDataCacher, self).__init__(settings, cache_name,
caching_policy,
load_policy)
super().__init__(settings, cache_name, caching_policy, load_policy)

method = self.settings['CHECK_MODIFIED_METHOD']
if method == 'mtime':
@@ -106,7 +102,7 @@ def filestamp_func(filename):
def cache_data(self, filename, data):
"""Cache stamp and data for the given file"""
stamp = self._get_file_stamp(filename)
super(FileStampDataCacher, self).cache_data(filename, (stamp, data))
super().cache_data(filename, (stamp, data))

def _get_file_stamp(self, filename):
"""Check if the given file has been modified
@@ -134,8 +130,7 @@ def get_cached_data(self, filename, default=None):
and current file stamp.
"""

stamp, data = super(FileStampDataCacher, self).get_cached_data(
filename, (None, default))
stamp, data = super().get_cached_data(filename, (None, default))
if stamp != self._get_file_stamp(filename):
return default
return data
@@ -1,33 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals

import copy
import datetime
import locale
import logging
import os
import re
import sys
from urllib.parse import urljoin, urlparse, urlunparse

import pytz

import six
from six.moves.urllib.parse import urljoin, urlparse, urlunparse

from pelican import signals
from pelican.settings import DEFAULT_CONFIG
from pelican.utils import (SafeDatetime, deprecated_attribute, memoized,
path_to_url, posixize_path,
python_2_unicode_compatible, sanitised_join,
set_date_tzinfo, slugify, strftime,
truncate_html_words)
from pelican.utils import (deprecated_attribute, memoized, path_to_url,
posixize_path, sanitised_join, set_date_tzinfo,
slugify, truncate_html_words)

# Import these so that they're avalaible when you import from pelican.contents.
from pelican.urlwrappers import (Author, Category, Tag, URLWrapper) # NOQA

logger = logging.getLogger(__name__)


@python_2_unicode_compatible
class Content(object):
"""Represents a content.
@@ -121,9 +115,6 @@ def __init__(self, content, metadata=None, settings=None,

if isinstance(self.date_format, tuple):
locale_string = self.date_format[0]
if sys.version_info < (3, ) and isinstance(locale_string,
six.text_type):
locale_string = locale_string.encode('ascii')
locale.setlocale(locale.LC_ALL, locale_string)
self.date_format = self.date_format[1]

@@ -133,11 +124,11 @@ def __init__(self, content, metadata=None, settings=None,

if hasattr(self, 'date'):
self.date = set_date_tzinfo(self.date, timezone)
self.locale_date = strftime(self.date, self.date_format)
self.locale_date = self.date.strftime(self.date_format)

if hasattr(self, 'modified'):
self.modified = set_date_tzinfo(self.modified, timezone)
self.locale_modified = strftime(self.modified, self.date_format)
self.locale_modified = self.modified.strftime(self.date_format)

# manage status
if not hasattr(self, 'status'):
@@ -213,7 +204,7 @@ def url_format(self):
'path': path_to_url(path),
'slug': getattr(self, 'slug', ''),
'lang': getattr(self, 'lang', 'en'),
'date': getattr(self, 'date', SafeDatetime.now()),
'date': getattr(self, 'date', datetime.datetime.now()),
'author': self.author.slug if hasattr(self, 'author') else '',
'category': self.category.slug if hasattr(self, 'category') else ''
})
@@ -497,7 +488,7 @@ class Page(Content):

def _expand_settings(self, key):
klass = 'draft_page' if self.status == 'draft' else None
return super(Page, self)._expand_settings(key, klass)
return super()._expand_settings(key, klass)


class Article(Content):
@@ -507,34 +498,33 @@ class Article(Content):
default_template = 'article'

def __init__(self, *args, **kwargs):
super(Article, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

# handle WITH_FUTURE_DATES (designate article to draft based on date)
if not self.settings['WITH_FUTURE_DATES'] and hasattr(self, 'date'):
if self.date.tzinfo is None:
now = SafeDatetime.now()
now = datetime.datetime.now()
else:
now = SafeDatetime.utcnow().replace(tzinfo=pytz.utc)
now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
if self.date > now:
self.status = 'draft'

# if we are a draft and there is no date provided, set max datetime
if not hasattr(self, 'date') and self.status == 'draft':
self.date = SafeDatetime.max
self.date = datetime.datetime.max

def _expand_settings(self, key):
klass = 'draft' if self.status == 'draft' else 'article'
return super(Article, self)._expand_settings(key, klass)
return super()._expand_settings(key, klass)


@python_2_unicode_compatible
class Static(Content):
mandatory_properties = ('title',)
default_status = 'published'
default_template = None

def __init__(self, *args, **kwargs):
super(Static, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._output_location_referenced = False

@deprecated_attribute(old='filepath', new='source_path', since=(3, 2, 0))
@@ -553,13 +543,13 @@ def dst():
def url(self):
# Note when url has been referenced, so we can avoid overriding it.
self._output_location_referenced = True
return super(Static, self).url
return super().url

@property
def save_as(self):
# Note when save_as has been referenced, so we can avoid overriding it.
self._output_location_referenced = True
return super(Static, self).save_as
return super().save_as

def attach_to(self, content):
"""Override our output directory with that of the given content object.
@@ -1,12 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals

import calendar
import errno
import fnmatch
import logging
import os
from codecs import open
from collections import defaultdict
from functools import partial
from itertools import chain, groupby
@@ -15,15 +13,12 @@
from jinja2 import (BaseLoader, ChoiceLoader, Environment, FileSystemLoader,
PrefixLoader, TemplateNotFound)

import six

from pelican import signals
from pelican.cache import FileStampDataCacher
from pelican.contents import Article, Page, Static
from pelican.readers import Readers
from pelican.utils import (DateFormatter, copy, mkdir_p, order_content,
posixize_path, process_translations,
python_2_unicode_compatible)
posixize_path, process_translations)


logger = logging.getLogger(__name__)
@@ -33,7 +28,6 @@ class PelicanTemplateNotFound(Exception):
pass


@python_2_unicode_compatible
class Generator(object):
"""Baseclass generator"""

@@ -138,7 +132,7 @@ def get_files(self, paths, exclude=[], extensions=None):
extensions are allowed)
"""
# backward compatibility for older generators
if isinstance(paths, six.string_types):
if isinstance(paths, str):
paths = [paths]

# group the exclude dir names by parent path, for use with os.walk()
@@ -247,7 +241,7 @@ def __init__(self, *args, **kwargs):
def _get_file_stamp(self, filename):
'''Get filestamp for path relative to generator.path'''
filename = os.path.join(self.path, filename)
return super(CachingGenerator, self)._get_file_stamp(filename)
return super()._get_file_stamp(filename)


class _FileLoader(BaseLoader):
@@ -294,7 +288,7 @@ def __init__(self, *args, **kwargs):
self.authors = defaultdict(list)
self.drafts = [] # only drafts in default language
self.drafts_translations = []
super(ArticlesGenerator, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
signals.article_generator_init.send(self)

def generate_feeds(self, writer):
@@ -513,8 +507,6 @@ def _generate_period_archives(dates, key, save_as_fmt, url_fmt):
context["period"] = (_period,)
else:
month_name = calendar.month_name[_period[1]]
if not six.PY3:
month_name = month_name.decode('utf-8')
if key == period_date_key['month']:
context["period"] = (_period[0],
month_name)
@@ -707,7 +699,7 @@ def __init__(self, *args, **kwargs):
self.hidden_translations = []
self.draft_pages = []
self.draft_translations = []
super(PagesGenerator, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
signals.page_generator_init.send(self)

def generate_context(self):
@@ -793,7 +785,7 @@ class StaticGenerator(Generator):
to output"""

def __init__(self, *args, **kwargs):
super(StaticGenerator, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fallback_to_symlinks = False
signals.static_generator_init.send(self)

0 comments on commit 772005f

Please sign in to comment.
You can’t perform that action at this time.