1
0
Fork 0
forked from github/pelican

Initial pass of removing Python 2 support

This commit removes Six as a dependency for Pelican, replacing the
relevant aliases with the proper Python 3 imports. It also removes
references to Python 2 logic that did not require Six.
This commit is contained in:
Kevin Yap 2019-11-05 23:17:19 -08:00
commit 1e0e541b57
43 changed files with 126 additions and 459 deletions

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
import argparse
import logging
@ -11,10 +10,9 @@ import sys
import time
from codecs import open
from collections import defaultdict
from six.moves.urllib.error import URLError
from six.moves.urllib.parse import quote, urlparse, urlsplit, urlunsplit
from six.moves.urllib.request import urlretrieve
from urllib.error import URLError
from urllib.parse import quote, urlparse, urlsplit, urlunsplit
from urllib.request import urlretrieve
# because logging.setLoggerClass has to be called before logging.getLogger
from pelican.log import init
@ -24,7 +22,7 @@ from pelican.utils import SafeDatetime, slugify
try:
from html import unescape # py3.5+
except ImportError:
from six.moves.html_parser import HTMLParser
from html.parser import HTMLParser
unescape = HTMLParser().unescape
logger = logging.getLogger(__name__)
@ -396,19 +394,8 @@ def posterous2fields(api_token, email, password):
"""Imports posterous posts"""
import base64
from datetime import timedelta
try:
# py3k import
import json
except ImportError:
# py2 import
import simplejson as json
try:
# py3k import
import urllib.request as urllib_request
except ImportError:
# py2 import
import urllib2 as urllib_request
import json
import urllib.request as urllib_request
def get_posterous_posts(api_token, email, password, page=1):
base64string = base64.encodestring(
@ -451,19 +438,8 @@ def posterous2fields(api_token, email, password):
def tumblr2fields(api_key, blogname):
""" Imports Tumblr posts (API v2)"""
try:
# py3k import
import json
except ImportError:
# py2 import
import simplejson as json
try:
# py3k import
import urllib.request as urllib_request
except ImportError:
# py2 import
import urllib2 as urllib_request
import json
import urllib.request as urllib_request
def get_tumblr_posts(api_key, blogname, offset=0):
url = ("http://api.tumblr.com/v2/blog/%s.tumblr.com/"

View file

@ -1,12 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
import argparse
import codecs
import locale
import os
import sys
from jinja2 import Environment, FileSystemLoader
@ -23,8 +21,6 @@ try:
except ImportError:
_DEFAULT_TIMEZONE = 'Europe/Paris'
import six
from pelican import __version__
locale.setlocale(locale.LC_ALL, '')
@ -77,41 +73,24 @@ CONF = {
# url for list of valid timezones
_TZ_URL = 'http://en.wikipedia.org/wiki/List_of_tz_database_time_zones'
_input_compat = six.moves.input
str_compat = six.text_type
# Create a 'marked' default path, to determine if someone has supplied
# a path on the command-line.
class _DEFAULT_PATH_TYPE(str_compat):
class _DEFAULT_PATH_TYPE(str):
is_default_path = True
_DEFAULT_PATH = _DEFAULT_PATH_TYPE(os.curdir)
def decoding_strings(f):
def wrapper(*args, **kwargs):
out = f(*args, **kwargs)
if isinstance(out, six.string_types) and not six.PY3:
# todo: make encoding configurable?
if six.PY3:
return out
else:
return out.decode(sys.stdin.encoding)
return out
return wrapper
@decoding_strings
def ask(question, answer=str_compat, default=None, length=None):
if answer == str_compat:
def ask(question, answer=str, default=None, length=None):
if answer == str:
r = ''
while True:
if default:
r = _input_compat('> {0} [{1}] '.format(question, default))
r = input('> {0} [{1}] '.format(question, default))
else:
r = _input_compat('> {0} '.format(question, default))
r = input('> {0} '.format(question, default))
r = r.strip()
@ -133,11 +112,11 @@ def ask(question, answer=str_compat, default=None, length=None):
r = None
while True:
if default is True:
r = _input_compat('> {0} (Y/n) '.format(question))
r = input('> {0} (Y/n) '.format(question))
elif default is False:
r = _input_compat('> {0} (y/N) '.format(question))
r = input('> {0} (y/N) '.format(question))
else:
r = _input_compat('> {0} (y/n) '.format(question))
r = input('> {0} (y/n) '.format(question))
r = r.strip().lower()
@ -157,9 +136,9 @@ def ask(question, answer=str_compat, default=None, length=None):
r = None
while True:
if default:
r = _input_compat('> {0} [{1}] '.format(question, default))
r = input('> {0} [{1}] '.format(question, default))
else:
r = _input_compat('> {0} '.format(question))
r = input('> {0} '.format(question))
r = r.strip()
@ -175,14 +154,14 @@ def ask(question, answer=str_compat, default=None, length=None):
return r
else:
raise NotImplementedError(
'Argument `answer` must be str_compat, bool, or integer')
'Argument `answer` must be str, bool, or integer')
def ask_timezone(question, default, tzurl):
"""Prompt for time zone and validate input"""
lower_tz = [tz.lower() for tz in pytz.all_timezones]
while True:
r = ask(question, str_compat, default)
r = ask(question, str, default)
r = r.strip().replace(' ', '_').lower()
if r in lower_tz:
r = pytz.all_timezones[lower_tz.index(r)]
@ -227,20 +206,20 @@ needed by Pelican.
else:
CONF['basedir'] = os.path.abspath(os.path.expanduser(
ask('Where do you want to create your new web site?',
answer=str_compat, default=args.path)))
answer=str, default=args.path)))
CONF['sitename'] = ask('What will be the title of this web site?',
answer=str_compat, default=args.title)
answer=str, default=args.title)
CONF['author'] = ask('Who will be the author of this web site?',
answer=str_compat, default=args.author)
answer=str, default=args.author)
CONF['lang'] = ask('What will be the default language of this web site?',
str_compat, args.lang or CONF['lang'], 2)
str, args.lang or CONF['lang'], 2)
if ask('Do you want to specify a URL prefix? e.g., https://example.com ',
answer=bool, default=True):
CONF['siteurl'] = ask('What is your URL prefix? (see '
'above example; no trailing slash)',
str_compat, CONF['siteurl'])
str, CONF['siteurl'])
CONF['with_pagination'] = ask('Do you want to enable article pagination?',
bool, bool(CONF['default_pagination']))
@ -263,49 +242,49 @@ needed by Pelican.
answer=bool, default=False):
CONF['ftp'] = True,
CONF['ftp_host'] = ask('What is the hostname of your FTP server?',
str_compat, CONF['ftp_host'])
str, CONF['ftp_host'])
CONF['ftp_user'] = ask('What is your username on that server?',
str_compat, CONF['ftp_user'])
str, CONF['ftp_user'])
CONF['ftp_target_dir'] = ask('Where do you want to put your '
'web site on that server?',
str_compat, CONF['ftp_target_dir'])
str, CONF['ftp_target_dir'])
if ask('Do you want to upload your website using SSH?',
answer=bool, default=False):
CONF['ssh'] = True,
CONF['ssh_host'] = ask('What is the hostname of your SSH server?',
str_compat, CONF['ssh_host'])
str, CONF['ssh_host'])
CONF['ssh_port'] = ask('What is the port of your SSH server?',
int, CONF['ssh_port'])
CONF['ssh_user'] = ask('What is your username on that server?',
str_compat, CONF['ssh_user'])
str, CONF['ssh_user'])
CONF['ssh_target_dir'] = ask('Where do you want to put your '
'web site on that server?',
str_compat, CONF['ssh_target_dir'])
str, CONF['ssh_target_dir'])
if ask('Do you want to upload your website using Dropbox?',
answer=bool, default=False):
CONF['dropbox'] = True,
CONF['dropbox_dir'] = ask('Where is your Dropbox directory?',
str_compat, CONF['dropbox_dir'])
str, CONF['dropbox_dir'])
if ask('Do you want to upload your website using S3?',
answer=bool, default=False):
CONF['s3'] = True,
CONF['s3_bucket'] = ask('What is the name of your S3 bucket?',
str_compat, CONF['s3_bucket'])
str, CONF['s3_bucket'])
if ask('Do you want to upload your website using '
'Rackspace Cloud Files?', answer=bool, default=False):
CONF['cloudfiles'] = True,
CONF['cloudfiles_username'] = ask('What is your Rackspace '
'Cloud username?', str_compat,
'Cloud username?', str,
CONF['cloudfiles_username'])
CONF['cloudfiles_api_key'] = ask('What is your Rackspace '
'Cloud API key?', str_compat,
'Cloud API key?', str,
CONF['cloudfiles_api_key'])
CONF['cloudfiles_container'] = ask('What is the name of your '
'Cloud Files container?',
str_compat,
str,
CONF['cloudfiles_container'])
if ask('Do you want to upload your website using GitHub Pages?',
@ -363,9 +342,7 @@ needed by Pelican.
try:
with codecs.open(os.path.join(CONF['basedir'], 'Makefile'),
'w', 'utf-8') as fd:
py_v = 'python'
if six.PY3:
py_v = 'python3'
py_v = 'python3'
_template = _jinja_env.get_template('Makefile.jinja2')
fd.write(_template.render(py_v=py_v, **CONF))
fd.close()

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
import argparse
import os

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
AUTHOR = {{author}}
SITENAME = {{sitename}}

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
# This file is only used if you use `make publish` or
# explicitly specify it as your config file.