diff --git a/ietf/api/serializer.py b/ietf/api/serializer.py index 98e276efe..dd178b419 100644 --- a/ietf/api/serializer.py +++ b/ietf/api/serializer.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2018-2019, All Rights Reserved +# Copyright The IETF Trust 2018-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -6,7 +6,6 @@ from __future__ import absolute_import, print_function, unicode_literals import hashlib import json -import six from django.core.cache import cache from django.core.exceptions import ObjectDoesNotExist, FieldError @@ -154,7 +153,7 @@ class AdminJsonSerializer(Serializer): if hasattr(field_value, "_meta"): self._current[name] = self.expand_related(field_value, name) else: - self._current[name] = six.text_type(field_value) + self._current[name] = str(field_value) except ObjectDoesNotExist: pass except AttributeError: diff --git a/ietf/bin/rfc-editor-index-updates b/ietf/bin/rfc-editor-index-updates index e9ac43a6c..0a6315a2f 100755 --- a/ietf/bin/rfc-editor-index-updates +++ b/ietf/bin/rfc-editor-index-updates @@ -11,7 +11,7 @@ import sys import syslog import traceback -from six.moves.urllib.request import urlopen +from urllib.request import urlopen # boilerplate basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) diff --git a/ietf/bin/rfc-editor-queue-updates b/ietf/bin/rfc-editor-queue-updates index a279346c7..bc1d4ab8b 100755 --- a/ietf/bin/rfc-editor-queue-updates +++ b/ietf/bin/rfc-editor-queue-updates @@ -3,7 +3,7 @@ import os import socket import sys -from six.moves.urllib.request import urlopen +from urllib.request import urlopen # boilerplate basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) diff --git a/ietf/checks.py b/ietf/checks.py index 235824c68..a1d76520a 100644 --- a/ietf/checks.py +++ b/ietf/checks.py @@ -5,12 +5,10 @@ from __future__ import absolute_import, print_function, unicode_literals import os -import six import sys import time from textwrap import dedent -if six.PY3: - from typing import List, Tuple # pyflakes:ignore +from typing import List, Tuple # pyflakes:ignore import debug # pyflakes:ignore debug.debug = True diff --git a/ietf/community/views.py b/ietf/community/views.py index c1a061e5d..8c1647384 100644 --- a/ietf/community/views.py +++ b/ietf/community/views.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2012-2019, All Rights Reserved +# Copyright The IETF Trust 2012-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -7,7 +7,6 @@ from __future__ import absolute_import, print_function, unicode_literals import csv import datetime import json -import six import uuid from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect, Http404 @@ -204,7 +203,7 @@ def export_to_csv(request, username=None, acronym=None, group_type=None): row.append(e.time.strftime("%Y-%m-%d") if e else "") row.append(strip_tags(doc.friendly_state())) row.append(doc.group.acronym if doc.group else "") - row.append(six.text_type(doc.ad) if doc.ad else "") + row.append(str(doc.ad) if doc.ad else "") e = doc.latest_event() row.append(e.time.strftime("%Y-%m-%d") if e else "") writer.writerow([v.encode("utf-8") for v in row]) diff --git a/ietf/doc/feeds.py b/ietf/doc/feeds.py index bcdefe112..5ee3b8bad 100644 --- a/ietf/doc/feeds.py +++ b/ietf/doc/feeds.py @@ -1,11 +1,10 @@ -# Copyright The IETF Trust 2007-2019, All Rights Reserved +# Copyright The IETF Trust 2007-2020, All Rights Reserved # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals import datetime -import six from django.contrib.syndication.views import Feed, FeedDoesNotExist from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed @@ -50,7 +49,7 @@ class DocumentChangesFeed(Feed): return item.time def item_author_name(self, item): - return six.text_type(item.by) + return str(item.by) def item_link(self, item): return urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=item.doc.canonical_name())) + "#history-%s" % item.pk diff --git a/ietf/doc/fields.py b/ietf/doc/fields.py index 7266f5d34..e4d1ed16d 100644 --- a/ietf/doc/fields.py +++ b/ietf/doc/fields.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2014-2019, All Rights Reserved +# Copyright The IETF Trust 2014-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -83,7 +83,7 @@ class SearchableDocumentsField(forms.CharField): "model_name": self.model.__name__.lower() }) - return ",".join(six.text_type(o.pk) for o in value) + return ",".join(str(o.pk) for o in value) def clean(self, value): value = super(SearchableDocumentsField, self).clean(value) diff --git a/ietf/doc/mails.py b/ietf/doc/mails.py index a36c06185..112c38292 100644 --- a/ietf/doc/mails.py +++ b/ietf/doc/mails.py @@ -6,7 +6,6 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime -import six import textwrap from django.template.loader import render_to_string @@ -288,7 +287,7 @@ def generate_publication_request(request, doc): approving_body = "IRSG" consensus_body = doc.group.acronym.upper() else: - approving_body = six.text_type(doc.stream) + approving_body = str(doc.stream) consensus_body = approving_body e = doc.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text") diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py index 61fe9404c..afb2eacb3 100644 --- a/ietf/doc/templatetags/ietf_filters.py +++ b/ietf/doc/templatetags/ietf_filters.py @@ -22,10 +22,11 @@ from django.utils.encoding import force_str # pyflakes:ignore force_str is used import debug # pyflakes:ignore -from ietf.doc.models import ConsensusDocEvent -from ietf.utils.text import wordwrap, fill, wrap_text_if_unwrapped -from ietf.utils.html import sanitize_fragment from ietf.doc.models import BallotDocEvent +from ietf.doc.models import ConsensusDocEvent +from ietf.utils.html import sanitize_fragment +from ietf.utils import log +from ietf.utils.text import wordwrap, fill, wrap_text_if_unwrapped register = template.Library() @@ -70,7 +71,7 @@ def parse_email_list(value): """ - if value and isinstance(value, (six.binary_type, six.text_type)): # testing for 'value' being true isn't necessary; it's a fast-out route + if value and isinstance(value, str): # testing for 'value' being true isn't necessary; it's a fast-out route addrs = re.split(", ?", value) ret = [] for addr in addrs: @@ -79,6 +80,8 @@ def parse_email_list(value): name = email ret.append('%s' % ( email.replace('&', '&'), escape(name) )) return mark_safe(", ".join(ret)) + elif value and isinstance(value, bytes): + log.assertion('isinstance(value, str)') else: return value @@ -151,10 +154,12 @@ def sanitize(value): @register.filter(name='bracket') def square_brackets(value): """Adds square brackets around text.""" - if isinstance(value, (six.binary_type, six.text_type)): + if isinstance(value, str): if value == "": value = " " return "[ %s ]" % value + elif isinstance(value, bytes): + log.assertion('isinstance(value, str)') elif value > 0: return "[ X ]" elif value < 0: @@ -344,7 +349,7 @@ def expires_soon(x,request): @register.filter(name='startswith') def startswith(x, y): - return six.text_type(x).startswith(y) + return str(x).startswith(y) @register.filter def has_role(user, role_names): diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index 73cab0089..a3443003f 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -42,7 +42,6 @@ import io import json import os import re -import six from six.moves.urllib.parse import quote @@ -1397,7 +1396,7 @@ def add_sessionpresentation(request,name): if doc.group: sessions = sorted(sessions,key=lambda x:0 if x.group==doc.group else 1) - session_choices = [(s.pk, six.text_type(s)) for s in sessions] + session_choices = [(s.pk, str(s)) for s in sessions] if request.method == 'POST': version_form = VersionForm(request.POST,choices=version_choices) diff --git a/ietf/group/tests_info.py b/ietf/group/tests_info.py index 514e0d636..ae2aed9d5 100644 --- a/ietf/group/tests_info.py +++ b/ietf/group/tests_info.py @@ -10,7 +10,6 @@ import calendar import datetime import io import bleach -import six from pyquery import PyQuery from tempfile import NamedTemporaryFile @@ -1442,7 +1441,7 @@ class StatusUpdateTests(TestCase): response = self.client.get(url) self.assertEqual(response.status_code,200) q=PyQuery(response.content) - self.assertTrue(bleach.linkify(escape(event.desc)) in six.text_type(q('pre'))) + self.assertTrue(bleach.linkify(escape(event.desc)) in str(q('pre'))) self.assertFalse(q('a#edit_button')) self.client.login(username=chair.person.user.username,password='%s+password'%chair.person.user.username) response = self.client.get(url) diff --git a/ietf/group/tests_review.py b/ietf/group/tests_review.py index f498a2edb..2f9058c0a 100644 --- a/ietf/group/tests_review.py +++ b/ietf/group/tests_review.py @@ -6,7 +6,6 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime import debug # pyflakes:ignore -import six from pyquery import PyQuery @@ -522,7 +521,7 @@ class ReviewTests(TestCase): # i.e. the document name is expected twice in the output (#2118) self.assertEqual(generated_text.count(review_req1.doc.name), 2) self.assertEqual(generated_text.count('(-0 lc reviewed)'), 2) # previous completed assignment - self.assertTrue(six.text_type(Person.objects.get(user__username="marschairman")) in generated_text) + self.assertTrue(str(Person.objects.get(user__username="marschairman")) in generated_text) empty_outbox() r = self.client.post(url, { diff --git a/ietf/group/views.py b/ietf/group/views.py index 6994625b2..90429a4e7 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -44,7 +44,6 @@ import json import math import os import re -import six from tempfile import mkstemp from collections import OrderedDict, defaultdict @@ -1539,7 +1538,7 @@ def manage_review_requests(request, acronym, group_type=None, assignment_status= saving = form_action.startswith("save") # check for conflicts - review_requests_dict = { six.text_type(r.pk): r for r in review_requests if r.pk} + review_requests_dict = { str(r.pk): r for r in review_requests if r.pk} posted_reqs = set(request.POST.getlist("reviewrequest", [])) posted_reqs.discard(u'None') current_reqs = set(review_requests_dict.keys()) diff --git a/ietf/idindex/index.py b/ietf/idindex/index.py index 03d5f2b2d..35197cdb4 100644 --- a/ietf/idindex/index.py +++ b/ietf/idindex/index.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2013-2019, All Rights Reserved +# Copyright The IETF Trust 2013-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -10,7 +10,6 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime import os import pytz -import six from django.conf import settings from django.template.loader import render_to_string @@ -195,7 +194,7 @@ def all_id2_txt(): area = d.group.parent.acronym fields.append(area) # 9 responsible AD name - fields.append(six.text_type(d.ad) if d.ad else "") + fields.append(str(d.ad) if d.ad else "") # 10 fields.append(d.intended_std_level.name if d.intended_std_level else "") # 11 diff --git a/ietf/idindex/tests.py b/ietf/idindex/tests.py index 07b0eebd7..4b234f412 100644 --- a/ietf/idindex/tests.py +++ b/ietf/idindex/tests.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2009-2019, All Rights Reserved +# Copyright The IETF Trust 2009-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -8,7 +8,6 @@ import datetime import io import os import shutil -import six from django.conf import settings @@ -102,7 +101,7 @@ class IndexTests(TestCase): self.assertEqual(t[6], draft.latest_event(type="new_revision").time.strftime("%Y-%m-%d")) self.assertEqual(t[7], draft.group.acronym) self.assertEqual(t[8], draft.group.parent.acronym) - self.assertEqual(t[9], six.text_type(draft.ad)) + self.assertEqual(t[9], str(draft.ad)) self.assertEqual(t[10], draft.intended_std_level.name) self.assertEqual(t[11], "") self.assertEqual(t[12], ".pdf,.txt") diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py index 9d3a9bb4a..d03de500a 100644 --- a/ietf/iesg/views.py +++ b/ietf/iesg/views.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2007-2019, All Rights Reserved +# Copyright The IETF Trust 2007-2020, All Rights Reserved # -*- coding: utf-8 -*- # # Portion Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). @@ -41,7 +41,6 @@ import io import itertools import json import os -import six import tarfile import time @@ -317,9 +316,9 @@ def agenda_documents_txt(request): row = ( d.computed_telechat_date.isoformat(), d.name, - six.text_type(d.intended_std_level), + str(d.intended_std_level), "1" if d.stream_id in ("ise", "irtf") else "0", - six.text_type(d.area_acronym()).lower(), + (d.area_acronym() or 'none').lower(), d.ad.plain_name() if d.ad else "None Assigned", d.rev, ) diff --git a/ietf/ipr/fields.py b/ietf/ipr/fields.py index 4b9987967..6d11b1b3c 100644 --- a/ietf/ipr/fields.py +++ b/ietf/ipr/fields.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2014-2019, All Rights Reserved +# Copyright The IETF Trust 2014-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -70,7 +70,7 @@ class SearchableIprDisclosuresField(forms.CharField): # patterns may not have been fully constructed there yet self.widget.attrs["data-ajax-url"] = urlreverse('ietf.ipr.views.ajax_search') - return ",".join(six.text_type(e.pk) for e in value) + return ",".join(str(e.pk) for e in value) def clean(self, value): value = super(SearchableIprDisclosuresField, self).clean(value) diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index 81df9ab95..238e32973 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2007-2019, All Rights Reserved +# Copyright The IETF Trust 2007-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -6,7 +6,6 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime import itertools -import six from django.conf import settings from django.contrib import messages @@ -456,7 +455,7 @@ def by_draft_txt(request): lines = [ "# Machine-readable list of IPR disclosures by draft name" ] for name, iprs in docipr.items(): - lines.append(name + "\t" + "\t".join(six.text_type(ipr_id) for ipr_id in sorted(iprs))) + lines.append(name + "\t" + "\t".join(str(ipr_id) for ipr_id in sorted(iprs))) return HttpResponse("\n".join(lines), content_type="text/plain; charset=%s"%settings.DEFAULT_CHARSET) @@ -478,7 +477,7 @@ def by_draft_recursive_txt(request): lines = [ "# Machine-readable list of IPR disclosures by draft name" ] for name, iprs in docipr.items(): - lines.append(name + "\t" + "\t".join(six.text_type(ipr_id) for ipr_id in sorted(iprs))) + lines.append(name + "\t" + "\t".join(str(ipr_id) for ipr_id in sorted(iprs))) return HttpResponse("\n".join(lines), content_type="text/plain; charset=%s"%settings.DEFAULT_CHARSET) diff --git a/ietf/liaisons/fields.py b/ietf/liaisons/fields.py index 6f21b7c74..1fe2afae0 100644 --- a/ietf/liaisons/fields.py +++ b/ietf/liaisons/fields.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2014-2019, All Rights Reserved +# Copyright The IETF Trust 2014-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -65,7 +65,7 @@ class SearchableLiaisonStatementsField(forms.CharField): # patterns may not have been fully constructed there yet self.widget.attrs["data-ajax-url"] = urlreverse("ietf.liaisons.views.ajax_select2_search_liaison_statements") - return ",".join(six.text_type(o.pk) for o in value) + return ",".join(str(o.pk) for o in value) def clean(self, value): value = super(SearchableLiaisonStatementsField, self).clean(value) diff --git a/ietf/liaisons/forms.py b/ietf/liaisons/forms.py index 8f409fb90..5bab1ba64 100644 --- a/ietf/liaisons/forms.py +++ b/ietf/liaisons/forms.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2011-2019, All Rights Reserved +# Copyright The IETF Trust 2011-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -206,7 +206,7 @@ class CustomModelMultipleChoiceField(forms.ModelMultipleChoiceField): if isinstance(value, QuerySet): return value if (hasattr(value, '__iter__') and - not isinstance(value, six.text_type) and + not isinstance(value, str) and not hasattr(value, '_meta')): return [super(CustomModelMultipleChoiceField, self).prepare_value(v) for v in value] return super(CustomModelMultipleChoiceField, self).prepare_value(value) @@ -454,7 +454,7 @@ class IncomingLiaisonForm(LiaisonModelForm): self.fields['from_contact'].initial = self.person.role_set.filter(group=queryset[0]).first().email.address self.fields['from_contact'].widget.attrs['readonly'] = True self.fields['from_groups'].queryset = queryset - self.fields['from_groups'].widget.submitter = six.text_type(self.person) + self.fields['from_groups'].widget.submitter = str(self.person) # if there's only one possibility make it the default if len(queryset) == 1: diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 60c4142fc..f802b7539 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -1,17 +1,18 @@ -# Copyright The IETF Trust 2007-2019, All Rights Reserved +# Copyright The IETF Trust 2007-2020, All Rights Reserved # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals # old meeting models can be found in ../proceedings/models.py -import pytz import datetime import io -from six.moves.urllib.parse import urljoin import os +import pytz import re import string +from urllib.parse import urljoin + import debug # pyflakes:ignore from django.core.validators import MinValueValidator diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 2dd0f57d9..00fc826ba 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -436,7 +436,7 @@ class MeetingTests(TestCase): response = self.client.get(url) self.assertContains(response, 'test acknowledgements') - @patch('six.moves.urllib.request.urlopen') + @patch('urllib.request.urlopen') def test_proceedings_attendees(self, mock_urlopen): mock_urlopen.return_value = six.BytesIO(b'[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]') make_meeting_test_data() @@ -448,7 +448,7 @@ class MeetingTests(TestCase): q = PyQuery(response.content) self.assertEqual(1,len(q("#id_attendees tbody tr"))) - @patch('six.moves.urllib.request.urlopen') + @patch('urllib.request.urlopen') def test_proceedings_overview(self, mock_urlopen): '''Test proceedings IETF Overview page. Note: old meetings aren't supported so need to add a new meeting then test. @@ -2041,7 +2041,7 @@ class IphoneAppJsonTests(TestCase): self.assertEqual(r.status_code,200) class FinalizeProceedingsTests(TestCase): - @patch('six.moves.urllib.request.urlopen') + @patch('urllib.request.urlopen') def test_finalize_proceedings(self, mock_urlopen): mock_urlopen.return_value = BytesIO(b'[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]') make_meeting_test_data() @@ -2103,7 +2103,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("title"))) + self.assertIn('Upload', str(q("title"))) self.assertFalse(session.sessionpresentation_set.exists()) test_file = StringIO('%PDF-1.4\n%âãÏÓ\nthis is some text for a test') test_file.name = "not_really.pdf" @@ -2114,7 +2114,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Revise', six.text_type(q("title"))) + self.assertIn('Revise', str(q("title"))) test_file = StringIO('%PDF-1.4\n%âãÏÓ\nthis is some different text for a test') test_file.name = "also_not_really.pdf" r = self.client.post(url,dict(file=test_file)) @@ -2138,7 +2138,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("title"))) + self.assertIn('Upload', str(q("title"))) self.assertFalse(session.sessionpresentation_set.exists()) test_file = StringIO('%PDF-1.4\n%âãÏÓ\nthis is some text for a test') test_file.name = "not_really.pdf" @@ -2156,7 +2156,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("title"))) + self.assertIn('Upload', str(q("title"))) def test_upload_minutes_agenda(self): @@ -2171,7 +2171,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("Title"))) + self.assertIn('Upload', str(q("Title"))) self.assertFalse(session.sessionpresentation_set.exists()) self.assertFalse(q('form input[type="checkbox"]')) @@ -2226,7 +2226,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Revise', six.text_type(q("Title"))) + self.assertIn('Revise', str(q("Title"))) test_file = BytesIO(b'this is some different text for a test') test_file.name = "also_some.txt" r = self.client.post(url,dict(file=test_file,apply_to_all=True)) @@ -2260,7 +2260,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("Title"))) + self.assertIn('Upload', str(q("Title"))) self.assertFalse(session.sessionpresentation_set.exists()) self.assertFalse(q('form input[type="checkbox"]')) @@ -2281,7 +2281,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("title"))) + self.assertIn('Upload', str(q("title"))) self.assertFalse(session.sessionpresentation_set.filter(document__type_id=doctype)) test_file = BytesIO(b'this is some text for a test') test_file.name = "not_really.txt" @@ -2304,7 +2304,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Upload', six.text_type(q("title"))) + self.assertIn('Upload', str(q("title"))) self.assertFalse(session1.sessionpresentation_set.filter(document__type_id='slides')) test_file = BytesIO(b'this is not really a slide') test_file.name = 'not_really.txt' @@ -2332,7 +2332,7 @@ class MaterialsTests(TestCase): r = self.client.get(url) self.assertTrue(r.status_code, 200) q = PyQuery(r.content) - self.assertIn('Revise', six.text_type(q("title"))) + self.assertIn('Revise', str(q("title"))) test_file = BytesIO(b'new content for the second slide deck') test_file.name = 'doesnotmatter.txt' r = self.client.post(url,dict(file=test_file,title='rename the presentation',apply_to_all=False)) diff --git a/ietf/meeting/utils.py b/ietf/meeting/utils.py index e7b696274..3daee71a9 100644 --- a/ietf/meeting/utils.py +++ b/ietf/meeting/utils.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2016-2019, All Rights Reserved +# Copyright The IETF Trust 2016-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -6,7 +6,7 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime import json -import six.moves.urllib.request +import urllib.request from six.moves.urllib.error import HTTPError from django.conf import settings @@ -115,7 +115,7 @@ def create_proceedings_templates(meeting): # Get meeting attendees from registration system url = settings.STATS_REGISTRATION_ATTENDEES_JSON_URL.format(number=meeting.number) try: - attendees = json.load(six.moves.urllib.request.urlopen(url)) + attendees = json.load(urllib.request.urlopen(url)) except (ValueError, HTTPError): attendees = [] diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 89e61b12b..a390dccfc 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -13,14 +13,13 @@ import json import os import pytz import re -import six import tarfile import markdown2 from calendar import timegm from collections import OrderedDict, Counter, deque -from six.moves.urllib.parse import unquote +from urllib.parse import unquote from tempfile import mkstemp from wsgiref.handlers import format_date_time @@ -556,7 +555,7 @@ def agenda_csv(schedule, filtered_assignments): headings = ["Date", "Start", "End", "Session", "Room", "Area", "Acronym", "Type", "Description", "Session ID", "Agenda", "Slides"] def write_row(row): - encoded_row = [v.encode('utf-8') if isinstance(v, six.text_type) else v for v in row] + encoded_row = [v.encode('utf-8') if isinstance(v, str) else v for v in row] while len(encoded_row) < len(headings): encoded_row.append(None) # produce empty entries at the end as necessary diff --git a/ietf/nomcom/forms.py b/ietf/nomcom/forms.py index fe8942bbc..5f41652a2 100644 --- a/ietf/nomcom/forms.py +++ b/ietf/nomcom/forms.py @@ -42,12 +42,12 @@ class PositionNomineeField(forms.ChoiceField): results = [] for position in positions: accepted_nominees = [np.nominee for np in NomineePosition.objects.filter(position=position,state='accepted').exclude(nominee__duplicated__isnull=False)] - nominees = [('%s_%s' % (position.id, i.id), six.text_type(i)) for i in accepted_nominees] + nominees = [('%s_%s' % (position.id, i.id), str(i)) for i in accepted_nominees] if nominees: results.append((position.name+" (Accepted)", nominees)) for position in positions: other_nominees = [np.nominee for np in NomineePosition.objects.filter(position=position).exclude(state='accepted').exclude(nominee__duplicated__isnull=False)] - nominees = [('%s_%s' % (position.id, i.id), six.text_type(i)) for i in other_nominees] + nominees = [('%s_%s' % (position.id, i.id), str(i)) for i in other_nominees] if nominees: results.append((position.name+" (Declined or Pending)", nominees)) kwargs['choices'] = results diff --git a/ietf/person/fields.py b/ietf/person/fields.py index 077b6c4ca..77246ac29 100644 --- a/ietf/person/fields.py +++ b/ietf/person/fields.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2012-2019, All Rights Reserved +# Copyright The IETF Trust 2012-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -179,7 +179,7 @@ class PersonEmailChoiceField(forms.ModelChoiceField): def label_from_instance(self, email): if self.label_with == "person": - return six.text_type(email.person) + return str(email.person) elif self.label_with == "email": return email.address else: diff --git a/ietf/person/models.py b/ietf/person/models.py index 92cf46f64..8e99c5cce 100644 --- a/ietf/person/models.py +++ b/ietf/person/models.py @@ -88,9 +88,8 @@ class Person(models.Model): def plain_ascii(self): if not hasattr(self, '_cached_plain_ascii'): if self.ascii: - if isinstance(self.ascii, six.binary_type): - uname = six.text_type(self.ascii) - ascii = unidecode_name(uname) + if isinstance(self.ascii, bytes): + ascii = unidecode_name(self.ascii.decode('utf-8')) else: ascii = unidecode_name(self.ascii) else: diff --git a/ietf/person/tests.py b/ietf/person/tests.py index 29215be95..fd3129e42 100644 --- a/ietf/person/tests.py +++ b/ietf/person/tests.py @@ -5,7 +5,6 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime -import six from pyquery import PyQuery from io import StringIO @@ -94,7 +93,7 @@ class PersonTests(TestCase): empty_outbox() p = PersonFactory(name="Föö Bär") PersonFactory(name=p.name) - self.assertTrue("possible duplicate" in six.text_type(outbox[0]["Subject"]).lower()) + self.assertTrue("possible duplicate" in str(outbox[0]["Subject"]).lower()) def test_merge(self): url = urlreverse("ietf.person.views.merge") diff --git a/ietf/review/mailarch.py b/ietf/review/mailarch.py index 3ad1dbd30..b56ec3355 100644 --- a/ietf/review/mailarch.py +++ b/ietf/review/mailarch.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2016-2019, All Rights Reserved +# Copyright The IETF Trust 2016-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -18,7 +18,7 @@ import base64 import email.utils from six.moves.urllib.parse import urlencode -from six.moves.urllib.request import urlopen +from urllib.request import urlopen import debug # pyflakes:ignore diff --git a/ietf/review/policies.py b/ietf/review/policies.py index 8946bd5c6..ffd3582e6 100644 --- a/ietf/review/policies.py +++ b/ietf/review/policies.py @@ -1,10 +1,9 @@ -# Copyright The IETF Trust 2019, All Rights Reserved +# Copyright The IETF Trust 2019-2020, All Rights Reserved from __future__ import absolute_import, print_function, unicode_literals import re -import six from django.db.models.aggregates import Max from ietf.doc.models import DocumentAuthor, DocAlias @@ -289,7 +288,7 @@ class AssignmentOrderResolver: if stats: explanations.append(", ".join(stats)) - label = six.text_type(email.person) + label = str(email.person) if explanations: label = "{}: {}".format(label, "; ".join(explanations)) return { diff --git a/ietf/secr/sreq/tests.py b/ietf/secr/sreq/tests.py index 24d9009a2..c556a02b8 100644 --- a/ietf/secr/sreq/tests.py +++ b/ietf/secr/sreq/tests.py @@ -5,7 +5,6 @@ from __future__ import absolute_import, print_function, unicode_literals import datetime -import six from django.urls import reverse @@ -227,14 +226,14 @@ class SubmitRequestCase(TestCase): r = self.client.post(url,post_data) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertTrue('Confirm' in six.text_type(q("title"))) + self.assertTrue('Confirm' in str(q("title"))) # confirm post_data['submit'] = 'Submit' r = self.client.post(confirm_url,post_data) self.assertRedirects(r, reverse('ietf.secr.sreq.views.main')) self.assertEqual(len(outbox),len_before+1) notification = outbox[-1] - notification_payload = six.text_type(notification.get_payload(decode=True),"utf-8","replace") + notification_payload = notification.get_payload(decode=True).decode(encoding="utf-8", errors="replace") session = Session.objects.get(meeting=meeting,group=group) self.assertEqual(session.resources.count(),1) self.assertEqual(session.people_constraints.count(),1) diff --git a/ietf/settings.py b/ietf/settings.py index 88c7ebaed..691707e19 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -9,12 +9,10 @@ from __future__ import absolute_import, print_function, unicode_literals # http://code.djangoproject.com/wiki/SplitSettings import os -import six import sys import datetime import warnings -if six.PY3: - from typing import Any, Dict, List, Tuple # pyflakes:ignore +from typing import Any, Dict, List, Tuple # pyflakes:ignore warnings.simplefilter("always", DeprecationWarning) warnings.filterwarnings("ignore", message="Report.file_reporters will no longer be available in Coverage.py 4.2", module="coverage.report") diff --git a/ietf/stats/backfill_data.py b/ietf/stats/backfill_data.py index 41fca2049..91f5c50d9 100755 --- a/ietf/stats/backfill_data.py +++ b/ietf/stats/backfill_data.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright The IETF Trust 2017-2019, All Rights Reserved +# Copyright The IETF Trust 2017-2020, All Rights Reserved # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals @@ -133,10 +133,10 @@ for doc in docs_qs.prefetch_related("docalias", "formal_languages", "documentaut # it's an extra author - skip those extra authors seen = set() # type: Set[Optional[str]] for full, _, _, _, _, email, country, company in d.get_author_list(): - assert full is None or isinstance(full, six.text_type) - assert email is None or isinstance(email, six.text_type) - assert country is None or isinstance(country, six.text_type) - assert isinstance(company, six.text_type) + assert full is None or isinstance(full, str) + assert email is None or isinstance(email, str) + assert country is None or isinstance(country, str) + assert isinstance(company, str) #full, email, country, company = [ unicode(s) for s in [full, email, country, company, ] ] if email in seen: continue diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py index 8d83eb9fa..205682b09 100644 --- a/ietf/submit/forms.py +++ b/ietf/submit/forms.py @@ -202,11 +202,11 @@ class SubmissionBaseUploadForm(forms.Form): self.revision = None self.filename = draftname self.title = self.xmlroot.findtext('front/title').strip() - if type(self.title) is six.text_type: + if type(self.title) is str: self.title = unidecode(self.title) self.title = normalize_text(self.title) self.abstract = (self.xmlroot.findtext('front/abstract') or '').strip() - if type(self.abstract) is six.text_type: + if type(self.abstract) is str: self.abstract = unidecode(self.abstract) author_info = self.xmlroot.findall('front/author') for author in author_info: diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 7cc5d34d5..4af95af10 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -421,7 +421,7 @@ class SubmitTests(TestCase): self.assertTrue("unknown-email-" not in confirm_email["To"]) if change_authors: # Since authors changed, ensure chairs are copied (and that the message says why) - self.assertTrue("chairs have been copied" in six.text_type(confirm_email)) + self.assertTrue("chairs have been copied" in str(confirm_email)) if group_type in ['wg','rg','ag']: self.assertTrue("mars-chairs@" in confirm_email["To"].lower()) elif group_type == 'area': @@ -431,7 +431,7 @@ class SubmitTests(TestCase): if stream_type=='ise': self.assertTrue("rfc-ise@" in confirm_email["To"].lower()) else: - self.assertNotIn("chairs have been copied", six.text_type(confirm_email)) + self.assertNotIn("chairs have been copied", str(confirm_email)) self.assertNotIn("mars-chairs@", confirm_email["To"].lower()) confirmation_url = self.extract_confirmation_url(confirm_email) @@ -570,7 +570,7 @@ class SubmitTests(TestCase): # both submitter and author get email self.assertTrue(author.email().address.lower() in confirm_email["To"]) self.assertTrue("submitter@example.com" in confirm_email["To"]) - self.assertFalse("chairs have been copied" in six.text_type(confirm_email)) + self.assertFalse("chairs have been copied" in str(confirm_email)) confirmation_url = self.extract_confirmation_url(outbox[-1]) diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py index 0b0b74bf0..6083539c0 100644 --- a/ietf/submit/utils.py +++ b/ietf/submit/utils.py @@ -493,7 +493,7 @@ def ensure_person_email_info_exists(name, email, docname): person = Person() person.name = name person.name_from_draft = name - log.assertion('isinstance(person.name, six.text_type)') + log.assertion('isinstance(person.name, str)') person.ascii = unidecode_name(person.name) person.save() else: @@ -682,7 +682,7 @@ def get_draft_meta(form, saved_files): if s is None: return "" - if isinstance(s, six.text_type): + if isinstance(s, str): return s else: try: diff --git a/ietf/sync/iana.py b/ietf/sync/iana.py index 186272674..e80772cec 100644 --- a/ietf/sync/iana.py +++ b/ietf/sync/iana.py @@ -10,7 +10,7 @@ import email import json import re -from six.moves.urllib.request import Request, urlopen +from urllib.request import Request, urlopen from django.conf import settings from django.utils.encoding import smart_bytes, force_str diff --git a/ietf/sync/rfceditor.py b/ietf/sync/rfceditor.py index 645e3d78c..ce74a5b7b 100644 --- a/ietf/sync/rfceditor.py +++ b/ietf/sync/rfceditor.py @@ -7,9 +7,8 @@ from __future__ import absolute_import, print_function, unicode_literals import base64 import datetime import re -import six -from six.moves.urllib.request import Request, urlopen +from urllib.request import Request, urlopen from six.moves.urllib.parse import urlencode from xml.dom import pulldom, Node @@ -560,6 +559,6 @@ def post_approved_draft(url, name): log(msg) if settings.SERVER_MODE == 'test': debug.say(msg) - error = six.text_type(e) + error = str(e) return text, error diff --git a/ietf/utils/admin.py b/ietf/utils/admin.py index ec141b78c..cf37dcff9 100644 --- a/ietf/utils/admin.py +++ b/ietf/utils/admin.py @@ -1,10 +1,9 @@ -# Copyright The IETF Trust 2011-2019, All Rights Reserved +# Copyright The IETF Trust 2011-2020, All Rights Reserved # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals -import six from django.contrib import admin from django.utils.encoding import force_text @@ -21,7 +20,7 @@ def name(obj): name = force_text(obj.name) if name: return name - return six.text_type(obj) + return str(obj) def admin_link(field, label=None, ordering="", display=name, suffix=""): if not label: diff --git a/ietf/utils/draft.py b/ietf/utils/draft.py index 368d545eb..d19e671b1 100755 --- a/ietf/utils/draft.py +++ b/ietf/utils/draft.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright The IETF Trust 2009-2019, All Rights Reserved +# Copyright The IETF Trust 2009-2020, All Rights Reserved # -*- coding: utf-8 -*- # -*- python -*- @@ -136,7 +136,7 @@ def acronym_match(s, l): class Draft(): def __init__(self, text, source, name_from_source=False): - assert isinstance(text, six.text_type) + assert isinstance(text, str) self.source = source self.rawtext = text self.name_from_source = name_from_source diff --git a/ietf/utils/mail.py b/ietf/utils/mail.py index 8e997c306..e535e6921 100644 --- a/ietf/utils/mail.py +++ b/ietf/utils/mail.py @@ -189,7 +189,7 @@ def send_mail(request, to, frm, subject, template, context, *args, **kwargs): return send_mail_text(request, to, frm, subject, txt, *args, **kwargs) def encode_message(txt): - assert isinstance(txt, six.text_type) + assert isinstance(txt, str) return MIMEText(txt.encode('utf-8'), 'plain', 'UTF-8') def send_mail_text(request, to, frm, subject, txt, cc=None, extra=None, toUser=False, bcc=None, copy=True, save=True): diff --git a/ietf/utils/markup_txt.py b/ietf/utils/markup_txt.py index 6e680fd81..b45f7b75b 100644 --- a/ietf/utils/markup_txt.py +++ b/ietf/utils/markup_txt.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2009-2019, All Rights Reserved +# Copyright The IETF Trust 2009-2020, All Rights Reserved # -*- coding: utf-8 -*- # # Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). @@ -45,7 +45,7 @@ from ietf.utils import log from ietf.utils.text import wordwrap def markup(content, width=None): - log.assertion('isinstance(content, six.text_type)') + log.assertion('isinstance(content, str)') # normalize line endings to LF only content = content.replace("\r\n", "\n") content = content.replace("\r", "\n") diff --git a/ietf/utils/patch.py b/ietf/utils/patch.py index 0c1952f3f..379f2c760 100644 --- a/ietf/utils/patch.py +++ b/ietf/utils/patch.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2020, All Rights Reserved +# Some parts Copyright The IETF Trust 2020, All Rights Reserved #!/usr/bin/env python """ Patch utility to apply unified diffs diff --git a/ietf/utils/test_utils.py b/ietf/utils/test_utils.py index fc5df7ef6..f6ba32c3f 100644 --- a/ietf/utils/test_utils.py +++ b/ietf/utils/test_utils.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2009-2019, All Rights Reserved +# Copyright The IETF Trust 2009-2020, All Rights Reserved # -*- coding: utf-8 -*- # # Portion Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). @@ -40,7 +40,6 @@ import os import re import email import html5lib -import six import sys from six.moves.urllib.parse import unquote @@ -175,7 +174,7 @@ class TestCase(django.test.TestCase): if subject: mlist = [ m for m in mlist if subject in m["Subject"] ] if text: - assert isinstance(text, six.text_type) + assert isinstance(text, str) mlist = [ m for m in mlist if text in get_payload(m) ] if count and len(mlist) != count: sys.stderr.write("Wrong count in assertMailboxContains(). The complete mailbox contains %s emails:\n\n" % len(mailbox)) diff --git a/ietf/utils/text.py b/ietf/utils/text.py index 611ff7e86..ee01fbbe0 100644 --- a/ietf/utils/text.py +++ b/ietf/utils/text.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2016-2019, All Rights Reserved +# Copyright The IETF Trust 2016-2020, All Rights Reserved # -*- coding: utf-8 -*- @@ -154,7 +154,7 @@ def decode(raw): def text_to_dict(t): "Converts text with RFC2822-formatted header fields into a dictionary-like object." # ensure we're handed a unicode parameter - assert isinstance(t, six.text_type) + assert isinstance(t, str) d = {} # Return {} for malformed input if not len(t.lstrip()) == len(t): diff --git a/requirements.txt b/requirements.txt index c03399a10..b288e3313 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,6 +20,7 @@ django-markup>=1.1 django-password-strength>=1.2.1 django-referrer-policy>=1.0 django-simple-history>=2.3.0 +django-stubs==1.3.0 django-tastypie>=0.13.2 django-webtest>=1.9.7 django-widget-tweaks>=1.3 @@ -37,6 +38,7 @@ jwcrypto>=0.4.0 # for signed notifications #lxml>=3.4.0 # from PyQuery; markdown2>=2.3.8 mock>=2.0.0 +mypy==0.750 # Version requirements determined by django-stubs. mysqlclient>=1.3.13 oauth2client>=4.0.0 # required by google-api-python-client, but not always pulled in pathlib>=1.0 @@ -60,8 +62,7 @@ six>=1.9.0 sqlparse>=0.2.2 tblib>=1.3.0 tqdm>=3.7.0 -Trac>=1.0.10,<1.2 -typing>=3.7.4.1 +#Trac>=1.0.10,<1.2 Unidecode>=0.4.18 #wsgiref>=0.1.2 xml2rfc>=2.35.0 diff --git a/requirements3.txt b/requirements3.txt deleted file mode 100644 index 15e1d796d..000000000 --- a/requirements3.txt +++ /dev/null @@ -1,71 +0,0 @@ -# -*- conf-mode -*- -setuptools>=18.5 # Require this first, to prevent later errors -# -argon2-cffi>=16.1.0 # For the Argon2 password hasher option -beautifulsoup4>=4.5.0 -bibtexparser>=0.6.2,<1.0 # Version 1.0 doesn't work under python 2.7. 1.0.1 doesn't recognize month names or abbreviations. -bleach>=2.0.0,!=3.0.0,!=3.0.1,!=3.0.2 -coverage>=4.0.1,!=4.0.2,<5.0 -#cssselect>=0.6.1 # for PyQuery -decorator>=4.0.4 -defusedxml>=0.4.1 # for TastyPie when ussing xml; not a declared dependency -Django>=1.11,!=1.11.18,<1.12 # 1.11.18 has problems exporting BinaryField from django.db.models -django-bcrypt>=0.9.2 # for the BCrypt password hasher option. Remove when all bcrypt upgraded to argon2 -django-bootstrap3>=8.2.1,<9.0.0 -django-csp>=3.5 -django-cors-headers>=2.4.0 -django-form-utils>=1.0.3 -django-formtools>=1.0 # instead of django.contrib.formtools in 1.8 -django-markup>=1.1 -django-password-strength>=1.2.1 -django-referrer-policy>=1.0 -django-simple-history>=2.3.0 -django-stubs==1.3.0 -django-tastypie>=0.13.2 -django-webtest>=1.9.7 -django-widget-tweaks>=1.3 -docutils>=0.12,!=0.15 -factory-boy>=2.9.0 -google-api-python-client -Faker>=0.8.8,!=0.8.9,!=0.8.10 # from factory-boy # Faker 0.8.9,0.8.10 sometimes return string names instead of unicode. -hashids>=1.1.0 -html2text>=2019.8.11 -html5lib>=1.0.1 -httplib2>=0.10.3 -# jsonfield 3.x and higher requires Django 2.2 or higher -jsonfield>=1.0.3,<3.0 # for SubmissionCheck. This is https://github.com/bradjasper/django-jsonfield/. -jwcrypto>=0.4.0 # for signed notifications -#lxml>=3.4.0 # from PyQuery; -markdown2>=2.3.8 -mock>=2.0.0 -mypy==0.750 # Version requirements determined by django-stubs. -mysqlclient>=1.3.13 -oauth2client>=4.0.0 # required by google-api-python-client, but not always pulled in -pathlib>=1.0 -pathlib2>=2.3.0 -Pillow>=3.0 -#pip==9.0.1 # Earlier pip has issues, 9.0.2 and 9.0.3, 10.0.0b1 leaves dross when down- and up-grading packages -pyang>=1.7.2 -pyflakes>=0.9.2 -pyopenssl>=17.5.0 # Used by urllib3.contrib, which is used by PyQuery but not marked as a dependency -pyquery>=1.2.13,!=1.2.14 # Pyqyery 1.2.14 fails on some selectors or stacked selectors -python-dateutil>=2.2 -python-magic>=0.4.6 -python-memcached>=1.48 # for django.core.cache.backends.memcached -python-mimeparse>=1.6 # from TastyPie -pytz>=2014.7 -#pyzmail>=1.0.3 -requests!=2.12.* -rfc2html>=2.0.1 -selenium>=2.42,<3.8.1 -six>=1.9.0 -sqlparse>=0.2.2 -tblib>=1.3.0 -tqdm>=3.7.0 -#Trac>=1.0.10,<1.2 -Unidecode>=0.4.18 -#wsgiref>=0.1.2 -xml2rfc>=2.9.3,!=2.6.0 -xym>=0.4.4,!=0.4.7,<1.0 -#zxcvbn-python>=4.4.14 # Not needed until we do back-end password entropy validation -