Merge pull request #1074 from tahoe-lafs/3728.scripts-python-3-part-3

Port allmydata.scripts to Python 3, part 3

Fixes ticket:3728
This commit is contained in:
Itamar Turner-Trauring 2021-06-03 09:08:13 -04:00 committed by GitHub
commit 9ed0cd421c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 96 additions and 43 deletions

0
newsfragments/3728.minor Normal file
View File

View File

@ -515,7 +515,7 @@ def list_aliases(options):
def list_(options): def list_(options):
from allmydata.scripts import tahoe_ls from allmydata.scripts import tahoe_ls
rc = tahoe_ls.list(options) rc = tahoe_ls.ls(options)
return rc return rc
def get(options): def get(options):

View File

@ -1,6 +1,14 @@
"""
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from __future__ import print_function
from past.builtins import unicode 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.path import os.path
from urllib.parse import quote as url_quote from urllib.parse import quote as url_quote
@ -162,7 +170,7 @@ class LocalDirectoryTarget(object):
self.children[n] = LocalFileTarget(pn) self.children[n] = LocalFileTarget(pn)
def get_child_target(self, name): def get_child_target(self, name):
precondition(isinstance(name, unicode), name) precondition(isinstance(name, str), name)
precondition(len(name), name) # don't want "" precondition(len(name), name) # don't want ""
if self.children is None: if self.children is None:
self.populate(recurse=False) self.populate(recurse=False)
@ -175,7 +183,7 @@ class LocalDirectoryTarget(object):
return child return child
def put_file(self, name, inf): def put_file(self, name, inf):
precondition(isinstance(name, unicode), name) precondition(isinstance(name, str), name)
pathname = os.path.join(self.pathname, name) pathname = os.path.join(self.pathname, name)
fileutil.put_file(pathname, inf) fileutil.put_file(pathname, inf)
@ -258,7 +266,7 @@ class TahoeDirectorySource(object):
nodetype, d = parsed nodetype, d = parsed
assert nodetype == "dirnode" assert nodetype == "dirnode"
self.mutable = d.get("mutable", False) # older nodes don't provide it self.mutable = d.get("mutable", False) # older nodes don't provide it
self.children_d = dict( [(unicode(name),value) self.children_d = dict( [(str(name),value)
for (name,value) for (name,value)
in d["children"].items()] ) in d["children"].items()] )
self.children = None self.children = None
@ -268,7 +276,7 @@ class TahoeDirectorySource(object):
self.writecap = to_bytes(d.get("rw_uri")) self.writecap = to_bytes(d.get("rw_uri"))
self.readcap = to_bytes(d.get("ro_uri")) self.readcap = to_bytes(d.get("ro_uri"))
self.mutable = d.get("mutable", False) # older nodes don't provide it self.mutable = d.get("mutable", False) # older nodes don't provide it
self.children_d = dict( [(unicode(name),value) self.children_d = dict( [(str(name),value)
for (name,value) for (name,value)
in d["children"].items()] ) in d["children"].items()] )
self.children = None self.children = None
@ -338,7 +346,7 @@ class TahoeDirectoryTarget(object):
self.writecap = to_bytes(d.get("rw_uri")) self.writecap = to_bytes(d.get("rw_uri"))
self.readcap = to_bytes(d.get("ro_uri")) self.readcap = to_bytes(d.get("ro_uri"))
self.mutable = d.get("mutable", False) # older nodes don't provide it self.mutable = d.get("mutable", False) # older nodes don't provide it
self.children_d = dict( [(unicode(name),value) self.children_d = dict( [(str(name),value)
for (name,value) for (name,value)
in d["children"].items()] ) in d["children"].items()] )
self.children = None self.children = None
@ -355,7 +363,7 @@ class TahoeDirectoryTarget(object):
nodetype, d = parsed nodetype, d = parsed
assert nodetype == "dirnode" assert nodetype == "dirnode"
self.mutable = d.get("mutable", False) # older nodes don't provide it self.mutable = d.get("mutable", False) # older nodes don't provide it
self.children_d = dict( [(unicode(name),value) self.children_d = dict( [(str(name),value)
for (name,value) for (name,value)
in d["children"].items()] ) in d["children"].items()] )
self.children = None self.children = None
@ -411,7 +419,7 @@ class TahoeDirectoryTarget(object):
def get_child_target(self, name): def get_child_target(self, name):
# return a new target for a named subdirectory of this dir # return a new target for a named subdirectory of this dir
precondition(isinstance(name, unicode), name) precondition(isinstance(name, str), name)
if self.children is None: if self.children is None:
self.populate(recurse=False) self.populate(recurse=False)
if name in self.children: if name in self.children:
@ -424,7 +432,7 @@ class TahoeDirectoryTarget(object):
return child return child
def put_file(self, name, inf): def put_file(self, name, inf):
precondition(isinstance(name, unicode), name) precondition(isinstance(name, str), name)
url = self.nodeurl + "uri" url = self.nodeurl + "uri"
if not seekable(inf): if not seekable(inf):
inf = inf.read() inf = inf.read()
@ -444,7 +452,7 @@ class TahoeDirectoryTarget(object):
self.new_children[name] = filecap self.new_children[name] = filecap
def put_uri(self, name, filecap): def put_uri(self, name, filecap):
precondition(isinstance(name, unicode), name) precondition(isinstance(name, str), name)
self.new_children[name] = filecap self.new_children[name] = filecap
def set_children(self): def set_children(self):
@ -453,7 +461,7 @@ class TahoeDirectoryTarget(object):
url = (self.nodeurl + "uri/" + url_quote(self.writecap) url = (self.nodeurl + "uri/" + url_quote(self.writecap)
+ "?t=set_children") + "?t=set_children")
set_data = {} set_data = {}
for (name, filecap) in self.new_children.items(): for (name, filecap) in list(self.new_children.items()):
# it just so happens that ?t=set_children will accept both file # it just so happens that ?t=set_children will accept both file
# read-caps and write-caps as ['rw_uri'], and will handle either # read-caps and write-caps as ['rw_uri'], and will handle either
# correctly. So don't bother trying to figure out whether the one # correctly. So don't bother trying to figure out whether the one
@ -597,7 +605,7 @@ class Copier(object):
# and get_source_info. # and get_source_info.
def get_target_info(self, destination_spec): def get_target_info(self, destination_spec):
precondition(isinstance(destination_spec, unicode), destination_spec) precondition(isinstance(destination_spec, str), destination_spec)
rootcap, path_utf8 = get_alias(self.aliases, destination_spec, None) rootcap, path_utf8 = get_alias(self.aliases, destination_spec, None)
path = path_utf8.decode("utf-8") path = path_utf8.decode("utf-8")
if rootcap == DefaultAliasMarker: if rootcap == DefaultAliasMarker:
@ -644,7 +652,7 @@ class Copier(object):
""" """
This turns an argv string into a (Local|Tahoe)(File|Directory)Source. This turns an argv string into a (Local|Tahoe)(File|Directory)Source.
""" """
precondition(isinstance(source_spec, unicode), source_spec) precondition(isinstance(source_spec, str), source_spec)
rootcap, path_utf8 = get_alias(self.aliases, source_spec, None) rootcap, path_utf8 = get_alias(self.aliases, source_spec, None)
path = path_utf8.decode("utf-8") path = path_utf8.decode("utf-8")
# any trailing slash is removed in abspath_expanduser_unicode(), so # any trailing slash is removed in abspath_expanduser_unicode(), so
@ -752,7 +760,7 @@ class Copier(object):
# target name collisions are an error # target name collisions are an error
collisions = [] collisions = []
for target, sources in targetmap.items(): for target, sources in list(targetmap.items()):
target_names = {} target_names = {}
for source in sources: for source in sources:
name = source.basename() name = source.basename()
@ -821,7 +829,7 @@ class Copier(object):
def assign_targets(self, targetmap, source, target): def assign_targets(self, targetmap, source, target):
# copy everything in the source into the target # copy everything in the source into the target
precondition(isinstance(source, DirectorySources), source) precondition(isinstance(source, DirectorySources), source)
for name, child in source.children.items(): for name, child in list(source.children.items()):
if isinstance(child, DirectorySources): if isinstance(child, DirectorySources):
# we will need a target directory for this one # we will need a target directory for this one
subtarget = target.get_child_target(name) subtarget = target.get_child_target(name)
@ -837,7 +845,7 @@ class Copier(object):
files_copied = 0 files_copied = 0
targets_finished = 0 targets_finished = 0
for target, sources in targetmap.items(): for target, sources in list(targetmap.items()):
_assert(isinstance(target, DirectoryTargets), target) _assert(isinstance(target, DirectoryTargets), target)
for source in sources: for source in sources:
_assert(isinstance(source, FileSources), source) _assert(isinstance(source, FileSources), source)
@ -857,7 +865,7 @@ class Copier(object):
def copy_file_into_dir(self, source, name, target): def copy_file_into_dir(self, source, name, target):
precondition(isinstance(source, FileSources), source) precondition(isinstance(source, FileSources), source)
precondition(isinstance(target, DirectoryTargets), target) precondition(isinstance(target, DirectoryTargets), target)
precondition(isinstance(name, unicode), name) precondition(isinstance(name, str), name)
if self.need_to_copy_bytes(source, target): if self.need_to_copy_bytes(source, target):
# if the target is a local directory, this will just write the # if the target is a local directory, this will just write the
# bytes to disk. If it is a tahoe directory, it will upload the # bytes to disk. If it is a tahoe directory, it will upload the

View File

@ -1,6 +1,14 @@
"""
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from __future__ import print_function
from future.utils import PY3 from future.utils import PY2, PY3
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
from urllib.parse import quote as url_quote from urllib.parse import quote as url_quote
from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \ from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \

