From ae4c606cc7a5e12576afd630fc88b5215ea695d4 Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Mon, 25 May 2020 22:02:27 -0700 Subject: [PATCH 01/10] Support Python 3.6, 3.7, 3.8 --- .travis.yml | 2 -- appveyor.yml | 15 +++++++++------ setup.py | 1 - 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56eb7d501..5059c859f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,6 @@ language: python jobs: include: - - os: linux - python: 2.7 - os: linux python: 3.6 - os: linux diff --git a/appveyor.yml b/appveyor.yml index 5103b1529..c7b7a1aa8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,13 +2,16 @@ build: false environment: matrix: - - PYTHON: "C:\\Python27" - PYTHON_VERSION: "2.7.8" - PYTHON_ARCH: "32" - MINICONDA: C:\Miniconda - - PYTHON: "C:\\Python36-x64" - PYTHON_VERSION: "3.6.6" + PYTHON_VERSION: "3.6.10" + PYTHON_ARCH: "64" + MINICONDA: C:\Miniconda3 + - PYTHON: "C:\\Python37-x64" + PYTHON_VERSION: "3.7.7" + PYTHON_ARCH: "64" + MINICONDA: C:\Miniconda3 + - PYTHON: "C:\\Python38-x64" + PYTHON_VERSION: "3.8.3" PYTHON_ARCH: "64" MINICONDA: C:\Miniconda3 diff --git a/setup.py b/setup.py index 958cfe3d4..911734b7b 100644 --- a/setup.py +++ b/setup.py @@ -74,7 +74,6 @@ def run(self): 'Intended Audience :: Information Technology', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', From 8fea0e048666f6363996822944ab220a2701d4e8 Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Mon, 25 May 2020 22:40:50 -0700 Subject: [PATCH 02/10] Remove Python 2/3 compatibility shims --- knowledge_repo/app/__init__.py | 2 -- knowledge_repo/app/app.py | 5 +---- knowledge_repo/app/auth_provider.py | 1 - knowledge_repo/app/auth_providers/oauth2.py | 5 ++--- knowledge_repo/app/deploy/common.py | 9 ++++---- knowledge_repo/app/deploy/gunicorn.py | 2 -- knowledge_repo/app/index.py | 2 -- knowledge_repo/app/migrations/env.py | 1 - knowledge_repo/app/models.py | 1 - knowledge_repo/app/routes/editor.py | 1 - knowledge_repo/app/routes/index.py | 1 - knowledge_repo/app/routes/posts.py | 1 - knowledge_repo/app/routes/tags.py | 1 - .../app/utils/knowledge_metadata.py | 4 ---- knowledge_repo/app/utils/posts.py | 1 - knowledge_repo/config.py | 6 ++--- knowledge_repo/converter.py | 1 - knowledge_repo/converters/gdoc.py | 2 -- knowledge_repo/converters/html.py | 2 -- knowledge_repo/mapping.py | 1 - knowledge_repo/post.py | 18 ++++++--------- knowledge_repo/postprocessor.py | 1 - .../postprocessors/extract_images.py | 3 +-- .../postprocessors/format_checks.py | 3 --- knowledge_repo/repositories/dbrepository.py | 1 - knowledge_repo/repositories/folder.py | 6 +---- knowledge_repo/repositories/gitrepository.py | 6 +---- knowledge_repo/repository.py | 22 +++++++------------ scripts/knowledge_repo | 2 -- scripts/kp | 3 --- tests/test_comments.py | 1 - 31 files changed, 27 insertions(+), 88 deletions(-) diff --git a/knowledge_repo/app/__init__.py b/knowledge_repo/app/__init__.py index 54ea1a785..b093934e4 100644 --- a/knowledge_repo/app/__init__.py +++ b/knowledge_repo/app/__init__.py @@ -1,4 +1,2 @@ -from __future__ import absolute_import - from . import auth_providers from .app import KnowledgeFlask diff --git a/knowledge_repo/app/app.py b/knowledge_repo/app/app.py index 5943bb1bb..036279c13 100644 --- a/knowledge_repo/app/app.py +++ b/knowledge_repo/app/app.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import os import imp import logging @@ -8,7 +6,6 @@ import uuid import mimetypes -import six from flask import Flask, current_app, render_template, request, session from flask_login import LoginManager, user_loaded_from_request from flask_mail import Mail @@ -52,7 +49,7 @@ def __init__(self, repo, db_uri=None, debug=None, config=None, **kwargs): # Load configuration from file or provided object if config: - if isinstance(config, six.string_types): + if isinstance(config, str): config = imp.load_source('knowledge_server_config', os.path.abspath(config)) self.config.from_object(config) diff --git a/knowledge_repo/app/auth_provider.py b/knowledge_repo/app/auth_provider.py index 154ba6ef3..abb30bca1 100644 --- a/knowledge_repo/app/auth_provider.py +++ b/knowledge_repo/app/auth_provider.py @@ -1,5 +1,4 @@ from abc import abstractmethod -from builtins import object from flask_principal import identity_changed, Identity from flask_login import login_user diff --git a/knowledge_repo/app/auth_providers/oauth2.py b/knowledge_repo/app/auth_providers/oauth2.py index 29baf159f..5c501b2a2 100644 --- a/knowledge_repo/app/auth_providers/oauth2.py +++ b/knowledge_repo/app/auth_providers/oauth2.py @@ -1,9 +1,8 @@ import posixpath import json -import six from flask import request, redirect -from six.moves.urllib.parse import urljoin +from urllib.parse import urljoin from ..models import User from ..auth_provider import KnowledgeAuthProvider @@ -158,7 +157,7 @@ def extract_from_dict(d, key): key = key[0] else: return extract_from_dict(d[key[0]], key[1:]) - if isinstance(key, six.string_types): + if isinstance(key, str): return d[key] raise RuntimeError("Invalid key type: {}.".format(key)) diff --git a/knowledge_repo/app/deploy/common.py b/knowledge_repo/app/deploy/common.py index 36edbe43d..4d89c55b0 100644 --- a/knowledge_repo/app/deploy/common.py +++ b/knowledge_repo/app/deploy/common.py @@ -6,7 +6,6 @@ from abc import abstractmethod from future.utils import with_metaclass -import six import knowledge_repo from knowledge_repo.utils.registry import SubclassRegisteringABCMeta @@ -29,7 +28,7 @@ def __init__(self, port=7000, workers=4, timeout=60): - assert isinstance(knowledge_builder, six.string_types + (types.FunctionType, )), \ + assert isinstance(knowledge_builder, str + (types.FunctionType, )), \ u"Unknown builder type {}".format(type(knowledge_builder)) self.knowledge_builder = knowledge_builder self.host = host @@ -57,7 +56,7 @@ def builder_str(self): if isinstance(self.knowledge_builder, types.FunctionType): out = [] for nl, cell in zip(self.knowledge_builder.__code__.co_freevars, self.knowledge_builder.__closure__): - if isinstance(cell.cell_contents, six.string_types): + if isinstance(cell.cell_contents, str): out.append(u'{} = "{}"'.format(nl, cell.cell_contents.replace('"', '\\"'))) else: out.append(u'{} = {}'.format(nl, cell.cell_contents)) @@ -67,7 +66,7 @@ def builder_str(self): @property def builder_func(self): - if isinstance(self.knowledge_builder, six.string_types): + if isinstance(self.knowledge_builder, str): knowledge_builder = 'def get_app():\n\t' + self.knowledge_builder.replace('\n', '\t') + '\n\treturn app' namespace = {} exec(knowledge_builder, namespace) @@ -95,7 +94,7 @@ def write_temp_files(self): out.append('import knowledge_repo') out.append(self.builder_str) - if not isinstance(self.knowledge_builder, six.string_types): + if not isinstance(self.knowledge_builder, str): out.append('app = %s()' % self.knowledge_builder.__name__) out.append('app.start_indexing()') diff --git a/knowledge_repo/app/deploy/gunicorn.py b/knowledge_repo/app/deploy/gunicorn.py index 540b218ac..625e43a56 100644 --- a/knowledge_repo/app/deploy/gunicorn.py +++ b/knowledge_repo/app/deploy/gunicorn.py @@ -5,8 +5,6 @@ Adapted from example in http://docs.gunicorn.org/en/stable/custom.html. """ -from __future__ import absolute_import - from gunicorn.app.base import BaseApplication from .common import KnowledgeDeployer diff --git a/knowledge_repo/app/index.py b/knowledge_repo/app/index.py index 8c93fefad..79180c2ef 100644 --- a/knowledge_repo/app/index.py +++ b/knowledge_repo/app/index.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import logging import multiprocessing import os diff --git a/knowledge_repo/app/migrations/env.py b/knowledge_repo/app/migrations/env.py index 01d6fdbb2..2b0e008ce 100755 --- a/knowledge_repo/app/migrations/env.py +++ b/knowledge_repo/app/migrations/env.py @@ -1,4 +1,3 @@ -from __future__ import with_statement from alembic import context from sqlalchemy import engine_from_config, pool from logging.config import fileConfig diff --git a/knowledge_repo/app/models.py b/knowledge_repo/app/models.py index c70409438..ce86d896d 100644 --- a/knowledge_repo/app/models.py +++ b/knowledge_repo/app/models.py @@ -3,7 +3,6 @@ import datetime import logging import traceback -from builtins import str from future.utils import raise_with_traceback from flask import current_app, request from flask_login import UserMixin diff --git a/knowledge_repo/app/routes/editor.py b/knowledge_repo/app/routes/editor.py index 1266dc62c..525372f44 100644 --- a/knowledge_repo/app/routes/editor.py +++ b/knowledge_repo/app/routes/editor.py @@ -2,7 +2,6 @@ import logging import sys import os -from builtins import str from datetime import datetime from flask import request, render_template, Blueprint, current_app, url_for, send_from_directory, g from sqlalchemy import or_ diff --git a/knowledge_repo/app/routes/index.py b/knowledge_repo/app/routes/index.py index 980d24e59..53580cf3b 100644 --- a/knowledge_repo/app/routes/index.py +++ b/knowledge_repo/app/routes/index.py @@ -8,7 +8,6 @@ """ import os import json -from builtins import str from collections import namedtuple from flask import request, render_template, redirect, Blueprint, current_app, make_response from flask_login import login_required diff --git a/knowledge_repo/app/routes/posts.py b/knowledge_repo/app/routes/posts.py index 87c624399..353602dfd 100755 --- a/knowledge_repo/app/routes/posts.py +++ b/knowledge_repo/app/routes/posts.py @@ -1,6 +1,5 @@ import logging import os -from builtins import str from flask import request, url_for, redirect, render_template, current_app, Blueprint, g, Response, abort from .. import permissions diff --git a/knowledge_repo/app/routes/tags.py b/knowledge_repo/app/routes/tags.py index 1e42db265..0ba2821cd 100644 --- a/knowledge_repo/app/routes/tags.py +++ b/knowledge_repo/app/routes/tags.py @@ -15,7 +15,6 @@ from sqlalchemy import and_ import logging import math -from builtins import str from .. import permissions from ..proxies import db_session diff --git a/knowledge_repo/app/utils/knowledge_metadata.py b/knowledge_repo/app/utils/knowledge_metadata.py index 99c3d6d16..c5c3802a6 100644 --- a/knowledge_repo/app/utils/knowledge_metadata.py +++ b/knowledge_repo/app/utils/knowledge_metadata.py @@ -1,7 +1,3 @@ - - -from __future__ import absolute_import -from __future__ import unicode_literals from markdown import Extension from markdown.preprocessors import Preprocessor diff --git a/knowledge_repo/app/utils/posts.py b/knowledge_repo/app/utils/posts.py index 928c1d517..2855aa806 100644 --- a/knowledge_repo/app/utils/posts.py +++ b/knowledge_repo/app/utils/posts.py @@ -5,7 +5,6 @@ - get_all_post_stats """ import math -from builtins import str from flask import current_app from sqlalchemy import func, distinct, or_ diff --git a/knowledge_repo/config.py b/knowledge_repo/config.py index 5c915184b..f74c91dac 100644 --- a/knowledge_repo/config.py +++ b/knowledge_repo/config.py @@ -6,8 +6,6 @@ import types import yaml -import six - logger = logging.getLogger(__name__) @@ -45,7 +43,7 @@ def update(self, *values, **kwargs): dict.update(self, value) elif isinstance(value, types.ModuleType): self.__update_from_module(value) - elif isinstance(value, six.string_types): + elif isinstance(value, str): if os.path.exists(value): self.__update_from_file(value) else: @@ -63,7 +61,7 @@ def update_defaults(self, *values, **kwargs): self.DEFAULT_CONFIGURATION.update(value) elif isinstance(value, types.ModuleType): self.__defaults_from_module(value) - elif isinstance(value, six.string_types): + elif isinstance(value, str): if os.path.exists(value): self.__defaults_from_file(value) else: diff --git a/knowledge_repo/converter.py b/knowledge_repo/converter.py index 2e138f925..945de992d 100644 --- a/knowledge_repo/converter.py +++ b/knowledge_repo/converter.py @@ -1,4 +1,3 @@ -from builtins import object import os from functools import wraps diff --git a/knowledge_repo/converters/gdoc.py b/knowledge_repo/converters/gdoc.py index 9861b0e43..1084d6d31 100644 --- a/knowledge_repo/converters/gdoc.py +++ b/knowledge_repo/converters/gdoc.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import cooked_input as ci import logging import os diff --git a/knowledge_repo/converters/html.py b/knowledge_repo/converters/html.py index 984474f5c..2d9eef3dd 100644 --- a/knowledge_repo/converters/html.py +++ b/knowledge_repo/converters/html.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import -from __future__ import unicode_literals import markdown from markdown import Extension from markdown.blockprocessors import BlockProcessor diff --git a/knowledge_repo/mapping.py b/knowledge_repo/mapping.py index 7aa21fdc7..21a94b9f5 100644 --- a/knowledge_repo/mapping.py +++ b/knowledge_repo/mapping.py @@ -1,4 +1,3 @@ -from builtins import object import re diff --git a/knowledge_repo/post.py b/knowledge_repo/post.py index 3f2a5b4df..542f2ab48 100755 --- a/knowledge_repo/post.py +++ b/knowledge_repo/post.py @@ -1,6 +1,3 @@ -from __future__ import absolute_import -from builtins import next -from builtins import object from collections import namedtuple import io import itertools @@ -16,7 +13,6 @@ import cooked_input as ci import PIL.Image -import six from .utils.encoding import encode, decode @@ -26,20 +22,20 @@ Header = namedtuple('Header', ('name', 'type', 'input')) HEADER_REQUIRED_FIELD_TYPES = [ - Header('title', six.string_types, ci.GetInput(prompt='title')), + Header('title', str, ci.GetInput(prompt='title')), Header('authors', list, ci.GetInput(prompt='authors (comma separated)', convertor=ci.ListConvertor())), - Header('tldr', six.string_types, ci.GetInput(prompt='tldr')), + Header('tldr', str, ci.GetInput(prompt='tldr')), Header('created_at', datetime.datetime, ci.GetInput(prompt='created_at', convertor=ci.DateConvertor(), default=datetime.date.today())), ] HEADER_OPTIONAL_FIELD_TYPES = [ - Header('subtitle', six.string_types, ci.GetInput(prompt='subtitle', required=False)), + Header('subtitle', str, ci.GetInput(prompt='subtitle', required=False)), Header('tags', list, ci.GetInput(prompt='tags (comma separated)', convertor=ci.ListConvertor(), required=False)), - Header('path', six.string_types, ci.GetInput(prompt='path', required=False)), + Header('path', str, ci.GetInput(prompt='path', required=False)), Header('updated_at', datetime.datetime, ci.GetInput(prompt='updated_at', convertor=ci.DateConvertor(), default=datetime.datetime.now())), Header('private', bool, ci.GetInput(prompt='private', convertor=ci.BooleanConvertor(), required=False)), # If true, this post starts out private Header('allowed_groups', list, ci.GetInput(prompt='allowed_groups (comma separated)', convertor=ci.ListConvertor(), required=False)), - Header('thumbnail', (int, ) + six.string_types, ci.GetInput(prompt='thumbnail', required=False)), + Header('thumbnail', (int, ) + str, ci.GetInput(prompt='thumbnail', required=False)), ] HEADERS_ALL = { @@ -395,7 +391,7 @@ def headers(self): if isinstance(value, datetime.date): headers[key] = datetime.datetime.combine(value, datetime.time(0)) if key == 'tags' and isinstance(value, list): - headers[key] = [str(v) if six.PY3 else unicode(v) for v in value] + headers[key] = [str(v) for v in value] return headers @headers.setter @@ -416,7 +412,7 @@ def update_headers(self, **headers): def thumbnail_uri(self): thumbnail = self.headers.get('thumbnail') - if not thumbnail or not isinstance(thumbnail, six.string_types): + if not thumbnail or not isinstance(thumbnail, str): return None if ':' not in thumbnail: # if thumbnail points to a local reference diff --git a/knowledge_repo/postprocessor.py b/knowledge_repo/postprocessor.py index 29c935144..70afca05b 100644 --- a/knowledge_repo/postprocessor.py +++ b/knowledge_repo/postprocessor.py @@ -1,4 +1,3 @@ -from builtins import object from .utils.registry import SubclassRegisteringABCMeta from future.utils import with_metaclass diff --git a/knowledge_repo/postprocessors/extract_images.py b/knowledge_repo/postprocessors/extract_images.py index e7842caa9..e748af3b2 100644 --- a/knowledge_repo/postprocessors/extract_images.py +++ b/knowledge_repo/postprocessors/extract_images.py @@ -1,7 +1,6 @@ import os import posixpath import re -import six import logging from ..postprocessor import KnowledgePostProcessor @@ -22,7 +21,7 @@ def update_thumbnail_uri(self, kp, images, image_mapping): thumbnail = kp.headers.get('thumbnail', 0) # if thumbnail is a number, select the nth image in this post as the thumbnail - if isinstance(thumbnail, six.string_types) and thumbnail.isdigit(): + if isinstance(thumbnail, str) and thumbnail.isdigit(): thumbnail = int(thumbnail) if isinstance(thumbnail, int): if len(images) > 0: diff --git a/knowledge_repo/postprocessors/format_checks.py b/knowledge_repo/postprocessors/format_checks.py index 07328378b..be9bc1918 100644 --- a/knowledge_repo/postprocessors/format_checks.py +++ b/knowledge_repo/postprocessors/format_checks.py @@ -1,8 +1,5 @@ import datetime -import six -from past.builtins import basestring - from ..post import HEADER_OPTIONAL_FIELD_TYPES, HEADER_REQUIRED_FIELD_TYPES from ..postprocessor import KnowledgePostProcessor diff --git a/knowledge_repo/repositories/dbrepository.py b/knowledge_repo/repositories/dbrepository.py index 1381f0a93..6123b1455 100644 --- a/knowledge_repo/repositories/dbrepository.py +++ b/knowledge_repo/repositories/dbrepository.py @@ -1,4 +1,3 @@ -from builtins import object import logging import posixpath diff --git a/knowledge_repo/repositories/folder.py b/knowledge_repo/repositories/folder.py index 564d9a9df..c522f342d 100644 --- a/knowledge_repo/repositories/folder.py +++ b/knowledge_repo/repositories/folder.py @@ -1,13 +1,9 @@ -from __future__ import print_function - import os import shutil import logging import time from io import open -import six - from ..post import KnowledgePost from ..repository import KnowledgeRepository from ..utils.encoding import encode @@ -67,7 +63,7 @@ def path(self): @path.setter def path(self, path): - assert isinstance(path, six.string_types), "The path specified must be a string." + assert isinstance(path, str), "The path specified must be a string." path = os.path.abspath(os.path.expanduser(path)) if not os.path.exists(path): path = os.path.abspath(path) diff --git a/knowledge_repo/repositories/gitrepository.py b/knowledge_repo/repositories/gitrepository.py index 646d7f92c..30e251868 100644 --- a/knowledge_repo/repositories/gitrepository.py +++ b/knowledge_repo/repositories/gitrepository.py @@ -1,6 +1,3 @@ -from __future__ import print_function -from builtins import input - import os import shutil import logging @@ -9,7 +6,6 @@ from io import open import git -import six import yaml from ..repository import KnowledgeRepository @@ -93,7 +89,7 @@ def path(self): @path.setter def path(self, path): - assert isinstance(path, six.string_types), "The path specified must be a string." + assert isinstance(path, str), "The path specified must be a string." path = os.path.abspath(os.path.expanduser(path)) if not os.path.exists(path): path = os.path.abspath(path) diff --git a/knowledge_repo/repository.py b/knowledge_repo/repository.py index e6da32246..38b8b4fa1 100644 --- a/knowledge_repo/repository.py +++ b/knowledge_repo/repository.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import print_function - -from builtins import object import sys import os import posixpath @@ -10,8 +6,6 @@ from collections import OrderedDict from enum import Enum -import six - from . import config_defaults from .post import KnowledgePost from .config import KnowledgeRepositoryConfig @@ -50,7 +44,7 @@ def for_uri(cls, uri, *args, **kwargs): def for_uris(cls, uri): # Import this within this method so as not to cause import resolution problems from .repositories.meta import MetaKnowledgeRepository - if isinstance(uri, six.string_types): + if isinstance(uri, str): uris = {'': uri} else: uris = uri @@ -100,14 +94,14 @@ def uris(self): # It assumes that self.uri is either a string or a dictionary mapping # of form: # {: } - if isinstance(self.uri, six.string_types): + if isinstance(self.uri, str): return {'': self.uri} elif isinstance(self.uri, dict): uri_dict = {} def add_uris(uri_dict, uri, parent=''): - if isinstance(uri, six.string_types): + if isinstance(uri, str): uri_dict[parent] = uri elif isinstance(uri, dict): for mountpoint, u in uri.items(): @@ -128,14 +122,14 @@ def revisions(self): # This method provides a mapping from uri to revision for this repository # and/or any nested repositories. This is most useful when checking if an # update is required server side. - if isinstance(self.uri, six.string_types): + if isinstance(self.uri, str): return {self.uri: self.revision} elif isinstance(self.uri, dict): revision_dict = {} def add_revisions(revision_dict, uri): - if isinstance(uri, six.string_types): + if isinstance(uri, str): revision_dict[uri] = KnowledgeRepository.for_uri(uri).revision elif isinstance(uri, dict): for u in uri.values(): @@ -190,13 +184,13 @@ def post(self, path, revision=None): return KnowledgePost(path=path, repository=self, revision=revision or self._kp_get_revision(path)) def dir(self, prefix=None, status=None): - if prefix is None or isinstance(prefix, six.string_types): + if prefix is None or isinstance(prefix, str): prefixes = [prefix] else: prefixes = prefix - assert all([prefix is None or isinstance(prefix, six.string_types) for prefix in prefixes]), "All path prefixes must be strings." + assert all([prefix is None or isinstance(prefix, str) for prefix in prefixes]), "All path prefixes must be strings." prefixes = [prefix if prefix is None else posixpath.relpath(prefix) for prefix in prefixes] - if isinstance(status, six.string_types): + if isinstance(status, str): if status == 'all': status = [self.PostStatus.DRAFT, self.PostStatus.SUBMITTED, self.PostStatus.PUBLISHED, self.PostStatus.UNPUBLISHED] else: diff --git a/scripts/knowledge_repo b/scripts/knowledge_repo index 7b0240e37..013a0db33 100755 --- a/scripts/knowledge_repo +++ b/scripts/knowledge_repo @@ -1,6 +1,4 @@ #!/usr/bin/env python -from __future__ import print_function -from __future__ import unicode_literals import sys import os diff --git a/scripts/kp b/scripts/kp index b054340fb..edf499a22 100755 --- a/scripts/kp +++ b/scripts/kp @@ -1,8 +1,5 @@ #!/usr/bin/env python -from __future__ import print_function -from __future__ import unicode_literals - import argparse import cooked_input as ci import os diff --git a/tests/test_comments.py b/tests/test_comments.py index fe6155170..4642c2643 100644 --- a/tests/test_comments.py +++ b/tests/test_comments.py @@ -1,4 +1,3 @@ -from __future__ import print_function import unittest import json From 4f74307b1638db90dc639a16bddc2c7882805fc3 Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Mon, 25 May 2020 22:45:46 -0700 Subject: [PATCH 03/10] fix --- knowledge_repo/app/index.py | 1 - knowledge_repo/post.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/knowledge_repo/app/index.py b/knowledge_repo/app/index.py index 79180c2ef..3d1a94b20 100644 --- a/knowledge_repo/app/index.py +++ b/knowledge_repo/app/index.py @@ -2,7 +2,6 @@ import multiprocessing import os import time -from builtins import str from .proxies import db_session, current_repo, current_app from .models import ErrorLog, Post, IndexMetadata diff --git a/knowledge_repo/post.py b/knowledge_repo/post.py index 542f2ab48..c86319601 100755 --- a/knowledge_repo/post.py +++ b/knowledge_repo/post.py @@ -35,7 +35,7 @@ Header('updated_at', datetime.datetime, ci.GetInput(prompt='updated_at', convertor=ci.DateConvertor(), default=datetime.datetime.now())), Header('private', bool, ci.GetInput(prompt='private', convertor=ci.BooleanConvertor(), required=False)), # If true, this post starts out private Header('allowed_groups', list, ci.GetInput(prompt='allowed_groups (comma separated)', convertor=ci.ListConvertor(), required=False)), - Header('thumbnail', (int, ) + str, ci.GetInput(prompt='thumbnail', required=False)), + Header('thumbnail', (int, str), ci.GetInput(prompt='thumbnail', required=False)), ] HEADERS_ALL = { From 151b7b67c630c5e0d6366da158eae3df5b829448 Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Mon, 25 May 2020 22:58:39 -0700 Subject: [PATCH 04/10] remove some future imports --- knowledge_repo/app/auth_provider.py | 3 +-- knowledge_repo/app/deploy/common.py | 3 +-- knowledge_repo/app/utils/auth.py | 2 +- knowledge_repo/converter.py | 3 +-- knowledge_repo/postprocessor.py | 3 +-- knowledge_repo/repository.py | 3 +-- 6 files changed, 6 insertions(+), 11 deletions(-) diff --git a/knowledge_repo/app/auth_provider.py b/knowledge_repo/app/auth_provider.py index abb30bca1..91b91be29 100644 --- a/knowledge_repo/app/auth_provider.py +++ b/knowledge_repo/app/auth_provider.py @@ -2,14 +2,13 @@ from flask_principal import identity_changed, Identity from flask_login import login_user -from future.utils import with_metaclass from flask import redirect, current_app, Blueprint, url_for, session from .utils.auth import prepare_user from ..utils.registry import SubclassRegisteringABCMeta -class KnowledgeAuthProvider(with_metaclass(SubclassRegisteringABCMeta, object)): +class KnowledgeAuthProvider(object, metaclass=SubclassRegisteringABCMeta): _registry_keys = None @classmethod diff --git a/knowledge_repo/app/deploy/common.py b/knowledge_repo/app/deploy/common.py index 4d89c55b0..fbfe552a8 100644 --- a/knowledge_repo/app/deploy/common.py +++ b/knowledge_repo/app/deploy/common.py @@ -4,7 +4,6 @@ import sys import textwrap from abc import abstractmethod -from future.utils import with_metaclass import knowledge_repo from knowledge_repo.utils.registry import SubclassRegisteringABCMeta @@ -20,7 +19,7 @@ def get_app(): return get_app -class KnowledgeDeployer(with_metaclass(SubclassRegisteringABCMeta, object)): +class KnowledgeDeployer(object, metaclass=SubclassRegisteringABCMeta): def __init__(self, knowledge_builder, diff --git a/knowledge_repo/app/utils/auth.py b/knowledge_repo/app/utils/auth.py index f48821dee..221278759 100644 --- a/knowledge_repo/app/utils/auth.py +++ b/knowledge_repo/app/utils/auth.py @@ -1,6 +1,6 @@ import datetime -from future.moves.urllib.parse import urlparse, urlencode, urljoin +from urllib.parse import urlparse, urlencode, urljoin from flask import request, url_for from flask_login import AnonymousUserMixin, login_user diff --git a/knowledge_repo/converter.py b/knowledge_repo/converter.py index 945de992d..dee430581 100644 --- a/knowledge_repo/converter.py +++ b/knowledge_repo/converter.py @@ -5,7 +5,6 @@ from .postprocessor import KnowledgePostProcessor from .utils.registry import SubclassRegisteringABCMeta from .utils.dependencies import check_dependencies -from future.utils import with_metaclass def get_format(filename, format=None): @@ -23,7 +22,7 @@ def get_format(filename, format=None): return format -class KnowledgePostConverter(with_metaclass(SubclassRegisteringABCMeta, object)): +class KnowledgePostConverter(object, metaclass=SubclassRegisteringABCMeta): _registry_keys = None # File extensions def __init__(self, kp, format=None, postprocessors=None, interactive=False, **kwargs): diff --git a/knowledge_repo/postprocessor.py b/knowledge_repo/postprocessor.py index 70afca05b..d677e092c 100644 --- a/knowledge_repo/postprocessor.py +++ b/knowledge_repo/postprocessor.py @@ -1,8 +1,7 @@ from .utils.registry import SubclassRegisteringABCMeta -from future.utils import with_metaclass -class KnowledgePostProcessor(with_metaclass(SubclassRegisteringABCMeta, object)): +class KnowledgePostProcessor(object, metaclass=SubclassRegisteringABCMeta): _registry_keys = [] def process(self, kp): diff --git a/knowledge_repo/repository.py b/knowledge_repo/repository.py index 38b8b4fa1..7bb758469 100644 --- a/knowledge_repo/repository.py +++ b/knowledge_repo/repository.py @@ -11,7 +11,6 @@ from .config import KnowledgeRepositoryConfig from .postprocessor import KnowledgePostProcessor from .utils.registry import SubclassRegisteringABCMeta -from future.utils import with_metaclass if sys.version_info.major > 2: from urllib.parse import urlparse @@ -19,7 +18,7 @@ from urlparse import urlparse -class KnowledgeRepository(with_metaclass(SubclassRegisteringABCMeta, object)): +class KnowledgeRepository(object, metaclass=SubclassRegisteringABCMeta): _registry_keys = None class PostStatus(Enum): From dafb409dc8c9f2e5a4fcb9918bcd57c5493a52c0 Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Mon, 25 May 2020 23:03:05 -0700 Subject: [PATCH 05/10] remove future dependency --- docs/requirements.txt | 1 - knowledge_repo/_version.py | 1 - knowledge_repo/app/models.py | 3 +-- knowledge_repo/utils/encoding.py | 5 ++--- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 7e2f37673..f08c41619 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ -future enum34 pyyaml markdown diff --git a/knowledge_repo/_version.py b/knowledge_repo/_version.py index 0344c355d..198dbc904 100644 --- a/knowledge_repo/_version.py +++ b/knowledge_repo/_version.py @@ -18,7 +18,6 @@ # should be defined elsewhere. __dependencies__ = [ # Knowledge Repository Dependencies - 'future', # Python 2/3 support 'enum34', # Python 3.4+ enum object used for Post status 'pyyaml', # Yaml parser and utilities 'markdown', # Markdown conversion utilities diff --git a/knowledge_repo/app/models.py b/knowledge_repo/app/models.py index ce86d896d..61fcba127 100644 --- a/knowledge_repo/app/models.py +++ b/knowledge_repo/app/models.py @@ -3,7 +3,6 @@ import datetime import logging import traceback -from future.utils import raise_with_traceback from flask import current_app, request from flask_login import UserMixin from flask_sqlalchemy import SQLAlchemy @@ -137,7 +136,7 @@ def wrapped(*args, **kwargs): db_session.rollback() db_session.add(ErrorLog.from_exception(e)) db_session.commit() - raise_with_traceback(e) + raise e.with_traceback() return wrapped diff --git a/knowledge_repo/utils/encoding.py b/knowledge_repo/utils/encoding.py index e40c6d886..07548320a 100644 --- a/knowledge_repo/utils/encoding.py +++ b/knowledge_repo/utils/encoding.py @@ -2,7 +2,6 @@ import sys import logging -from future.utils import raise_with_traceback __all__ = ['encode', 'decode'] @@ -29,7 +28,7 @@ def encode(data, encoding='utf-8'): data = data.encode(encoding) except Exception as e: if os.environ.get('DEBUG'): - raise_with_traceback(e) + raise e.with_traceback() logger.warning("An encoding error has occurred... continuing anyway. To capture these errors, rerun the current command prefixed with `DEBUG=1 `.") data = data.encode(encoding, errors='ignore') return data @@ -42,7 +41,7 @@ def decode(data, encoding='utf-8'): data = data.decode(encoding) except Exception as e: if os.environ.get('DEBUG'): - raise_with_traceback(e) + raise e.with_traceback() logger.warning("An decoding error has occurred... continuing anyway. To capture these errors, rerun the current command prefixed with `DEBUG=1 `.") data = data.decode(encoding, errors='ignore') return data From 67a419333acce34208316bca9737517dd4e30e6c Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Mon, 25 May 2020 23:05:23 -0700 Subject: [PATCH 06/10] remove enum34 --- docs/requirements.txt | 1 - knowledge_repo/_version.py | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f08c41619..6720e5ca8 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ -enum34 pyyaml markdown pygments diff --git a/knowledge_repo/_version.py b/knowledge_repo/_version.py index 198dbc904..41ec1e0a9 100644 --- a/knowledge_repo/_version.py +++ b/knowledge_repo/_version.py @@ -18,7 +18,6 @@ # should be defined elsewhere. __dependencies__ = [ # Knowledge Repository Dependencies - 'enum34', # Python 3.4+ enum object used for Post status 'pyyaml', # Yaml parser and utilities 'markdown', # Markdown conversion utilities 'pygments', # Code highlighting support in markdown From 89de4111bcba10f331969220f80397425c73eb57 Mon Sep 17 00:00:00 2001 From: Naoya Kanai Date: Tue, 26 May 2020 15:16:35 -0700 Subject: [PATCH 07/10] Py2 deprecation: remove unicode handling logic --- knowledge_repo/app/app.py | 4 +-- knowledge_repo/app/deploy/common.py | 12 +++---- knowledge_repo/app/deploy/gunicorn.py | 2 +- knowledge_repo/app/deploy/uwsgi.py | 8 ++--- knowledge_repo/app/index.py | 12 +++---- knowledge_repo/app/models.py | 10 +++--- knowledge_repo/app/routes/editor.py | 18 +++++------ knowledge_repo/app/routes/index.py | 6 ++-- knowledge_repo/app/routes/posts.py | 14 ++++---- knowledge_repo/app/utils/emails.py | 2 +- knowledge_repo/app/utils/render.py | 6 ++-- knowledge_repo/app/utils/search.py | 34 ++++++++++---------- knowledge_repo/config.py | 10 +++--- knowledge_repo/converters/html.py | 2 +- knowledge_repo/mapping.py | 2 +- knowledge_repo/repositories/dbrepository.py | 2 +- knowledge_repo/repositories/gitrepository.py | 5 ++- knowledge_repo/utils/dependencies.py | 2 +- knowledge_repo/utils/encoding.py | 16 +++------ knowledge_repo/utils/types.py | 7 ---- 20 files changed, 80 insertions(+), 94 deletions(-) diff --git a/knowledge_repo/app/app.py b/knowledge_repo/app/app.py index 036279c13..859415122 100644 --- a/knowledge_repo/app/app.py +++ b/knowledge_repo/app/app.py @@ -72,7 +72,7 @@ def __init__(self, repo, db_uri=None, debug=None, config=None, **kwargs): # Configure database if db_uri: self.config['SQLALCHEMY_DATABASE_URI'] = db_uri - logger.debug(u"Using database: {}".format(self.config['SQLALCHEMY_DATABASE_URI'])) + logger.debug("Using database: {}".format(self.config['SQLALCHEMY_DATABASE_URI'])) # Register database schema with flask app sqlalchemy_db.init_app(self) @@ -232,7 +232,7 @@ def modify_query(**new_values): for key, value in new_values.items(): args[key] = value - return u'{}?{}'.format(request.path, url_encode(args)) + return '{}?{}'.format(request.path, url_encode(args)) @self.template_global() def pagination_pages(current_page, page_count, max_pages=5, extremes=True): diff --git a/knowledge_repo/app/deploy/common.py b/knowledge_repo/app/deploy/common.py index fbfe552a8..fcfb34cb1 100644 --- a/knowledge_repo/app/deploy/common.py +++ b/knowledge_repo/app/deploy/common.py @@ -28,7 +28,7 @@ def __init__(self, workers=4, timeout=60): assert isinstance(knowledge_builder, str + (types.FunctionType, )), \ - u"Unknown builder type {}".format(type(knowledge_builder)) + "Unknown builder type {}".format(type(knowledge_builder)) self.knowledge_builder = knowledge_builder self.host = host self.port = port @@ -56,11 +56,11 @@ def builder_str(self): out = [] for nl, cell in zip(self.knowledge_builder.__code__.co_freevars, self.knowledge_builder.__closure__): if isinstance(cell.cell_contents, str): - out.append(u'{} = "{}"'.format(nl, cell.cell_contents.replace('"', '\\"'))) + out.append('{} = "{}"'.format(nl, cell.cell_contents.replace('"', '\\"'))) else: - out.append(u'{} = {}'.format(nl, cell.cell_contents)) + out.append('{} = {}'.format(nl, cell.cell_contents)) out.append(textwrap.dedent(inspect.getsource(self.knowledge_builder))) - return u'\n'.join(out) + return '\n'.join(out) return self.knowledge_builder @property @@ -89,7 +89,7 @@ def write_temp_files(self): out = [] out.append('import sys') - out.append(u'sys.path.insert(0, "{}")'.format(kr_path)) + out.append('sys.path.insert(0, "{}")'.format(kr_path)) out.append('import knowledge_repo') out.append(self.builder_str) @@ -98,7 +98,7 @@ def write_temp_files(self): out.append('app.start_indexing()') with open(tmp_path, 'w') as f: - f.write(u'\n'.join(out)) + f.write('\n'.join(out)) return tmp_dir diff --git a/knowledge_repo/app/deploy/gunicorn.py b/knowledge_repo/app/deploy/gunicorn.py index 625e43a56..abb55d86c 100644 --- a/knowledge_repo/app/deploy/gunicorn.py +++ b/knowledge_repo/app/deploy/gunicorn.py @@ -28,7 +28,7 @@ def load_config(self): # Update the configuration with the options specified via KnowledgeDeployer options = { - 'bind': u'{}:{}'.format(self.host, self.port), + 'bind': '{}:{}'.format(self.host, self.port), 'workers': self.workers, 'timeout': self.timeout, } diff --git a/knowledge_repo/app/deploy/uwsgi.py b/knowledge_repo/app/deploy/uwsgi.py index ecb463836..838c31974 100644 --- a/knowledge_repo/app/deploy/uwsgi.py +++ b/knowledge_repo/app/deploy/uwsgi.py @@ -12,7 +12,7 @@ class uWSGIDeployer(KnowledgeDeployer): _registry_keys = ['uwsgi'] - COMMAND = u"uwsgi {protocol} --plugin python --wsgi-file {{path}} --callable app --master --processes {{processes}} --threads {{threads}}" + COMMAND = "uwsgi {protocol} --plugin python --wsgi-file {{path}} --callable app --master --processes {{processes}} --threads {{threads}}" def run(self): if not self.app.check_thread_support(): @@ -21,7 +21,7 @@ def run(self): tmp_dir = self.write_temp_files() options = { - 'socket': u'{}:{}'.format(self.host, self.port), + 'socket': '{}:{}'.format(self.host, self.port), 'processes': self.workers, 'threads': 2, 'timeout': self.timeout, @@ -36,8 +36,8 @@ def run(self): self.COMMAND = self.COMMAND.format(protocol="--http {socket}") try: - cmd = u"cd {};".format(tmp_dir) + self.COMMAND.format(**options) - logger.info("Starting server with command: %s", u" ".join(cmd)) + cmd = "cd {};".format(tmp_dir) + self.COMMAND.format(**options) + logger.info("Starting server with command: %s", " ".join(cmd)) subprocess.check_output(cmd, shell=True) finally: shutil.rmtree(tmp_dir) diff --git a/knowledge_repo/app/index.py b/knowledge_repo/app/index.py index 3d1a94b20..43da1afc4 100644 --- a/knowledge_repo/app/index.py +++ b/knowledge_repo/app/index.py @@ -157,12 +157,12 @@ def update_index(check_timeouts=True, force=False, reindex=False): # If UUID has changed, check if we can find it elsewhere in the repository, and if so update index path if post.uuid and ((post.path not in kr_dir) or (post.uuid != kr_dir[post.path].uuid)): if post.uuid in kr_uuids: - logger.info(u'Updating location of post: {} -> {}'.format(post.path, kr_uuids[post.uuid].path)) + logger.info('Updating location of post: {} -> {}'.format(post.path, kr_uuids[post.uuid].path)) post.path = kr_uuids[post.uuid].path # If path of post no longer in directory, mark as unpublished if post.path not in kr_dir: - logger.info(u'Recording unpublished status for post at {}'.format(post.path)) + logger.info('Recording unpublished status for post at {}'.format(post.path)) post.status = current_repo.PostStatus.UNPUBLISHED continue @@ -174,17 +174,17 @@ def update_index(check_timeouts=True, force=False, reindex=False): # Update metadata of post if required if reindex or (kp.revision > post.revision or not post.is_published or kp.uuid != post.uuid): if kp.is_valid(): - logger.info(u'Recording update to post at: {}'.format(kp.path)) + logger.info('Recording update to post at: {}'.format(kp.path)) post.update_metadata_from_kp(kp) else: - logger.warning(u'Update to post at "{}" is corrupt.'.format(kp.path)) + logger.warning('Update to post at "{}" is corrupt.'.format(kp.path)) # Add the new posts that remain in kr_dir for kp_path, kp in kr_dir.items(): if not kp.is_valid(): - logger.warning(u'New post at "{}" is corrupt.'.format(kp.path)) + logger.warning('New post at "{}" is corrupt.'.format(kp.path)) continue - logger.info(u'creating new post from path {}'.format(kp_path)) + logger.info('creating new post from path {}'.format(kp_path)) post = Post() db_session.add(post) db_session.flush() # (matthew) Fix groups logic so this is not necessary diff --git a/knowledge_repo/app/models.py b/knowledge_repo/app/models.py index 61fcba127..59553c293 100644 --- a/knowledge_repo/app/models.py +++ b/knowledge_repo/app/models.py @@ -122,9 +122,9 @@ def from_exception(cls, e): filename = os.path.relpath(filename, os.path.join(os.path.dirname(__file__), '..')) return ErrorLog( function=function, - location=u'{}:{}'.format(filename, linenumber), - message=u'{}: {}'.format(e.__class__.__name__, u"; ".join(str(a) for a in e.args)), - traceback=u"\n".join(traceback.format_tb(tb)) + location='{}:{}'.format(filename, linenumber), + message='{}: {}'.format(e.__class__.__name__, "; ".join(str(a) for a in e.args)), + traceback="\n".join(traceback.format_tb(tb)) ) @classmethod @@ -338,7 +338,7 @@ class Tag(db.Model): def description(self): if self._description: return self._description - return u"All posts with tag '{}'.".format(self.name) + return "All posts with tag '{}'.".format(self.name) @description.expression def description(self): @@ -405,7 +405,7 @@ def authors(self, authors): @hybrid_property def authors_string(self): - return u', '.join([author.format_name for author in self.authors]) + return ', '.join([author.format_name for author in self.authors]) @authors_string.expression def authors_string(self): diff --git a/knowledge_repo/app/routes/editor.py b/knowledge_repo/app/routes/editor.py index 525372f44..c94c46e7b 100644 --- a/knowledge_repo/app/routes/editor.py +++ b/knowledge_repo/app/routes/editor.py @@ -129,7 +129,7 @@ def save_post(): if prefixes is not None: if not any([path.startswith(prefix) for prefix in prefixes]): - return json.dumps({'msg': (u"Your post path must begin with one of {}").format(prefixes), + return json.dumps({'msg': ("Your post path must begin with one of {}").format(prefixes), 'success': False}) # TODO better handling of overwriting @@ -137,7 +137,7 @@ def save_post(): if path in current_repo: kp = current_repo.post(path) if current_user.identifier not in kp.headers['authors'] and current_user.identifier not in current_repo.config.editors: - return json.dumps({'msg': (u"Post with path {} already exists and you are not an author!" + return json.dumps({'msg': ("Post with path {} already exists and you are not an author!" "\nPlease try a different path").format(path), 'success': False}) @@ -192,7 +192,7 @@ def publish_post(): """ Publish the post by changing the status """ path = request.args.get('path', None) if path not in current_repo: - return json.dumps({'msg': u"Unable to retrieve post with path = {}!".format(path), 'success': False}) + return json.dumps({'msg': "Unable to retrieve post with path = {}!".format(path), 'success': False}) current_repo.publish(path) update_index(check_timeouts=False) @@ -206,7 +206,7 @@ def unpublish_post(): """ Unpublish the post """ path = request.args.get('path', None) if path not in current_repo: - return json.dumps({'msg': u"Unable to retrieve post with path = {}!".format(path), 'success': False}) + return json.dumps({'msg': "Unable to retrieve post with path = {}!".format(path), 'success': False}) current_repo.unpublish(path) update_index(check_timeouts=False) @@ -220,7 +220,7 @@ def accept(): """ Accept the post """ path = request.args.get('path', None) if path not in current_repo: - return json.dumps({'msg': u"Unable to retrieve post with path = {}!".format(path), 'success': False}) + return json.dumps({'msg': "Unable to retrieve post with path = {}!".format(path), 'success': False}) current_repo.accept(path) update_index() return 'OK' @@ -233,7 +233,7 @@ def delete_post(): """ Delete a post """ path = request.args.get('path', None) if path not in current_repo: - return json.dumps({'msg': u"Unable to retrieve post with path = {}!".format(path), 'success': False}) + return json.dumps({'msg': "Unable to retrieve post with path = {}!".format(path), 'success': False}) kp = current_repo.post(path) if current_user.identifier not in kp.headers['authors']: return json.dumps({'msg': "You can only delete a post where you are an author!", 'success': False}) @@ -300,7 +300,7 @@ def file_upload(): send_from_directory(dst_folder, filename) uploadedFiles += [url_for("static", filename=os.path.join(upload_folder, filename))] except Exception as e: - error_msg = u"ERROR during image upload: {}".format(str(e)) + error_msg = "ERROR during image upload: {}".format(str(e)) logger.error(error_msg) return json.dumps({'error_msg': error_msg, 'success': False}) @@ -312,11 +312,11 @@ def file_upload(): num_pages = src_pdf.getNumPages() for page_num in range(num_pages): page_png = pdf_page_to_png(src_pdf, page_num) - page_name = u"{filename}_{page_num}.jpg".format(**locals()) + page_name = "{filename}_{page_num}.jpg".format(**locals()) page_png.save(filename=os.path.join(dst_folder, page_name)) uploadedFiles += [url_for("static", filename=os.path.join(upload_folder, page_name))] except Exception as e: - error_msg = u"ERROR during pdf upload: {}".format(str(e)) + error_msg = "ERROR during pdf upload: {}".format(str(e)) logger.error(error_msg) return json.dumps({'error_msg': error_msg, 'success': False}) diff --git a/knowledge_repo/app/routes/index.py b/knowledge_repo/app/routes/index.py index 53580cf3b..8bb53f51d 100644 --- a/knowledge_repo/app/routes/index.py +++ b/knowledge_repo/app/routes/index.py @@ -41,7 +41,7 @@ def site_map(): # url = url_for(rule.endpoint, **(rule.defaults or {})) links.append((str(rule), rule.endpoint)) # links is now a list of url, endpoint tuples - return u'
'.join(str(link) for link in links) + return '
'.join(str(link) for link in links) @blueprint.route('/') @@ -218,7 +218,7 @@ def unpack(d): _, grouped_data = unpack(folder_to_posts) else: - raise ValueError(u"Group by `{}` not understood.".format(group_by)) + raise ValueError("Group by `{}` not understood.".format(group_by)) def rec_sort(content, sort_by): sorted_content = [] @@ -328,5 +328,5 @@ def generate_projects_typeahead(): if not permissions.index_view.can(): return '[]' # return path stubs for all repositories - stubs = [u'/'.join(p.split('/')[:-1]) for p in current_repo.dir()] + stubs = ['/'.join(p.split('/')[:-1]) for p in current_repo.dir()] return json.dumps(list(set(stubs))) diff --git a/knowledge_repo/app/routes/posts.py b/knowledge_repo/app/routes/posts.py index 353602dfd..0b6f43b55 100755 --- a/knowledge_repo/app/routes/posts.py +++ b/knowledge_repo/app/routes/posts.py @@ -53,7 +53,7 @@ def render(path): .filter(Post.path == knowledge_aliases[path]) .first()) if not post: - logger.warning(u"unable to find post at {}".format(path)) + logger.warning("unable to find post at {}".format(path)) return abort(404) if post.contains_excluded_tag: # It's possible that someone gets a direct link to a post that has an excluded tag @@ -145,7 +145,7 @@ def _render_preview(path, tmpl): post = current_repo.post(knowledge_aliases[path]) if not post: - raise Exception(u"unable to find post at {}".format(path)) + raise Exception("unable to find post at {}".format(path)) rendered = render_post(post, with_toc=True) raw_post = render_post_raw(post) if (mode == 'raw') else None @@ -158,7 +158,7 @@ def _render_preview(path, tmpl): raw_post=raw_post, comments=[], username=None, - post_author=u', '.join(post.headers['authors']), + post_author=', '.join(post.headers['authors']), title=post.headers['title'], page_views=0, unique_views=0, @@ -195,13 +195,13 @@ def download(): return Response( post.to_string(format=resource_type), mimetype="application/zip", - headers={u"Content-disposition": "attachment; filename={}".format(filename)}) + headers={"Content-disposition": "attachment; filename={}".format(filename)}) elif resource_type == 'pdf': filename = os.path.basename(post.path)[:-3] + '.pdf' return Response( post.to_string(format=resource_type), mimetype="application/pdf", - headers={u"Content-disposition": "attachment; filename={}".format(filename)}) + headers={"Content-disposition": "attachment; filename={}".format(filename)}) elif resource_type == 'source': path = request.args.get('path', None) assert path is not None, "Source path not provided." @@ -209,6 +209,6 @@ def download(): return Response( post._read_ref(path), mimetype="application/octet-stream", - headers={u"Content-disposition": "attachment; filename={}".format(os.path.basename(path))}) + headers={"Content-disposition": "attachment; filename={}".format(os.path.basename(path))}) else: - raise RuntimeError(u"Invalid resource_type: {}".format(resource_type)) + raise RuntimeError("Invalid resource_type: {}".format(resource_type)) diff --git a/knowledge_repo/app/utils/emails.py b/knowledge_repo/app/utils/emails.py index 25741b8f7..1130765f5 100644 --- a/knowledge_repo/app/utils/emails.py +++ b/knowledge_repo/app/utils/emails.py @@ -89,7 +89,7 @@ def send_subscription_email(post, tag): return default_recipients = ['knowledge_consumer@notreal.com'] - subject = u"New knowledge post: {}".format(post.title) + subject = "New knowledge post: {}".format(post.title) post_authors = [p.format_name for p in post.authors] post_tags = [t.name for t in post.tags] msg = Message(subject=subject, recipients=default_recipients, bcc=recipients_bcc) diff --git a/knowledge_repo/app/utils/render.py b/knowledge_repo/app/utils/render.py index c7042fa40..e0b6f2cfd 100644 --- a/knowledge_repo/app/utils/render.py +++ b/knowledge_repo/app/utils/render.py @@ -34,7 +34,7 @@ def render_post_tldr(post): def render_post_header(post): - header_template = Template(u""" + header_template = Template("""