diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cae14c013..e14268f23 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,10 @@ on: - "master" pull_request: +env: + # Tell Hypothesis which configuration we want it to use. + TAHOE_LAFS_HYPOTHESIS_PROFILE: "ci" + jobs: coverage: diff --git a/newsfragments/3615.minor b/newsfragments/3615.minor new file mode 100644 index 000000000..e69de29bb diff --git a/src/allmydata/util/_python3.py b/src/allmydata/util/_python3.py index 51496537a..38598fe9b 100644 --- a/src/allmydata/util/_python3.py +++ b/src/allmydata/util/_python3.py @@ -117,6 +117,10 @@ PORTED_MODULES = [ "allmydata.util.statistics", "allmydata.util.time_format", "allmydata.web.common", + "allmydata.web.check_results", + "allmydata.web.filenode", + "allmydata.web.info", + "allmydata.web.introweb", "allmydata.web.logs", "allmydata.webish", ] diff --git a/src/allmydata/web/check_results.py b/src/allmydata/web/check_results.py index 1bf726fb2..6c8810f2b 100644 --- a/src/allmydata/web/check_results.py +++ b/src/allmydata/web/check_results.py @@ -1,4 +1,14 @@ -from future.builtins import str +""" +Ported to Python 3. +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from future.utils import PY2 +if PY2: + from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 import time diff --git a/src/allmydata/web/filenode.py b/src/allmydata/web/filenode.py index 9929a6236..dd793888e 100644 --- a/src/allmydata/web/filenode.py +++ b/src/allmydata/web/filenode.py @@ -1,4 +1,18 @@ -from past.builtins import unicode, long +""" +Ported to Python 3. +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from future.utils import PY2 +if PY2: + from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, max, min # noqa: F401 + # Use native unicode() as str() to prevent leaking futurebytes in ways that + # break string formattin. + from past.builtins import unicode as str +from past.builtins import long from twisted.web import http, static from twisted.internet import defer @@ -130,7 +144,7 @@ class PlaceHolderNodeHandler(Resource, ReplaceMeMixin): if t == b"uri": return self.replace_me_with_a_childcap(req, self.client, replace) - raise WebError("PUT to a file: bad t=%s" % unicode(t, "utf-8")) + raise WebError("PUT to a file: bad t=%s" % str(t, "utf-8")) @render_exception def render_POST(self, req): @@ -147,7 +161,7 @@ class PlaceHolderNodeHandler(Resource, ReplaceMeMixin): # t=mkdir is handled in DirectoryNodeHandler._POST_mkdir, so # there are no other t= values left to be handled by the # placeholder. - raise WebError("POST to a file: bad t=%s" % unicode(t, "utf-8")) + raise WebError("POST to a file: bad t=%s" % str(t, "utf-8")) return handle_when_done(req, d) @@ -180,7 +194,7 @@ class FileNodeHandler(Resource, ReplaceMeMixin, object): @render_exception def render_GET(self, req): - t = unicode(get_arg(req, b"t", b"").strip(), "ascii") + t = str(get_arg(req, b"t", b"").strip(), "ascii") # t=info contains variable ophandles, so is not allowed an ETag. FIXED_OUTPUT_TYPES = ["", "json", "uri", "readonly-uri"] @@ -287,7 +301,7 @@ class FileNodeHandler(Resource, ReplaceMeMixin, object): assert self.parentnode and self.name return self.replace_me_with_a_childcap(req, self.client, replace) - raise WebError("PUT to a file: bad t=%s" % unicode(t, "utf-8")) + raise WebError("PUT to a file: bad t=%s" % str(t, "utf-8")) @render_exception def render_POST(self, req): @@ -309,7 +323,7 @@ class FileNodeHandler(Resource, ReplaceMeMixin, object): assert self.parentnode and self.name d = self.replace_me_with_a_formpost(req, self.client, replace) else: - raise WebError("POST to file: bad t=%s" % unicode(t, "ascii")) + raise WebError("POST to file: bad t=%s" % str(t, "ascii")) return handle_when_done(req, d) @@ -374,7 +388,7 @@ class FileDownloader(Resource, object): self.filenode = filenode self.filename = filename - def parse_range_header(self, range): + def parse_range_header(self, range_header): # Parse a byte ranges according to RFC 2616 "14.35.1 Byte # Ranges". Returns None if the range doesn't make sense so it # can be ignored (per the spec). When successful, returns a @@ -385,7 +399,7 @@ class FileDownloader(Resource, object): try: # byte-ranges-specifier - units, rangeset = range.split('=', 1) + units, rangeset = range_header.split('=', 1) if units != 'bytes': return None # nothing else supported diff --git a/src/allmydata/web/info.py b/src/allmydata/web/info.py index 21ac0fd7e..2d45f9994 100644 --- a/src/allmydata/web/info.py +++ b/src/allmydata/web/info.py @@ -1,4 +1,14 @@ -from past.builtins import unicode +""" +Ported to Python 3. +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from future.utils import PY2 +if PY2: + from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 import os from urllib.parse import quote as urlquote @@ -47,7 +57,7 @@ class MoreInfoElement(Element): def abbrev(self, storage_index_or_none): if storage_index_or_none: - return unicode(base32.b2a(storage_index_or_none)[:6], "ascii") + return str(base32.b2a(storage_index_or_none)[:6], "ascii") return "LIT file" def get_type(self): diff --git a/src/allmydata/web/introweb.py b/src/allmydata/web/introweb.py index 280d6cc26..621a15a5c 100644 --- a/src/allmydata/web/introweb.py +++ b/src/allmydata/web/introweb.py @@ -1,3 +1,14 @@ +""" +Ported to Python 3. +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from future.utils import PY2 +if PY2: + from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 import time, os from pkg_resources import resource_filename