View File

@ -1,5 +1,15 @@
"""
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from __future__ import print_function
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
try: try:
from allmydata.scripts.types_ import SubCommands from allmydata.scripts.types_ import SubCommands
except ImportError: except ImportError:

View File

@ -1,7 +1,16 @@
"""
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from __future__ import print_function
from past.builtins import unicode from future.utils import PY2
from six import ensure_text, ensure_str 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
from six import ensure_text
import time import time
from urllib.parse import quote as url_quote from urllib.parse import quote as url_quote
@ -11,7 +20,7 @@ from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
from allmydata.scripts.common_http import do_http, format_http_error from allmydata.scripts.common_http import do_http, format_http_error
from allmydata.util.encodingutil import unicode_to_output, quote_output, is_printable_ascii, to_bytes from allmydata.util.encodingutil import unicode_to_output, quote_output, is_printable_ascii, to_bytes
def list(options): def ls(options):
nodeurl = options['node-url'] nodeurl = options['node-url']
aliases = options.aliases aliases = options.aliases
where = options.where where = options.where
@ -28,7 +37,7 @@ def list(options):
e.display(stderr) e.display(stderr)
return 1 return 1
path = unicode(path, "utf-8") path = str(path, "utf-8")
url = nodeurl + "uri/%s" % url_quote(rootcap) url = nodeurl + "uri/%s" % url_quote(rootcap)
if path: if path:
# move where.endswith check here? # move where.endswith check here?
@ -50,7 +59,7 @@ def list(options):
if options['json']: if options['json']:
# The webapi server should always output printable ASCII. # The webapi server should always output printable ASCII.
if is_printable_ascii(data): if is_printable_ascii(data):
data = unicode(data, "ascii") data = str(data, "ascii")
print(data, file=stdout) print(data, file=stdout)
return 0 return 0
else: else:
@ -87,7 +96,7 @@ def list(options):
for name in childnames: for name in childnames:
child = children[name] child = children[name]
name = unicode(name) name = str(name)
childtype = child[0] childtype = child[0]
# See webapi.txt for a discussion of the meanings of unix local # See webapi.txt for a discussion of the meanings of unix local
@ -147,23 +156,18 @@ def list(options):
if not options["classify"]: if not options["classify"]:
classify = "" classify = ""
encoding_error = False line.append(name + classify)
try:
line.append(unicode_to_output(name) + classify)
except UnicodeEncodeError:
encoding_error = True
line.append(quote_output(name) + classify)
if options["uri"]: if options["uri"]:
line.append(ensure_str(uri)) line.append(ensure_text(uri))
if options["readonly-uri"]: if options["readonly-uri"]:
line.append(quote_output(ensure_str(ro_uri) or "-", quotemarks=False)) line.append(quote_output(ensure_text(ro_uri) or "-", quotemarks=False))
rows.append((encoding_error, line)) rows.append(line)
max_widths = [] max_widths = []
left_justifys = [] left_justifys = []
for (encoding_error, row) in rows: for row in rows:
for i,cell in enumerate(row): for i,cell in enumerate(row):
while len(max_widths) <= i: while len(max_widths) <= i:
max_widths.append(0) max_widths.append(0)
@ -185,12 +189,19 @@ def list(options):
fmt = " ".join(fmt_pieces) fmt = " ".join(fmt_pieces)
rc = 0 rc = 0
for (encoding_error, row) in rows: for row in rows:
row = (fmt % tuple(row)).rstrip()
encoding_error = False
try:
row = unicode_to_output(row)
except UnicodeEncodeError:
encoding_error = True
row = quote_output(row)
if encoding_error: if encoding_error:
print((fmt % tuple(row)).rstrip(), file=stderr) print(row, file=stderr)
rc = 1 rc = 1
else: else:
print((fmt % tuple(row)).rstrip(), file=stdout) print(row, file=stdout)
if rc == 1: if rc == 1:
print("\nThis listing included files whose names could not be converted to the terminal" \ print("\nThis listing included files whose names could not be converted to the terminal" \

View File

@ -1,7 +1,16 @@
"""
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from __future__ import print_function
from future.utils import PY3 from future.utils import PY2, PY3
from past.builtins import unicode 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
from six import ensure_str
from urllib.parse import quote as url_quote from urllib.parse import quote as url_quote
import json import json
@ -37,7 +46,7 @@ class ManifestStreamer(LineOnlyReceiver, object):
except UnknownAliasError as e: except UnknownAliasError as e:
e.display(stderr) e.display(stderr)
return 1 return 1
path = unicode(path, "utf-8") path = str(path, "utf-8")
if path == '/': if path == '/':
path = '' path = ''
url = nodeurl + "uri/%s" % url_quote(rootcap) url = nodeurl + "uri/%s" % url_quote(rootcap)
@ -96,8 +105,10 @@ class ManifestStreamer(LineOnlyReceiver, object):
if vc: if vc:
print(quote_output(vc, quotemarks=False), file=stdout) print(quote_output(vc, quotemarks=False), file=stdout)
else: else:
print("%s %s" % (quote_output(d["cap"], quotemarks=False), # ensure_str() only necessary for Python 2.
quote_path(d["path"], quotemarks=False)), file=stdout) print(ensure_str("%s %s") % (
quote_output(d["cap"], quotemarks=False),
quote_path(d["path"], quotemarks=False)), file=stdout)
def manifest(options): def manifest(options):
return ManifestStreamer().run(options) return ManifestStreamer().run(options)

View File

@ -105,6 +105,11 @@ PORTED_MODULES = [
"allmydata.scripts.tahoe_add_alias", "allmydata.scripts.tahoe_add_alias",
"allmydata.scripts.tahoe_backup", "allmydata.scripts.tahoe_backup",
"allmydata.scripts.tahoe_check", "allmydata.scripts.tahoe_check",
"allmydata.scripts.tahoe_cp",
"allmydata.scripts.tahoe_get",
"allmydata.scripts.tahoe_invite",
"allmydata.scripts.tahoe_ls",
"allmydata.scripts.tahoe_manifest",
"allmydata.scripts.types_", "allmydata.scripts.types_",
"allmydata.stats", "allmydata.stats",
"allmydata.storage_client", "allmydata.storage_client",