Remove py2-only code paths

Change-Id: Ic66b9ae89837afe31929ce07cc625dfc28314ea3
This commit is contained in:
Tim Burke 2022-08-18 11:28:08 -07:00
parent 94d3a5dee8
commit 128124cdd8
196 changed files with 1275 additions and 2757 deletions

View File

@ -80,11 +80,7 @@ presented below::
from swift.common.request_helpers import get_sys_meta_prefix from swift.common.request_helpers import get_sys_meta_prefix
from swift.proxy.controllers.base import get_container_info from swift.proxy.controllers.base import get_container_info
from eventlet import Timeout from eventlet import Timeout
import six from eventlet.green.urllib import urllib_request
if six.PY3:
from eventlet.green.urllib import request as urllib2
else:
from eventlet.green import urllib2
# x-container-sysmeta-webhook # x-container-sysmeta-webhook
SYSMETA_WEBHOOK = get_sys_meta_prefix('container') + 'webhook' SYSMETA_WEBHOOK = get_sys_meta_prefix('container') + 'webhook'
@ -119,10 +115,10 @@ presented below::
webhook = container_info['sysmeta'].get('webhook') webhook = container_info['sysmeta'].get('webhook')
if webhook: if webhook:
# create a POST request with obj name as body # create a POST request with obj name as body
webhook_req = urllib2.Request(webhook, data=obj) webhook_req = urllib_request.Request(webhook, data=obj)
with Timeout(20): with Timeout(20):
try: try:
urllib2.urlopen(webhook_req).read() urllib_request.urlopen(webhook_req).read()
except (Exception, Timeout): except (Exception, Timeout):
self.logger.exception( self.logger.exception(
'failed POST to webhook %s' % webhook) 'failed POST to webhook %s' % webhook)

View File

@ -65,7 +65,6 @@ PyYAML==3.12
requests==2.14.2 requests==2.14.2
requests-mock==1.2.0 requests-mock==1.2.0
rfc3986==1.1.0 rfc3986==1.1.0
six==1.10.0
smmap2==2.0.3 smmap2==2.0.3
snowballstemmer==1.2.1 snowballstemmer==1.2.1
stestr==2.0.0 stestr==2.0.0

View File

@ -192,7 +192,6 @@ s3transfer===0.10.4;python_version>='3.8'
s3transfer===0.8.2;python_version=='3.7' s3transfer===0.8.2;python_version=='3.7'
s3transfer===0.5.2;python_version=='3.6' s3transfer===0.5.2;python_version=='3.6'
setuptools===75.3.0;python_version>='3.12' setuptools===75.3.0;python_version>='3.12'
six===1.16.0
smmap===5.0.1;python_version>='3.7' smmap===5.0.1;python_version>='3.7'
smmap===5.0.0;python_version=='3.6' smmap===5.0.0;python_version=='3.6'
stestr===4.1.0 stestr===4.1.0

View File

@ -7,7 +7,6 @@ greenlet>=0.3.3
PasteDeploy>=2.0.0 PasteDeploy>=2.0.0
lxml>=4.2.3 lxml>=4.2.3
requests>=2.14.2 # Apache-2.0 requests>=2.14.2 # Apache-2.0
six>=1.10.0
xattr>=0.7.2;sys_platform!='win32' # MIT xattr>=0.7.2;sys_platform!='win32' # MIT
PyECLib>=1.3.1,!=1.6.2,!=1.6.3 # BSD PyECLib>=1.3.1,!=1.6.2,!=1.6.3 # BSD
cryptography>=2.0.2 # BSD/Apache-2.0 cryptography>=2.0.2 # BSD/Apache-2.0

View File

@ -19,10 +19,8 @@ Pluggable Back-end for Account Server
import sqlite3 import sqlite3
import six
from swift.common.utils import Timestamp, RESERVED_BYTE from swift.common.utils import Timestamp, RESERVED_BYTE
from swift.common.db import DatabaseBroker, utf8encode, zero_like from swift.common.db import DatabaseBroker, zero_like
DATADIR = 'accounts' DATADIR = 'accounts'
@ -372,9 +370,6 @@ class AccountBroker(DatabaseBroker):
put_timestamp, 0) put_timestamp, 0)
""" """
delim_force_gte = False delim_force_gte = False
if six.PY2:
(marker, end_marker, prefix, delimiter) = utf8encode(
marker, end_marker, prefix, delimiter)
if reverse: if reverse:
# Reverse the markers if we are reversing the listing. # Reverse the markers if we are reversing the listing.
marker, end_marker = end_marker, marker marker, end_marker = end_marker, marker

View File

@ -22,7 +22,6 @@ from time import time
import itertools import itertools
from eventlet import GreenPool, sleep, Timeout from eventlet import GreenPool, sleep, Timeout
import six
import swift.common.db import swift.common.db
from swift.account.backend import AccountBroker, DATADIR from swift.account.backend import AccountBroker, DATADIR
@ -267,12 +266,9 @@ class AccountReaper(Daemon):
while containers: while containers:
try: try:
for (container, _junk, _junk, _junk, _junk) in containers: for (container, _junk, _junk, _junk, _junk) in containers:
if six.PY3:
container_ = container.encode('utf-8')
else:
container_ = container
this_shard = ( this_shard = (
int(md5(container_, usedforsecurity=False) int(md5(container.encode('utf-8'),
usedforsecurity=False)
.hexdigest(), 16) % len(nodes)) .hexdigest(), 16) % len(nodes))
if container_shard not in (this_shard, None): if container_shard not in (this_shard, None):
continue continue

View File

@ -15,8 +15,6 @@
import json import json
import six
from swift.common import constraints from swift.common import constraints
from swift.common.middleware import listing_formats from swift.common.middleware import listing_formats
from swift.common.swob import HTTPOk, HTTPNoContent, str_to_wsgi from swift.common.swob import HTTPOk, HTTPNoContent, str_to_wsgi
@ -86,12 +84,11 @@ def account_listing_response(account, req, response_content_type, broker=None,
data = [] data = []
for (name, object_count, bytes_used, put_timestamp, is_subdir) \ for (name, object_count, bytes_used, put_timestamp, is_subdir) \
in account_list: in account_list:
name_ = name.decode('utf8') if six.PY2 else name
if is_subdir: if is_subdir:
data.append({'subdir': name_}) data.append({'subdir': name})
else: else:
data.append( data.append(
{'name': name_, 'count': object_count, 'bytes': bytes_used, {'name': name, 'count': object_count, 'bytes': bytes_used,
'last_modified': Timestamp(put_timestamp).isoformat}) 'last_modified': Timestamp(put_timestamp).isoformat})
if response_content_type.endswith('/xml'): if response_content_type.endswith('/xml'):
account_list = listing_formats.account_to_xml(data, account) account_list = listing_formats.account_to_xml(data, account)

View File

@ -23,7 +23,7 @@ from itertools import chain
import json import json
from eventlet.greenpool import GreenPool from eventlet.greenpool import GreenPool
from eventlet.event import Event from eventlet.event import Event
from six.moves.urllib.parse import quote from urllib.parse import quote
from swift.common.ring import Ring from swift.common.ring import Ring
from swift.common.utils import split_path from swift.common.utils import split_path

View File

@ -28,7 +28,6 @@ import argparse
import io import io
import itertools import itertools
import json import json
import six
import time import time
from swift.common.internal_client import InternalClient from swift.common.internal_client import InternalClient
@ -50,17 +49,11 @@ def make_delete_jobs(account, container, objects, timestamp):
:returns: list of dicts appropriate for an UPDATE request to an :returns: list of dicts appropriate for an UPDATE request to an
expiring-object queue expiring-object queue
''' '''
if six.PY2:
if isinstance(account, str):
account = account.decode('utf8')
if isinstance(container, str):
container = container.decode('utf8')
return [ return [
{ {
'name': build_task_obj( 'name': build_task_obj(
timestamp, account, container, timestamp, account, container,
obj.decode('utf8') if six.PY2 and isinstance(obj, str) obj, high_precision=True),
else obj, high_precision=True),
'deleted': 0, 'deleted': 0,
'created_at': timestamp.internal, 'created_at': timestamp.internal,
'etag': MD5_OF_EMPTY_STRING, 'etag': MD5_OF_EMPTY_STRING,

View File

@ -23,9 +23,7 @@ from time import time
from eventlet import GreenPool, patcher, sleep from eventlet import GreenPool, patcher, sleep
from eventlet.pools import Pool from eventlet.pools import Pool
import six from configparser import ConfigParser
from six.moves import range
from six.moves.configparser import ConfigParser
from swift.common.internal_client import SimpleClient from swift.common.internal_client import SimpleClient
from swift.common.ring import Ring from swift.common.ring import Ring
@ -53,7 +51,7 @@ def put_object(connpool, container, obj, report):
global retries_done global retries_done
try: try:
with connpool.item() as conn: with connpool.item() as conn:
data = io.BytesIO(obj if six.PY2 else obj.encode('utf8')) data = io.BytesIO(obj.encode('utf8'))
conn.put_object(container, obj, data, conn.put_object(container, obj, data,
headers={'x-object-meta-dispersion': obj}) headers={'x-object-meta-dispersion': obj})
retries_done += conn.attempts - 1 retries_done += conn.attempts - 1

View File

@ -17,7 +17,7 @@
from __future__ import print_function from __future__ import print_function
import json import json
from collections import defaultdict from collections import defaultdict
from six.moves.configparser import ConfigParser from configparser import ConfigParser
from optparse import OptionParser from optparse import OptionParser
from sys import exit, stdout, stderr from sys import exit, stdout, stderr
from time import time from time import time

View File

@ -24,8 +24,7 @@ import subprocess
import sys import sys
import six from configparser import ConfigParser
from six.moves.configparser import ConfigParser
from swift.common.utils import backward, get_logger, dump_recon_cache, \ from swift.common.utils import backward, get_logger, dump_recon_cache, \
config_true_value config_true_value
@ -128,7 +127,6 @@ def get_errors(error_re, log_file_pattern, minutes, logger,
print("Unable to open " + path) print("Unable to open " + path)
sys.exit(1) sys.exit(1)
for line in backward(f): for line in backward(f):
if not six.PY2:
line = line.decode(log_file_encoding, 'surrogateescape') line = line.decode(log_file_encoding, 'surrogateescape')
if '[ 0.000000]' in line \ if '[ 0.000000]' in line \
or 'KERNEL supported cpus:' in line \ or 'KERNEL supported cpus:' in line \

View File

@ -17,7 +17,6 @@ Script for generating a form signature for use with FormPost middleware.
""" """
from __future__ import print_function from __future__ import print_function
import hmac import hmac
import six
from hashlib import sha1 from hashlib import sha1
from os.path import basename from os.path import basename
from time import time from time import time
@ -95,10 +94,8 @@ def main(argv):
return 1 return 1
data = '%s\n%s\n%s\n%s\n%s' % (path, redirect, max_file_size, data = '%s\n%s\n%s\n%s\n%s' % (path, redirect, max_file_size,
max_file_count, expires) max_file_count, expires)
if six.PY3: data = data.encode('utf8')
data = data if isinstance(data, six.binary_type) else \ key = key if isinstance(key, bytes) else \
data.encode('utf8')
key = key if isinstance(key, six.binary_type) else \
key.encode('utf8') key.encode('utf8')
sig = hmac.new(key, data, sig = hmac.new(key, data,
sha1).hexdigest() sha1).hexdigest()

View File

@ -21,8 +21,7 @@ import sqlite3
import sys import sys
from collections import defaultdict from collections import defaultdict
import six import urllib
from six.moves import urllib
from swift.common.exceptions import LockTimeout from swift.common.exceptions import LockTimeout
from swift.common.utils import hash_path, storage_directory, \ from swift.common.utils import hash_path, storage_directory, \
@ -722,7 +721,6 @@ def print_item_locations(ring, ring_name=None, account=None, container=None,
def obj_main(): def obj_main():
if not six.PY2:
# Make stdout able to write escaped bytes # Make stdout able to write escaped bytes
sys.stdout = codecs.getwriter("utf-8")( sys.stdout = codecs.getwriter("utf-8")(
sys.stdout.detach(), errors='surrogateescape') sys.stdout.detach(), errors='surrogateescape')

View File

@ -163,9 +163,6 @@ import sys
import time import time
from contextlib import contextmanager from contextlib import contextmanager
from six.moves import input
from swift.common.utils import Timestamp, get_logger, ShardRange, readconf, \ from swift.common.utils import Timestamp, get_logger, ShardRange, readconf, \
ShardRangeList, non_negative_int, config_positive_int_value ShardRangeList, non_negative_int, config_positive_int_value
from swift.container.backend import ContainerBroker, UNSHARDED from swift.container.backend import ContainerBroker, UNSHARDED

View File

@ -18,8 +18,7 @@
from __future__ import print_function from __future__ import print_function
from eventlet.green import socket from eventlet.green import socket
from six import string_types from urllib.parse import urlparse
from six.moves.urllib.parse import urlparse
from swift.common.utils import ( from swift.common.utils import (
SWIFT_CONF_FILE, md5_hash_for_file, set_swift_dir) SWIFT_CONF_FILE, md5_hash_for_file, set_swift_dir)
@ -30,13 +29,9 @@ import json
import optparse import optparse
import time import time
import sys import sys
import six
import os import os
if six.PY3: from eventlet.green.urllib import request as urllib_request
from eventlet.green.urllib import request as urllib2
else:
from eventlet.green import urllib2
def seconds2timeunit(seconds): def seconds2timeunit(seconds):
@ -86,19 +81,19 @@ class Scout(object):
""" """
url = base_url + recon_type url = base_url + recon_type
try: try:
body = urllib2.urlopen(url, timeout=self.timeout).read() body = urllib_request.urlopen(url, timeout=self.timeout).read()
if six.PY3 and isinstance(body, six.binary_type): if isinstance(body, bytes):
body = body.decode('utf8') body = body.decode('utf8')
content = json.loads(body) content = json.loads(body)
if self.verbose: if self.verbose:
print("-> %s: %s" % (url, content)) print("-> %s: %s" % (url, content))
status = 200 status = 200
except urllib2.HTTPError as err: except urllib_request.HTTPError as err:
if not self.suppress_errors or self.verbose: if not self.suppress_errors or self.verbose:
print("-> %s: %s" % (url, err)) print("-> %s: %s" % (url, err))
content = err content = err
status = err.code status = err.code
except (urllib2.URLError, socket.timeout) as err: except (urllib_request.URLError, socket.timeout) as err:
if not self.suppress_errors or self.verbose: if not self.suppress_errors or self.verbose:
print("-> %s: %s" % (url, err)) print("-> %s: %s" % (url, err))
content = err content = err
@ -128,19 +123,19 @@ class Scout(object):
""" """
try: try:
url = "http://%s:%s/" % (host[0], host[1]) url = "http://%s:%s/" % (host[0], host[1])
req = urllib2.Request(url) req = urllib_request.Request(url)
req.get_method = lambda: 'OPTIONS' req.get_method = lambda: 'OPTIONS'
conn = urllib2.urlopen(req) conn = urllib_request.urlopen(req)
header = conn.info().get('Server') header = conn.info().get('Server')
server_header = header.split('/') server_header = header.split('/')
content = server_header[0] content = server_header[0]
status = 200 status = 200
except urllib2.HTTPError as err: except urllib_request.HTTPError as err:
if not self.suppress_errors or self.verbose: if not self.suppress_errors or self.verbose:
print("-> %s: %s" % (url, err)) print("-> %s: %s" % (url, err))
content = err content = err
status = err.code status = err.code
except (urllib2.URLError, socket.timeout) as err: except (urllib_request.URLError, socket.timeout) as err:
if not self.suppress_errors or self.verbose: if not self.suppress_errors or self.verbose:
print("-> %s: %s" % (url, err)) print("-> %s: %s" % (url, err))
content = err content = err
@ -1074,7 +1069,7 @@ class SwiftRecon(object):
ring_names = [p.ring_name for p in POLICIES if ( ring_names = [p.ring_name for p in POLICIES if (
p.name == policy or not policy or ( p.name == policy or not policy or (
policy.isdigit() and int(policy) == int(p) or policy.isdigit() and int(policy) == int(p) or
(isinstance(policy, string_types) (isinstance(policy, str)
and policy in p.aliases)))] and policy in p.aliases)))]
else: else:
ring_names = [self.server_type] ring_names = [self.server_type]

View File

@ -31,9 +31,6 @@ from datetime import timedelta
import optparse import optparse
import math import math
from six.moves import zip as izip
from six.moves import input
from swift.common import exceptions from swift.common import exceptions
from swift.common.ring import RingBuilder, Ring, RingData from swift.common.ring import RingBuilder, Ring, RingData
from swift.common.ring.builder import MAX_BALANCE from swift.common.ring.builder import MAX_BALANCE
@ -156,7 +153,7 @@ def _parse_add_values(argvish):
print(Commands.add.__doc__.strip()) print(Commands.add.__doc__.strip())
exit(EXIT_ERROR) exit(EXIT_ERROR)
devs_and_weights = izip(islice(args, 0, len(args), 2), devs_and_weights = zip(islice(args, 0, len(args), 2),
islice(args, 1, len(args), 2)) islice(args, 1, len(args), 2))
for devstr, weightstr in devs_and_weights: for devstr, weightstr in devs_and_weights:
@ -257,7 +254,7 @@ def _parse_set_weight_values(argvish):
print(Commands.set_weight.__doc__.strip()) print(Commands.set_weight.__doc__.strip())
exit(EXIT_ERROR) exit(EXIT_ERROR)
devs_and_weights = izip(islice(argvish, 0, len(argvish), 2), devs_and_weights = zip(islice(argvish, 0, len(argvish), 2),
islice(argvish, 1, len(argvish), 2)) islice(argvish, 1, len(argvish), 2))
for devstr, weightstr in devs_and_weights: for devstr, weightstr in devs_and_weights:
devs = (builder.search_devs( devs = (builder.search_devs(
@ -347,7 +344,7 @@ def _parse_set_region_values(argvish):
print(Commands.set_region.__doc__.strip()) print(Commands.set_region.__doc__.strip())
exit(EXIT_ERROR) exit(EXIT_ERROR)
devs_and_regions = izip(islice(argvish, 0, len(argvish), 2), devs_and_regions = zip(islice(argvish, 0, len(argvish), 2),
islice(argvish, 1, len(argvish), 2)) islice(argvish, 1, len(argvish), 2))
for devstr, regionstr in devs_and_regions: for devstr, regionstr in devs_and_regions:
devs.extend(builder.search_devs( devs.extend(builder.search_devs(
@ -382,7 +379,7 @@ def _parse_set_zone_values(argvish):
print(Commands.set_zone.__doc__.strip()) print(Commands.set_zone.__doc__.strip())
exit(EXIT_ERROR) exit(EXIT_ERROR)
devs_and_zones = izip(islice(argvish, 0, len(argvish), 2), devs_and_zones = zip(islice(argvish, 0, len(argvish), 2),
islice(argvish, 1, len(argvish), 2)) islice(argvish, 1, len(argvish), 2))
for devstr, zonestr in devs_and_zones: for devstr, zonestr in devs_and_zones:
devs.extend(builder.search_devs( devs.extend(builder.search_devs(
@ -415,7 +412,7 @@ def _parse_set_info_values(argvish):
print(Commands.search.__doc__.strip()) print(Commands.search.__doc__.strip())
exit(EXIT_ERROR) exit(EXIT_ERROR)
searches_and_changes = izip(islice(argvish, 0, len(argvish), 2), searches_and_changes = zip(islice(argvish, 0, len(argvish), 2),
islice(argvish, 1, len(argvish), 2)) islice(argvish, 1, len(argvish), 2))
for search_value, change_value in searches_and_changes: for search_value, change_value in searches_and_changes:

View File

@ -27,28 +27,22 @@ BufferedHTTPResponse.
""" """
from swift.common import constraints from swift.common import constraints
import http.client
import logging import logging
import time import time
import socket import socket
import eventlet from eventlet.green.http.client import CONTINUE, HTTPConnection, \
from eventlet.green.httplib import CONTINUE, HTTPConnection, HTTPMessage, \
HTTPResponse, HTTPSConnection, _UNKNOWN, ImproperConnectionState HTTPResponse, HTTPSConnection, _UNKNOWN, ImproperConnectionState
from six.moves.urllib.parse import quote, parse_qsl, urlencode from urllib.parse import quote, parse_qsl, urlencode
import six
if six.PY2: from eventlet.green.http import client as green_http_client
httplib = eventlet.import_patched('httplib')
from eventlet.green import httplib as green_httplib
else:
httplib = eventlet.import_patched('http.client')
from eventlet.green.http import client as green_httplib
# Apparently http.server uses this to decide when/whether to send a 431. # Apparently http.server uses this to decide when/whether to send a 431.
# Give it some slack, so the app is more likely to get the chance to reject # Give it some slack, so the app is more likely to get the chance to reject
# with a 400 instead. # with a 400 instead.
httplib._MAXHEADERS = constraints.MAX_HEADER_COUNT * 1.6 http.client._MAXHEADERS = constraints.MAX_HEADER_COUNT * 1.6
green_httplib._MAXHEADERS = constraints.MAX_HEADER_COUNT * 1.6 green_http_client._MAXHEADERS = constraints.MAX_HEADER_COUNT * 1.6
class BufferedHTTPResponse(HTTPResponse): class BufferedHTTPResponse(HTTPResponse):
@ -65,11 +59,6 @@ class BufferedHTTPResponse(HTTPResponse):
# No socket means no file-like -- set it to None like in # No socket means no file-like -- set it to None like in
# HTTPResponse.close() # HTTPResponse.close()
self.fp = None self.fp = None
elif six.PY2:
# sock.fd is a socket._socketobject
# sock.fd._sock is a _socket.socket object, which is what we want.
self._real_socket = sock.fd._sock
self.fp = sock.makefile('rb')
else: else:
# sock.fd is a socket.socket, which should have a _real_close # sock.fd is a socket.socket, which should have a _real_close
self._real_socket = sock.fd self._real_socket = sock.fd
@ -91,7 +80,6 @@ class BufferedHTTPResponse(HTTPResponse):
self.will_close = _UNKNOWN # conn will close at end of response self.will_close = _UNKNOWN # conn will close at end of response
self._readline_buffer = b'' self._readline_buffer = b''
if not six.PY2:
def begin(self): def begin(self):
HTTPResponse.begin(self) HTTPResponse.begin(self)
header_payload = self.headers.get_payload() header_payload = self.headers.get_payload()
@ -125,15 +113,7 @@ class BufferedHTTPResponse(HTTPResponse):
self.status = status self.status = status
self.reason = reason.strip() self.reason = reason.strip()
self.version = 11 self.version = 11
if six.PY2: self.headers = self.msg = http.client.parse_headers(self.fp)
# Under py2, HTTPMessage.__init__ reads the headers
# which advances fp
self.msg = HTTPMessage(self.fp, 0)
# immediately kill msg.fp to make sure it isn't read again
self.msg.fp = None
else:
# py3 has a separate helper for it
self.headers = self.msg = httplib.parse_headers(self.fp)
def read(self, amt=None): def read(self, amt=None):
if not self._readline_buffer: if not self._readline_buffer:
@ -157,26 +137,6 @@ class BufferedHTTPResponse(HTTPResponse):
self._readline_buffer = b'' self._readline_buffer = b''
return buf + HTTPResponse.read(self, smaller_amt) return buf + HTTPResponse.read(self, smaller_amt)
def readline(self, size=1024):
# You'd think Python's httplib would provide this, but it doesn't.
# It does, however, provide a comment in the HTTPResponse class:
#
# # XXX It would be nice to have readline and __iter__ for this,
# # too.
#
# Yes, it certainly would.
while (b'\n' not in self._readline_buffer
and len(self._readline_buffer) < size):
read_size = size - len(self._readline_buffer)
chunk = HTTPResponse.read(self, read_size)
if not chunk:
break
self._readline_buffer += chunk
line, newline, rest = self._readline_buffer.partition(b'\n')
self._readline_buffer = rest
return line + newline
def nuke_from_orbit(self): def nuke_from_orbit(self):
""" """
Terminate the socket with extreme prejudice. Terminate the socket with extreme prejudice.
@ -186,12 +146,7 @@ class BufferedHTTPResponse(HTTPResponse):
you care about has a reference to this socket. you care about has a reference to this socket.
""" """
if self._real_socket: if self._real_socket:
if six.PY2: # Hopefully this is equivalent to py2's _real_socket.close()?
# this is idempotent; see sock_close in Modules/socketmodule.c
# in the Python source for details.
self._real_socket.close()
else:
# Hopefully this is equivalent?
# TODO: verify that this does everything ^^^^ does for py2 # TODO: verify that this does everything ^^^^ does for py2
self._real_socket._real_close() self._real_socket._real_close()
self._real_socket = None self._real_socket = None
@ -268,13 +223,13 @@ def http_connect(ipaddr, port, device, partition, method, path,
:param ssl: set True if SSL should be used (default: False) :param ssl: set True if SSL should be used (default: False)
:returns: HTTPConnection object :returns: HTTPConnection object
""" """
if isinstance(path, six.text_type): if isinstance(path, str):
path = path.encode("utf-8") path = path.encode("utf-8")
if isinstance(device, six.text_type): if isinstance(device, str):
device = device.encode("utf-8") device = device.encode("utf-8")
if isinstance(partition, six.text_type): if isinstance(partition, str):
partition = partition.encode('utf-8') partition = partition.encode('utf-8')
elif isinstance(partition, six.integer_types): elif isinstance(partition, int):
partition = str(partition).encode('ascii') partition = str(partition).encode('ascii')
path = quote(b'/' + device + b'/' + partition + path) path = quote(b'/' + device + b'/' + partition + path)
return http_connect_raw( return http_connect_raw(
@ -305,10 +260,6 @@ def http_connect_raw(ipaddr, port, method, path, headers=None,
conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port)) conn = BufferedHTTPConnection('%s:%s' % (ipaddr, port))
if query_string: if query_string:
# Round trip to ensure proper quoting # Round trip to ensure proper quoting
if six.PY2:
query_string = urlencode(parse_qsl(
query_string, keep_blank_values=True))
else:
query_string = urlencode( query_string = urlencode(
parse_qsl(query_string, keep_blank_values=True, parse_qsl(query_string, keep_blank_values=True,
encoding='latin1'), encoding='latin1'),

View File

@ -17,9 +17,8 @@ import functools
import os import os
from os.path import isdir # tighter scoped import for mocking from os.path import isdir # tighter scoped import for mocking
import six from configparser import ConfigParser, NoSectionError, NoOptionError
from six.moves.configparser import ConfigParser, NoSectionError, NoOptionError import urllib
from six.moves import urllib
from swift.common import utils, exceptions from swift.common import utils, exceptions
from swift.common.swob import HTTPBadRequest, HTTPLengthRequired, \ from swift.common.swob import HTTPBadRequest, HTTPLengthRequired, \
@ -130,7 +129,7 @@ def check_metadata(req, target_type):
meta_count = 0 meta_count = 0
meta_size = 0 meta_size = 0
for key, value in req.headers.items(): for key, value in req.headers.items():
if (isinstance(value, six.string_types) if (isinstance(value, str)
and len(value) > MAX_HEADER_SIZE): and len(value) > MAX_HEADER_SIZE):
return HTTPBadRequest(body=b'Header value too long: %s' % return HTTPBadRequest(body=b'Header value too long: %s' %
@ -364,7 +363,7 @@ def check_utf8(string, internal=False):
if not string: if not string:
return False return False
try: try:
if isinstance(string, six.text_type): if isinstance(string, str):
encoded = string.encode('utf-8') encoded = string.encode('utf-8')
decoded = string decoded = string
else: else:
@ -412,9 +411,6 @@ def check_name_format(req, name, target_type):
raise HTTPPreconditionFailed( raise HTTPPreconditionFailed(
request=req, request=req,
body='%s name cannot be empty' % target_type) body='%s name cannot be empty' % target_type)
if six.PY2:
if isinstance(name, six.text_type):
name = name.encode('utf-8')
if '/' in name: if '/' in name:
raise HTTPPreconditionFailed( raise HTTPPreconditionFailed(
request=req, request=req,

View File

@ -19,8 +19,7 @@ import hmac
import os import os
import time import time
import six import configparser
from six.moves import configparser
from swift.common.utils import get_valid_utf8_str from swift.common.utils import get_valid_utf8_str
@ -158,7 +157,7 @@ class ContainerSyncRealms(object):
user_key = get_valid_utf8_str(user_key) user_key = get_valid_utf8_str(user_key)
# XXX We don't know what is the best here yet; wait for container # XXX We don't know what is the best here yet; wait for container
# sync to be tested. # sync to be tested.
if isinstance(path, six.text_type): if isinstance(path, str):
path = path.encode('utf-8') path = path.encode('utf-8')
return hmac.new( return hmac.new(
realm_key, realm_key,

View File

@ -21,11 +21,9 @@ import json
import logging import logging
import os import os
from uuid import uuid4 from uuid import uuid4
import sys
import time import time
import errno import errno
import six import pickle # nosec: B403
import six.moves.cPickle as pickle
from tempfile import mkstemp from tempfile import mkstemp
from eventlet import sleep, Timeout from eventlet import sleep, Timeout
@ -55,27 +53,13 @@ SQLITE_ARG_LIMIT = 999
RECLAIM_PAGE_SIZE = 10000 RECLAIM_PAGE_SIZE = 10000
def utf8encode(*args):
return [(s.encode('utf8') if isinstance(s, six.text_type) else s)
for s in args]
def native_str_keys_and_values(metadata): def native_str_keys_and_values(metadata):
if six.PY2: bin_keys = [k for k in metadata if isinstance(k, bytes)]
uni_keys = [k for k in metadata if isinstance(k, six.text_type)]
for k in uni_keys:
sv = metadata[k]
del metadata[k]
metadata[k.encode('utf-8')] = [
x.encode('utf-8') if isinstance(x, six.text_type) else x
for x in sv]
else:
bin_keys = [k for k in metadata if isinstance(k, six.binary_type)]
for k in bin_keys: for k in bin_keys:
sv = metadata[k] sv = metadata[k]
del metadata[k] del metadata[k]
metadata[k.decode('utf-8')] = [ metadata[k.decode('utf-8')] = [
x.decode('utf-8') if isinstance(x, six.binary_type) else x x.decode('utf-8') if isinstance(x, bytes) else x
for x in sv] for x in sv]
@ -219,7 +203,7 @@ def get_db_connection(path, timeout=30, logger=None, okay_to_create=False):
connect_time = time.time() connect_time = time.time()
conn = sqlite3.connect(path, check_same_thread=False, conn = sqlite3.connect(path, check_same_thread=False,
factory=GreenDBConnection, timeout=timeout) factory=GreenDBConnection, timeout=timeout)
if QUERY_LOGGING and logger and not six.PY2: if QUERY_LOGGING and logger:
conn.set_trace_callback(logger.debug) conn.set_trace_callback(logger.debug)
if not okay_to_create: if not okay_to_create:
# attempt to detect and fail when connect creates the db file # attempt to detect and fail when connect creates the db file
@ -380,7 +364,7 @@ class DatabaseBroker(object):
os.close(fd) os.close(fd)
conn = sqlite3.connect(tmp_db_file, check_same_thread=False, conn = sqlite3.connect(tmp_db_file, check_same_thread=False,
factory=GreenDBConnection, timeout=0) factory=GreenDBConnection, timeout=0)
if QUERY_LOGGING and not six.PY2: if QUERY_LOGGING:
conn.set_trace_callback(self.logger.debug) conn.set_trace_callback(self.logger.debug)
# creating dbs implicitly does a lot of transactions, so we # creating dbs implicitly does a lot of transactions, so we
# pick fast, unsafe options here and do a big fsync at the end. # pick fast, unsafe options here and do a big fsync at the end.
@ -505,25 +489,25 @@ class DatabaseBroker(object):
self.logger.error(detail) self.logger.error(detail)
raise sqlite3.DatabaseError(detail) raise sqlite3.DatabaseError(detail)
def possibly_quarantine(self, exc_type, exc_value, exc_traceback): def possibly_quarantine(self, err):
""" """
Checks the exception info to see if it indicates a quarantine situation Checks the exception info to see if it indicates a quarantine situation
(malformed or corrupted database). If not, the original exception will (malformed or corrupted database). If not, the original exception will
be reraised. If so, the database will be quarantined and a new be reraised. If so, the database will be quarantined and a new
sqlite3.DatabaseError will be raised indicating the action taken. sqlite3.DatabaseError will be raised indicating the action taken.
""" """
if 'database disk image is malformed' in str(exc_value): if 'database disk image is malformed' in str(err):
exc_hint = 'malformed database' exc_hint = 'malformed database'
elif 'malformed database schema' in str(exc_value): elif 'malformed database schema' in str(err):
exc_hint = 'malformed database' exc_hint = 'malformed database'
elif ' is not a database' in str(exc_value): elif ' is not a database' in str(err):
# older versions said 'file is not a database' # older versions said 'file is not a database'
# now 'file is encrypted or is not a database' # now 'file is encrypted or is not a database'
exc_hint = 'corrupted database' exc_hint = 'corrupted database'
elif 'disk I/O error' in str(exc_value): elif 'disk I/O error' in str(err):
exc_hint = 'disk error while accessing database' exc_hint = 'disk error while accessing database'
else: else:
six.reraise(exc_type, exc_value, exc_traceback) raise err
self.quarantine(exc_hint) self.quarantine(exc_hint)
@ -557,8 +541,8 @@ class DatabaseBroker(object):
try: try:
self.conn = get_db_connection(self.db_file, self.timeout, self.conn = get_db_connection(self.db_file, self.timeout,
self.logger) self.logger)
except (sqlite3.DatabaseError, DatabaseConnectionError): except (sqlite3.DatabaseError, DatabaseConnectionError) as e:
self.possibly_quarantine(*sys.exc_info()) self.possibly_quarantine(e)
else: else:
raise DatabaseConnectionError(self.db_file, "DB doesn't exist") raise DatabaseConnectionError(self.db_file, "DB doesn't exist")
conn = self.conn conn = self.conn
@ -567,12 +551,12 @@ class DatabaseBroker(object):
yield conn yield conn
conn.rollback() conn.rollback()
self.conn = conn self.conn = conn
except sqlite3.DatabaseError: except sqlite3.DatabaseError as e:
try: try:
conn.close() conn.close()
except Exception: except Exception:
pass pass
self.possibly_quarantine(*sys.exc_info()) self.possibly_quarantine(e)
except (Exception, Timeout): except (Exception, Timeout):
conn.close() conn.close()
raise raise
@ -848,11 +832,8 @@ class DatabaseBroker(object):
for entry in fp.read().split(b':'): for entry in fp.read().split(b':'):
if entry: if entry:
try: try:
if six.PY2:
data = pickle.loads(base64.b64decode(entry))
else:
data = pickle.loads(base64.b64decode(entry), data = pickle.loads(base64.b64decode(entry),
encoding='utf8') encoding='utf8') # nosec: B301
self._commit_puts_load(item_list, data) self._commit_puts_load(item_list, data)
except Exception: except Exception:
self.logger.exception( self.logger.exception(

View File

@ -13,9 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import binascii import binascii
import hashlib
import hmac import hmac
import six
from swift.common.utils import strict_b64decode from swift.common.utils import strict_b64decode
@ -55,17 +53,14 @@ def get_hmac(request_method, path, expires, key, digest="sha1",
parts.insert(0, ip_range) parts.insert(0, ip_range)
formats.insert(0, b"ip=%s") formats.insert(0, b"ip=%s")
if not isinstance(key, six.binary_type): if isinstance(key, str):
key = key.encode('utf8') key = key.encode('utf8')
message = b'\n'.join( message = b'\n'.join(
fmt % (part if isinstance(part, six.binary_type) fmt % (part if isinstance(part, bytes)
else part.encode("utf-8")) else part.encode("utf-8"))
for fmt, part in zip(formats, parts)) for fmt, part in zip(formats, parts))
if six.PY2 and isinstance(digest, six.string_types):
digest = getattr(hashlib, digest)
return hmac.new(key, message, digest).hexdigest() return hmac.new(key, message, digest).hexdigest()
@ -132,15 +127,10 @@ def extract_digest_and_algorithm(value):
if ('-' in value or '_' in value) and not ( if ('-' in value or '_' in value) and not (
'+' in value or '/' in value): '+' in value or '/' in value):
value = value.replace('-', '+').replace('_', '/') value = value.replace('-', '+').replace('_', '/')
value = binascii.hexlify(strict_b64decode(value + '==')) value = binascii.hexlify(
if not six.PY2: strict_b64decode(value + '==')).decode('ascii')
value = value.decode('ascii')
else: else:
try:
binascii.unhexlify(value) # make sure it decodes binascii.unhexlify(value) # make sure it decodes
except TypeError:
# This is just for py2
raise ValueError('Non-hexadecimal digit found')
algo = { algo = {
40: 'sha1', 40: 'sha1',
64: 'sha256', 64: 'sha256',

View File

@ -23,9 +23,8 @@ import os
import socket import socket
from eventlet import sleep, Timeout from eventlet import sleep, Timeout
import six import pickle # nosec: B403
import six.moves.cPickle as pickle from http.client import HTTPException
from six.moves.http_client import HTTPException
from swift.common.bufferedhttp import http_connect, http_connect_raw from swift.common.bufferedhttp import http_connect, http_connect_raw
from swift.common.exceptions import ClientException from swift.common.exceptions import ClientException
@ -44,7 +43,7 @@ class DirectClientException(ClientException):
# host can be used to override the node ip and port reported in # host can be used to override the node ip and port reported in
# the exception # the exception
host = host if host is not None else node host = host if host is not None else node
if not isinstance(path, six.text_type): if isinstance(path, bytes):
path = path.decode("utf-8") path = path.decode("utf-8")
full_path = quote('/%s/%s%s' % (node['device'], part, path)) full_path = quote('/%s/%s%s' % (node['device'], part, path))
msg = '%s server %s:%s direct %s %r gave status %s' % ( msg = '%s server %s:%s direct %s %r gave status %s' % (
@ -59,7 +58,7 @@ class DirectClientException(ClientException):
class DirectClientReconException(ClientException): class DirectClientReconException(ClientException):
def __init__(self, method, node, path, resp): def __init__(self, method, node, path, resp):
if not isinstance(path, six.text_type): if isinstance(path, bytes):
path = path.decode("utf-8") path = path.decode("utf-8")
msg = 'server %s:%s direct %s %r gave status %s' % ( msg = 'server %s:%s direct %s %r gave status %s' % (
node['ip'], node['port'], method, path, resp.status) node['ip'], node['port'], method, path, resp.status)
@ -72,7 +71,7 @@ class DirectClientReconException(ClientException):
def _make_path(*components): def _make_path(*components):
return u'/' + u'/'.join( return u'/' + u'/'.join(
x.decode('utf-8') if isinstance(x, six.binary_type) else x x.decode('utf-8') if isinstance(x, bytes) else x
for x in components) for x in components)
@ -111,7 +110,7 @@ def _make_req(node, part, method, path, headers, stype,
content_length = int(v) content_length = int(v)
if not contents: if not contents:
headers['Content-Length'] = '0' headers['Content-Length'] = '0'
if isinstance(contents, six.string_types): if isinstance(contents, str):
contents = [contents] contents = [contents]
if content_length is None: if content_length is None:
headers['Transfer-Encoding'] = 'chunked' headers['Transfer-Encoding'] = 'chunked'
@ -657,7 +656,7 @@ def direct_get_suffix_hashes(node, part, suffixes, conn_timeout=5,
host={'ip': node['replication_ip'], host={'ip': node['replication_ip'],
'port': node['replication_port']} 'port': node['replication_port']}
) )
return pickle.loads(resp.read()) return pickle.loads(resp.read()) # nosec: B301
def retry(func, *args, **kwargs): def retry(func, *args, **kwargs):

View File

@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import six
class HeaderKeyDict(dict): class HeaderKeyDict(dict):
""" """
@ -31,9 +29,6 @@ class HeaderKeyDict(dict):
@staticmethod @staticmethod
def _title(s): def _title(s):
if six.PY2:
return s.title()
else:
return s.encode('latin1').title().decode('latin1') return s.encode('latin1').title().decode('latin1')
def update(self, other): def update(self, other):
@ -51,9 +46,7 @@ class HeaderKeyDict(dict):
key = self._title(key) key = self._title(key)
if value is None: if value is None:
self.pop(key, None) self.pop(key, None)
elif six.PY2 and isinstance(value, six.text_type): elif isinstance(value, bytes):
return dict.__setitem__(self, key, value.encode('utf-8'))
elif six.PY3 and isinstance(value, six.binary_type):
return dict.__setitem__(self, key, value.decode('latin-1')) return dict.__setitem__(self, key, value.decode('latin-1'))
else: else:
return dict.__setitem__(self, key, str(value)) return dict.__setitem__(self, key, str(value))

View File

@ -14,18 +14,13 @@
# limitations under the License. # limitations under the License.
from eventlet import wsgi, websocket from eventlet import wsgi, websocket
import six
from swift.common.utils import generate_trans_id from swift.common.utils import generate_trans_id
from swift.common.http import HTTP_NO_CONTENT, HTTP_RESET_CONTENT, \ from swift.common.http import HTTP_NO_CONTENT, HTTP_RESET_CONTENT, \
HTTP_NOT_MODIFIED HTTP_NOT_MODIFIED
if six.PY2: from eventlet.green.http import client as http_client
from eventlet.green import httplib as http_client from html import escape
from cgi import escape
else:
from eventlet.green.http import client as http_client
from html import escape
class SwiftHttpProtocol(wsgi.HttpProtocol): class SwiftHttpProtocol(wsgi.HttpProtocol):
@ -59,13 +54,6 @@ class SwiftHttpProtocol(wsgi.HttpProtocol):
class MessageClass(wsgi.HttpProtocol.MessageClass): class MessageClass(wsgi.HttpProtocol.MessageClass):
"""Subclass to see when the client didn't provide a Content-Type""" """Subclass to see when the client didn't provide a Content-Type"""
# for py2:
def parsetype(self):
if self.typeheader is None:
self.typeheader = ''
wsgi.HttpProtocol.MessageClass.parsetype(self)
# for py3:
def get_default_type(self): def get_default_type(self):
"""If the client didn't provide a content type, leave it blank.""" """If the client didn't provide a content type, leave it blank."""
return '' return ''
@ -84,9 +72,7 @@ class SwiftHttpProtocol(wsgi.HttpProtocol):
self.command = None # set in case of error on the first line self.command = None # set in case of error on the first line
self.request_version = version = self.default_request_version self.request_version = version = self.default_request_version
self.close_connection = True self.close_connection = True
requestline = self.raw_requestline requestline = self.raw_requestline.decode('iso-8859-1')
if not six.PY2:
requestline = requestline.decode('iso-8859-1')
requestline = requestline.rstrip('\r\n') requestline = requestline.rstrip('\r\n')
self.requestline = requestline self.requestline = requestline
# Split off \x20 explicitly (see https://bugs.python.org/issue33973) # Split off \x20 explicitly (see https://bugs.python.org/issue33973)
@ -147,9 +133,6 @@ class SwiftHttpProtocol(wsgi.HttpProtocol):
self.command, self.path = command, path self.command, self.path = command, path
# Examine the headers and look for a Connection directive. # Examine the headers and look for a Connection directive.
if six.PY2:
self.headers = self.MessageClass(self.rfile, 0)
else:
try: try:
self.headers = http_client.parse_headers( self.headers = http_client.parse_headers(
self.rfile, self.rfile,
@ -183,7 +166,6 @@ class SwiftHttpProtocol(wsgi.HttpProtocol):
return False return False
return True return True
if not six.PY2:
def get_environ(self, *args, **kwargs): def get_environ(self, *args, **kwargs):
environ = wsgi.HttpProtocol.get_environ(self, *args, **kwargs) environ = wsgi.HttpProtocol.get_environ(self, *args, **kwargs)
header_payload = self.headers.get_payload() header_payload = self.headers.get_payload()
@ -332,7 +314,6 @@ class SwiftHttpProxiedProtocol(SwiftHttpProtocol):
SwiftHttpProtocol.__init__(self, *a, **kw) SwiftHttpProtocol.__init__(self, *a, **kw)
def handle_error(self, connection_line): def handle_error(self, connection_line):
if not six.PY2:
connection_line = connection_line.decode('latin-1') connection_line = connection_line.decode('latin-1')
# No further processing will proceed on this connection under any # No further processing will proceed on this connection under any
@ -373,10 +354,6 @@ class SwiftHttpProxiedProtocol(SwiftHttpProtocol):
# line. # line.
pass pass
elif proxy_parts[1] in (b'TCP4', b'TCP6') and len(proxy_parts) == 6: elif proxy_parts[1] in (b'TCP4', b'TCP6') and len(proxy_parts) == 6:
if six.PY2:
self.client_address = (proxy_parts[2], proxy_parts[4])
self.proxy_address = (proxy_parts[3], proxy_parts[5])
else:
self.client_address = ( self.client_address = (
proxy_parts[2].decode('latin-1'), proxy_parts[2].decode('latin-1'),
proxy_parts[4].decode('latin-1')) proxy_parts[4].decode('latin-1'))

View File

@ -14,13 +14,13 @@
# limitations under the License. # limitations under the License.
from eventlet import sleep, Timeout, spawn from eventlet import sleep, Timeout, spawn
from eventlet.green import httplib, socket from eventlet.green import socket
from eventlet.green.http import client as http_client
from eventlet.green.urllib import request as urllib_request
import json import json
import six import urllib
from six.moves import range
from six.moves import urllib
import struct import struct
from sys import exc_info, exit from sys import exit
import zlib import zlib
from time import gmtime, strftime, time from time import gmtime, strftime, time
from zlib import compressobj from zlib import compressobj
@ -34,11 +34,6 @@ from swift.common.swob import Request, bytes_to_wsgi
from swift.common.utils import quote, close_if_possible, drain_and_close from swift.common.utils import quote, close_if_possible, drain_and_close
from swift.common.wsgi import loadapp from swift.common.wsgi import loadapp
if six.PY3:
from eventlet.green.urllib import request as urllib2
else:
from eventlet.green import urllib2
class UnexpectedResponse(Exception): class UnexpectedResponse(Exception):
""" """
@ -127,8 +122,6 @@ class CompressingFileReader(object):
return chunk return chunk
raise StopIteration raise StopIteration
next = __next__
def seek(self, offset, whence=0): def seek(self, offset, whence=0):
if not (offset == 0 and whence == 0): if not (offset == 0 and whence == 0):
raise NotImplementedError('Seek implemented on offset 0 only') raise NotImplementedError('Seek implemented on offset 0 only')
@ -217,7 +210,7 @@ class InternalClient(object):
headers.setdefault(USE_REPLICATION_NETWORK_HEADER, 'true') headers.setdefault(USE_REPLICATION_NETWORK_HEADER, 'true')
for attempt in range(self.request_tries): for attempt in range(self.request_tries):
resp = exc_type = exc_value = exc_traceback = None resp = err = None
req = Request.blank( req = Request.blank(
path, environ={'REQUEST_METHOD': method}, headers=headers) path, environ={'REQUEST_METHOD': method}, headers=headers)
if body_file is not None: if body_file is not None:
@ -229,8 +222,8 @@ class InternalClient(object):
try: try:
# execute in a separate greenthread to not polute corolocals # execute in a separate greenthread to not polute corolocals
resp = spawn(req.get_response, self.app).wait() resp = spawn(req.get_response, self.app).wait()
except (Exception, Timeout): except (Exception, Timeout) as e:
exc_type, exc_value, exc_traceback = exc_info() err = e
else: else:
if resp.status_int in acceptable_statuses or \ if resp.status_int in acceptable_statuses or \
resp.status_int // 100 in acceptable_statuses: resp.status_int // 100 in acceptable_statuses:
@ -256,9 +249,8 @@ class InternalClient(object):
# non 2XX responses # non 2XX responses
msg += ' (%s)' % resp.body msg += ' (%s)' % resp.body
raise UnexpectedResponse(msg, resp) raise UnexpectedResponse(msg, resp)
if exc_type: if err:
# To make pep8 tool happy, in place of raise t, v, tb: raise err
six.reraise(exc_type, exc_value, exc_traceback)
def handle_request(self, *args, **kwargs): def handle_request(self, *args, **kwargs):
resp = self.make_request(*args, **kwargs) resp = self.make_request(*args, **kwargs)
@ -848,10 +840,10 @@ class InternalClient(object):
def get_auth(url, user, key, auth_version='1.0', **kwargs): def get_auth(url, user, key, auth_version='1.0', **kwargs):
if auth_version != '1.0': if auth_version != '1.0':
exit('ERROR: swiftclient missing, only auth v1.0 supported') exit('ERROR: swiftclient missing, only auth v1.0 supported')
req = urllib2.Request(url) req = urllib_request.Request(url)
req.add_header('X-Auth-User', user) req.add_header('X-Auth-User', user)
req.add_header('X-Auth-Key', key) req.add_header('X-Auth-Key', key)
conn = urllib2.urlopen(req) conn = urllib_request.urlopen(req)
headers = conn.info() headers = conn.info()
return ( return (
headers.getheader('X-Storage-Url'), headers.getheader('X-Storage-Url'),
@ -914,12 +906,12 @@ class SimpleClient(object):
url += '?' + '&'.join(params) url += '?' + '&'.join(params)
req = urllib2.Request(url, headers=headers, data=contents) req = urllib_request.Request(url, headers=headers, data=contents)
if proxy: if proxy:
proxy = urllib.parse.urlparse(proxy) proxy = urllib.parse.urlparse(proxy)
req.set_proxy(proxy.netloc, proxy.scheme) req.set_proxy(proxy.netloc, proxy.scheme)
req.get_method = lambda: method req.get_method = lambda: method
conn = urllib2.urlopen(req, timeout=timeout) conn = urllib_request.urlopen(req, timeout=timeout)
body = conn.read() body = conn.read()
info = conn.info() info = conn.info()
try: try:
@ -961,14 +953,15 @@ class SimpleClient(object):
self.attempts += 1 self.attempts += 1
try: try:
return self.base_request(method, **kwargs) return self.base_request(method, **kwargs)
except urllib2.HTTPError as err: except urllib_request.HTTPError as err:
if is_client_error(err.getcode() or 500): if is_client_error(err.getcode() or 500):
raise ClientException('Client error', raise ClientException('Client error',
http_status=err.getcode()) http_status=err.getcode())
elif self.attempts > retries: elif self.attempts > retries:
raise ClientException('Raise too many retries', raise ClientException('Raise too many retries',
http_status=err.getcode()) http_status=err.getcode())
except (socket.error, httplib.HTTPException, urllib2.URLError): except (socket.error, http_client.HTTPException,
urllib_request.URLError):
if self.attempts > retries: if self.attempts > retries:
raise raise
sleep(backoff) sleep(backoff)

View File

@ -17,8 +17,6 @@ import os
import ctypes import ctypes
from ctypes.util import find_library from ctypes.util import find_library
import six
__all__ = ['linkat'] __all__ = ['linkat']
@ -72,9 +70,9 @@ class Linkat(object):
if not isinstance(olddirfd, int) or not isinstance(newdirfd, int): if not isinstance(olddirfd, int) or not isinstance(newdirfd, int):
raise TypeError("fd must be an integer.") raise TypeError("fd must be an integer.")
if isinstance(oldpath, six.text_type): if isinstance(oldpath, str):
oldpath = oldpath.encode('utf8') oldpath = oldpath.encode('utf8')
if isinstance(newpath, six.text_type): if isinstance(newpath, str):
newpath = newpath.encode('utf8') newpath = newpath.encode('utf8')
return self._c_linkat(olddirfd, oldpath, newdirfd, newpath, flags) return self._c_linkat(olddirfd, oldpath, newdirfd, newpath, flags)

View File

@ -24,14 +24,9 @@ import signal
import time import time
import subprocess import subprocess
import re import re
import six
import sys import sys
import tempfile import tempfile
try: from shutil import which
from shutil import which
except ImportError:
# py2
from distutils.spawn import find_executable as which
from swift.common.utils import search_tree, remove_file, write_file, readconf from swift.common.utils import search_tree, remove_file, write_file, readconf
from swift.common.exceptions import InvalidPidFileException from swift.common.exceptions import InvalidPidFileException
@ -845,10 +840,8 @@ class Server(object):
if proc.stdout.closed: if proc.stdout.closed:
output = '' output = ''
else: else:
output = proc.stdout.read() output = proc.stdout.read().decode('utf8', 'backslashreplace')
proc.stdout.close() proc.stdout.close()
if not six.PY2:
output = output.decode('utf8', 'backslashreplace')
if kwargs.get('once', False): if kwargs.get('once', False):
# if you don't want once to wait you can send it to the # if you don't want once to wait you can send it to the

View File

@ -45,7 +45,6 @@ http://github.com/memcached/memcached/blob/1.4.2/doc/protocol.txt
""" """
import os import os
import six
import json import json
import logging import logging
# the name of 'time' module is changed to 'tm', to avoid changing the # the name of 'time' module is changed to 'tm', to avoid changing the
@ -56,8 +55,7 @@ from bisect import bisect
from eventlet.green import socket, ssl from eventlet.green import socket, ssl
from eventlet.pools import Pool from eventlet.pools import Pool
from eventlet import Timeout from eventlet import Timeout
from six.moves import range from configparser import ConfigParser, NoSectionError, NoOptionError
from six.moves.configparser import ConfigParser, NoSectionError, NoOptionError
from swift.common import utils from swift.common import utils
from swift.common.exceptions import MemcacheConnectionError, \ from swift.common.exceptions import MemcacheConnectionError, \
MemcacheIncrNotFoundError, MemcachePoolTimeout MemcacheIncrNotFoundError, MemcachePoolTimeout
@ -91,9 +89,6 @@ EXPTIME_MAXDELTA = 30 * 24 * 60 * 60
def md5hash(key): def md5hash(key):
if not isinstance(key, bytes): if not isinstance(key, bytes):
if six.PY2:
key = key.encode('utf-8')
else:
key = key.encode('utf-8', errors='surrogateescape') key = key.encode('utf-8', errors='surrogateescape')
return md5(key, usedforsecurity=False).hexdigest().encode('ascii') return md5(key, usedforsecurity=False).hexdigest().encode('ascii')
@ -421,7 +416,6 @@ class MemcacheRing(object):
# Wait for the set to complete # Wait for the set to complete
msg = fp.readline().strip() msg = fp.readline().strip()
if msg != b'STORED': if msg != b'STORED':
if not six.PY2:
msg = msg.decode('ascii') msg = msg.decode('ascii')
raise MemcacheConnectionError('failed set: %s' % msg) raise MemcacheConnectionError('failed set: %s' % msg)
self._return_conn(server, fp, sock) self._return_conn(server, fp, sock)

View File

@ -14,8 +14,7 @@
# limitations under the License. # limitations under the License.
import json import json
import six from urllib.parse import unquote, urlparse
from six.moves.urllib.parse import unquote, urlparse
def clean_acl(name, value): def clean_acl(name, value):
@ -294,12 +293,8 @@ def acls_from_account_info(info):
if not any((admin_members, readwrite_members, readonly_members)): if not any((admin_members, readwrite_members, readonly_members)):
return None return None
acls = { return {
'admin': admin_members, 'admin': admin_members,
'read-write': readwrite_members, 'read-write': readwrite_members,
'read-only': readonly_members, 'read-only': readonly_members,
} }
if six.PY2:
for k in ('admin', 'read-write', 'read-only'):
acls[k] = [v.encode('utf8') for v in acls[k]]
return acls

View File

@ -195,7 +195,6 @@ payload sent to the proxy (the list of objects/containers to be deleted).
""" """
import json import json
import six
import tarfile import tarfile
from xml.sax.saxutils import escape # nosec B406 from xml.sax.saxutils import escape # nosec B406
from time import time from time import time
@ -257,8 +256,6 @@ def get_response_body(data_format, data_dict, error_list, root_tag):
escape(status), '</status></object>\n', escape(status), '</status></object>\n',
]) ])
output.extend(['</errors>\n</', root_tag, '>\n']) output.extend(['</errors>\n</', root_tag, '>\n'])
if six.PY2:
return ''.join(output)
return ''.join(output).encode('utf-8') return ''.join(output).encode('utf-8')
output = [] output = []
@ -268,8 +265,6 @@ def get_response_body(data_format, data_dict, error_list, root_tag):
output.extend( output.extend(
'%s, %s\n' % (name, status) '%s, %s\n' % (name, status)
for name, status in error_list) for name, status in error_list)
if six.PY2:
return ''.join(output)
return ''.join(output).encode('utf-8') return ''.join(output).encode('utf-8')
@ -279,13 +274,9 @@ def pax_key_to_swift_header(pax_key):
return "Content-Type" return "Content-Type"
elif pax_key.startswith(u"SCHILY.xattr.user.meta."): elif pax_key.startswith(u"SCHILY.xattr.user.meta."):
useful_part = pax_key[len(u"SCHILY.xattr.user.meta."):] useful_part = pax_key[len(u"SCHILY.xattr.user.meta."):]
if six.PY2:
return "X-Object-Meta-" + useful_part.encode("utf-8")
return str_to_wsgi("X-Object-Meta-" + useful_part) return str_to_wsgi("X-Object-Meta-" + useful_part)
elif pax_key.startswith(u"LIBARCHIVE.xattr.user.meta."): elif pax_key.startswith(u"LIBARCHIVE.xattr.user.meta."):
useful_part = pax_key[len(u"LIBARCHIVE.xattr.user.meta."):] useful_part = pax_key[len(u"LIBARCHIVE.xattr.user.meta."):]
if six.PY2:
return "X-Object-Meta-" + useful_part.encode("utf-8")
return str_to_wsgi("X-Object-Meta-" + useful_part) return str_to_wsgi("X-Object-Meta-" + useful_part)
else: else:
# You can get things like atime/mtime/ctime or filesystem ACLs in # You can get things like atime/mtime/ctime or filesystem ACLs in
@ -357,9 +348,6 @@ class Bulk(object):
while data_remaining: while data_remaining:
if b'\n' in line: if b'\n' in line:
obj_to_delete, line = line.split(b'\n', 1) obj_to_delete, line = line.split(b'\n', 1)
if six.PY2:
obj_to_delete = wsgi_unquote(obj_to_delete.strip())
else:
# yeah, all this chaining is pretty terrible... # yeah, all this chaining is pretty terrible...
# but it gets even worse trying to use UTF-8 and # but it gets even worse trying to use UTF-8 and
# errors='surrogateescape' when dealing with terrible # errors='surrogateescape' when dealing with terrible
@ -373,9 +361,6 @@ class Bulk(object):
line += data line += data
else: else:
data_remaining = False data_remaining = False
if six.PY2:
obj_to_delete = wsgi_unquote(line.strip())
else:
obj_to_delete = wsgi_to_str(wsgi_unquote( obj_to_delete = wsgi_to_str(wsgi_unquote(
bytes_to_wsgi(line.strip()))) bytes_to_wsgi(line.strip())))
if obj_to_delete: if obj_to_delete:
@ -577,9 +562,7 @@ class Bulk(object):
len(failed_files) >= self.max_failed_extractions: len(failed_files) >= self.max_failed_extractions:
break break
if tar_info.isfile(): if tar_info.isfile():
obj_path = tar_info.name obj_path = tar_info.name.encode('utf-8', 'surrogateescape')
if not six.PY2:
obj_path = obj_path.encode('utf-8', 'surrogateescape')
obj_path = bytes_to_wsgi(obj_path) obj_path = bytes_to_wsgi(obj_path)
if obj_path.startswith('./'): if obj_path.startswith('./'):
obj_path = obj_path[2:] obj_path = obj_path[2:]

View File

@ -27,8 +27,6 @@ maximum lookup depth. If a match is found, the environment's Host header is
rewritten and the request is passed further down the WSGI chain. rewritten and the request is passed further down the WSGI chain.
""" """
import six
try: try:
import dns.resolver import dns.resolver
import dns.exception import dns.exception
@ -149,8 +147,6 @@ class CNAMELookupMiddleware(object):
if self.memcache: if self.memcache:
memcache_key = ''.join(['cname-', a_domain]) memcache_key = ''.join(['cname-', a_domain])
found_domain = self.memcache.get(memcache_key) found_domain = self.memcache.get(memcache_key)
if six.PY2 and found_domain:
found_domain = found_domain.encode('utf-8')
if found_domain is None: if found_domain is None:
ttl, found_domain = lookup_cname(a_domain, self.resolver) ttl, found_domain = lookup_cname(a_domain, self.resolver)
if self.memcache and ttl > 0: if self.memcache and ttl > 0:

View File

@ -19,8 +19,7 @@ import os
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import six import urllib.parse
from six.moves.urllib import parse as urlparse
from swift.common.exceptions import EncryptionException, UnknownSecretIdError from swift.common.exceptions import EncryptionException, UnknownSecretIdError
from swift.common.swob import HTTPInternalServerError from swift.common.swob import HTTPInternalServerError
@ -225,7 +224,7 @@ def dump_crypto_meta(crypto_meta):
for name, value in crypto_meta.items()} for name, value in crypto_meta.items()}
# use sort_keys=True to make serialized form predictable for testing # use sort_keys=True to make serialized form predictable for testing
return urlparse.quote_plus( return urllib.parse.quote_plus(
json.dumps(b64_encode_meta(crypto_meta), sort_keys=True)) json.dumps(b64_encode_meta(crypto_meta), sort_keys=True))
@ -251,13 +250,13 @@ def load_crypto_meta(value, b64decode=True):
str(name): ( str(name): (
base64.b64decode(val) if name in ('iv', 'key') and b64decode base64.b64decode(val) if name in ('iv', 'key') and b64decode
else b64_decode_meta(val) if isinstance(val, dict) else b64_decode_meta(val) if isinstance(val, dict)
else val.encode('utf8') if six.PY2 else val) else val)
for name, val in crypto_meta.items()} for name, val in crypto_meta.items()}
try: try:
if not isinstance(value, six.string_types): if not isinstance(value, str):
raise ValueError('crypto meta not a string') raise ValueError('crypto meta not a string')
val = json.loads(urlparse.unquote_plus(value)) val = json.loads(urllib.parse.unquote_plus(value))
if not isinstance(val, dict): if not isinstance(val, dict):
raise ValueError('crypto meta not a Mapping') raise ValueError('crypto meta not a Mapping')
return b64_decode_meta(val) return b64_decode_meta(val)

View File

@ -14,7 +14,6 @@
# limitations under the License. # limitations under the License.
import hashlib import hashlib
import hmac import hmac
import six
from swift.common.exceptions import UnknownSecretIdError from swift.common.exceptions import UnknownSecretIdError
from swift.common.middleware.crypto.crypto_utils import CRYPTO_KEY_CALLBACK from swift.common.middleware.crypto.crypto_utils import CRYPTO_KEY_CALLBACK
@ -101,11 +100,6 @@ class KeyMasterContext(WSGIContext):
# Older py3 proxies may have written down crypto meta as WSGI # Older py3 proxies may have written down crypto meta as WSGI
# strings; we still need to be able to read that # strings; we still need to be able to read that
try: try:
if six.PY2:
alt_path = tuple(
part.decode('utf-8').encode('latin1')
for part in (key_acct, key_cont, key_obj))
else:
alt_path = tuple( alt_path = tuple(
part.encode('latin1').decode('utf-8') part.encode('latin1').decode('utf-8')
for part in (key_acct, key_cont, key_obj)) for part in (key_acct, key_cont, key_obj))
@ -336,7 +330,6 @@ class BaseKeyMaster(object):
self.logger.warning('Unrecognised secret id: %s' % secret_id) self.logger.warning('Unrecognised secret id: %s' % secret_id)
raise UnknownSecretIdError(secret_id) raise UnknownSecretIdError(secret_id)
else: else:
if not six.PY2:
path = path.encode('utf-8') path = path.encode('utf-8')
return hmac.new(key, path, digestmod=hashlib.sha256).digest() return hmac.new(key, path, digestmod=hashlib.sha256).digest()

View File

@ -120,8 +120,6 @@ Here's an example using ``curl`` with tiny 1-byte segments::
import json import json
import six
from swift.common import constraints from swift.common import constraints
from swift.common.exceptions import ListingIterError, SegmentError from swift.common.exceptions import ListingIterError, SegmentError
from swift.common.http import is_success from swift.common.http import is_success
@ -207,8 +205,6 @@ class GetContext(WSGIContext):
break break
seg_name = segment['name'] seg_name = segment['name']
if six.PY2:
seg_name = seg_name.encode("utf-8")
# We deliberately omit the etag and size here; # We deliberately omit the etag and size here;
# SegmentedIterable will check size and etag if # SegmentedIterable will check size and etag if

View File

@ -123,11 +123,9 @@ the file are simply ignored).
__all__ = ['FormPost', 'filter_factory', 'READ_CHUNK_SIZE', 'MAX_VALUE_LENGTH'] __all__ = ['FormPost', 'filter_factory', 'READ_CHUNK_SIZE', 'MAX_VALUE_LENGTH']
import hmac import hmac
import hashlib
from time import time from time import time
import six from urllib.parse import quote
from six.moves.urllib.parse import quote
from swift.common.constraints import valid_api_version from swift.common.constraints import valid_api_version
from swift.common.exceptions import MimeInvalid from swift.common.exceptions import MimeInvalid
@ -249,9 +247,7 @@ class FormPost(object):
('Content-Length', str(len(body))))) ('Content-Length', str(len(body)))))
return [body] return [body]
except (FormInvalid, EOFError) as err: except (FormInvalid, EOFError) as err:
body = 'FormPost: %s' % err body = ('FormPost: %s' % err).encode('utf-8')
if six.PY3:
body = body.encode('utf-8')
start_response( start_response(
'400 Bad Request', '400 Bad Request',
(('Content-Type', 'text/plain'), (('Content-Type', 'text/plain'),
@ -273,7 +269,6 @@ class FormPost(object):
:returns: status_line, headers_list, body :returns: status_line, headers_list, body
""" """
keys = self._get_keys(env) keys = self._get_keys(env)
if six.PY3:
boundary = boundary.encode('utf-8') boundary = boundary.encode('utf-8')
status = message = '' status = message = ''
attributes = {} attributes = {}
@ -320,7 +315,6 @@ class FormPost(object):
data += chunk data += chunk
while fp.read(READ_CHUNK_SIZE): while fp.read(READ_CHUNK_SIZE):
pass pass
if six.PY3:
data = data.decode('utf-8') data = data.decode('utf-8')
if 'name' in attrs: if 'name' in attrs:
attributes[attrs['name'].lower()] = data.rstrip('\r\n--') attributes[attrs['name'].lower()] = data.rstrip('\r\n--')
@ -337,7 +331,6 @@ class FormPost(object):
body = status body = status
if message: if message:
body = status + '\r\nFormPost: ' + message.title() body = status + '\r\nFormPost: ' + message.title()
if six.PY3:
body = body.encode('utf-8') body = body.encode('utf-8')
if not is_success(status_code) and resp_body: if not is_success(status_code) and resp_body:
body = resp_body body = resp_body
@ -352,7 +345,6 @@ class FormPost(object):
quote(message)) quote(message))
body = '<html><body><p><a href="%s">' \ body = '<html><body><p><a href="%s">' \
'Click to continue...</a></p></body></html>' % redirect 'Click to continue...</a></p></body></html>' % redirect
if six.PY3:
body = body.encode('utf-8') body = body.encode('utf-8')
headers.extend( headers.extend(
[('Location', redirect), ('Content-Length', str(len(body)))]) [('Location', redirect), ('Content-Length', str(len(body)))])
@ -415,7 +407,6 @@ class FormPost(object):
attributes.get('max_file_size') or '0', attributes.get('max_file_size') or '0',
attributes.get('max_file_count') or '0', attributes.get('max_file_count') or '0',
attributes.get('expires') or '0') attributes.get('expires') or '0')
if six.PY3:
hmac_body = hmac_body.encode('utf-8') hmac_body = hmac_body.encode('utf-8')
has_valid_sig = False has_valid_sig = False
@ -426,13 +417,12 @@ class FormPost(object):
raise FormUnauthorized('invalid signature') raise FormUnauthorized('invalid signature')
if hash_name not in self.allowed_digests: if hash_name not in self.allowed_digests:
raise FormUnauthorized('invalid signature') raise FormUnauthorized('invalid signature')
hash_algorithm = getattr(hashlib, hash_name) if six.PY2 else hash_name
for key in keys: for key in keys:
# Encode key like in swift.common.utls.get_hmac. # Encode key like in swift.common.utls.get_hmac.
if not isinstance(key, six.binary_type): if not isinstance(key, bytes):
key = key.encode('utf8') key = key.encode('utf8')
sig = hmac.new(key, hmac_body, hash_algorithm).hexdigest() sig = hmac.new(key, hmac_body, hash_name).hexdigest()
if streq_const_time(sig, signature): if streq_const_time(sig, signature):
has_valid_sig = True has_valid_sig = True
if not has_valid_sig: if not has_valid_sig:

View File

@ -36,7 +36,7 @@ from swift.common.utils import get_logger, config_true_value
from swift.common.request_helpers import ( from swift.common.request_helpers import (
remove_items, get_sys_meta_prefix, OBJECT_TRANSIENT_SYSMETA_PREFIX remove_items, get_sys_meta_prefix, OBJECT_TRANSIENT_SYSMETA_PREFIX
) )
from six.moves.urllib.parse import urlsplit from urllib.parse import urlsplit
import re import re
#: A list of python regular expressions that will be used to #: A list of python regular expressions that will be used to

View File

@ -80,7 +80,7 @@ environment (everyone can query the locality data using this middleware).
import json import json
from six.moves.urllib.parse import quote, unquote from urllib.parse import quote, unquote
from swift.common.ring import Ring from swift.common.ring import Ring
from swift.common.utils import get_logger, split_path from swift.common.utils import get_logger, split_path

View File

@ -14,7 +14,6 @@
# limitations under the License. # limitations under the License.
import json import json
import six
from xml.etree.cElementTree import Element, SubElement, tostring from xml.etree.cElementTree import Element, SubElement, tostring
from swift.common.constraints import valid_api_version from swift.common.constraints import valid_api_version
@ -84,8 +83,7 @@ def account_to_xml(listing, account_name):
else: else:
sub = SubElement(doc, 'container') sub = SubElement(doc, 'container')
for field in ('name', 'count', 'bytes', 'last_modified'): for field in ('name', 'count', 'bytes', 'last_modified'):
SubElement(sub, field).text = six.text_type( SubElement(sub, field).text = str(record.pop(field))
record.pop(field))
sub.tail = '\n' sub.tail = '\n'
return to_xml(doc) return to_xml(doc)
@ -101,8 +99,7 @@ def container_to_xml(listing, base_name):
sub = SubElement(doc, 'object') sub = SubElement(doc, 'object')
for field in ('name', 'hash', 'bytes', 'content_type', for field in ('name', 'hash', 'bytes', 'content_type',
'last_modified'): 'last_modified'):
SubElement(sub, field).text = six.text_type( SubElement(sub, field).text = str(record.pop(field))
record.pop(field))
return to_xml(doc) return to_xml(doc)
@ -126,8 +123,6 @@ class ListingFilter(object):
for entry in list(listing): for entry in list(listing):
for key in ('name', 'subdir'): for key in ('name', 'subdir'):
value = entry.get(key, '') value = entry.get(key, '')
if six.PY2:
value = value.encode('utf-8')
if RESERVED in value: if RESERVED in value:
if container: if container:
self.logger.warning( self.logger.warning(

View File

@ -16,8 +16,7 @@
from base64 import standard_b64encode as b64encode from base64 import standard_b64encode as b64encode
from base64 import standard_b64decode as b64decode from base64 import standard_b64decode as b64decode
import six from urllib.parse import quote
from six.moves.urllib.parse import quote
from swift.common import swob from swift.common import swob
from swift.common.http import HTTP_OK from swift.common.http import HTTP_OK
@ -145,9 +144,8 @@ class BucketController(Controller):
query['marker'] = swob.wsgi_to_str(req.params['start-after']) query['marker'] = swob.wsgi_to_str(req.params['start-after'])
# continuation-token overrides start-after # continuation-token overrides start-after
if 'continuation-token' in req.params: if 'continuation-token' in req.params:
decoded = b64decode(req.params['continuation-token']) decoded = b64decode(
if not six.PY2: req.params['continuation-token']).decode('utf8')
decoded = decoded.decode('utf8')
query['marker'] = decoded query['marker'] = decoded
if 'fetch-owner' in req.params: if 'fetch-owner' in req.params:
fetch_owner = config_true_value(req.params['fetch-owner']) fetch_owner = config_true_value(req.params['fetch-owner'])

View File

@ -65,17 +65,14 @@ import os
import re import re
import time import time
import six
from swift.common import constraints from swift.common import constraints
from swift.common.swob import Range, bytes_to_wsgi, normalize_etag, \ from swift.common.swob import Range, bytes_to_wsgi, normalize_etag, \
wsgi_to_str wsgi_to_str
from swift.common.utils import json, public, reiterate, md5, Timestamp from swift.common.utils import json, public, reiterate, md5, Timestamp
from swift.common.db import utf8encode
from swift.common.request_helpers import get_container_update_override_key, \ from swift.common.request_helpers import get_container_update_override_key, \
get_param get_param
from six.moves.urllib.parse import quote, urlparse from urllib.parse import quote, urlparse
from swift.common.middleware.s3api.controllers.base import Controller, \ from swift.common.middleware.s3api.controllers.base import Controller, \
bucket_operation, object_operation, check_container_existence bucket_operation, object_operation, check_container_existence
@ -293,8 +290,6 @@ class UploadsController(Controller):
:return (non_delimited_uploads, common_prefixes) :return (non_delimited_uploads, common_prefixes)
""" """
if six.PY2:
(prefix, delimiter) = utf8encode(prefix, delimiter)
non_delimited_uploads = [] non_delimited_uploads = []
common_prefixes = set() common_prefixes = set()
for upload in uploads: for upload in uploads:
@ -363,9 +358,6 @@ class UploadsController(Controller):
new_uploads, prefix, delimiter) new_uploads, prefix, delimiter)
uploads.extend(new_uploads) uploads.extend(new_uploads)
prefixes.extend(new_prefixes) prefixes.extend(new_prefixes)
if six.PY2:
query['marker'] = objects[-1]['name'].encode('utf-8')
else:
query['marker'] = objects[-1]['name'] query['marker'] = objects[-1]['name']
truncated = len(uploads) >= maxuploads truncated = len(uploads) >= maxuploads
@ -542,9 +534,6 @@ class UploadController(Controller):
if not new_objects: if not new_objects:
break break
objects.extend(new_objects) objects.extend(new_objects)
if six.PY2:
query['marker'] = new_objects[-1]['name'].encode('utf-8')
else:
query['marker'] = new_objects[-1]['name'] query['marker'] = new_objects[-1]['name']
last_part = 0 last_part = 0
@ -642,9 +631,6 @@ class UploadController(Controller):
container = req.container_name + MULTIUPLOAD_SUFFIX container = req.container_name + MULTIUPLOAD_SUFFIX
obj = bytes_to_wsgi(o['name'].encode('utf-8')) obj = bytes_to_wsgi(o['name'].encode('utf-8'))
req.get_response(self.app, container=container, obj=obj) req.get_response(self.app, container=container, obj=obj)
if six.PY2:
query['marker'] = objects[-1]['name'].encode('utf-8')
else:
query['marker'] = objects[-1]['name'] query['marker'] = objects[-1]['name']
resp = req.get_response(self.app, 'GET', container, '', resp = req.get_response(self.app, 'GET', container, '',
query=query) query=query)

View File

@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from six.moves.urllib.parse import quote from urllib.parse import quote
from swift.common.utils import public from swift.common.utils import public
from swift.common.middleware.s3api.controllers.base import Controller from swift.common.middleware.s3api.controllers.base import Controller

View File

@ -26,12 +26,11 @@ except ImportError:
else: else:
import importlib.resources import importlib.resources
resource_stream = None resource_stream = None
import six
from swift.common.utils import get_logger from swift.common.utils import get_logger
from swift.common.middleware.s3api.exception import S3Exception from swift.common.middleware.s3api.exception import S3Exception
from swift.common.middleware.s3api.utils import camel_to_snake, \ from swift.common.middleware.s3api.utils import camel_to_snake, \
utf8encode, utf8decode utf8decode
XMLNS_S3 = 'http://s3.amazonaws.com/doc/2006-03-01/' XMLNS_S3 = 'http://s3.amazonaws.com/doc/2006-03-01/'
XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance' XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'
@ -51,7 +50,7 @@ def cleanup_namespaces(elem):
tag = tag[len('{%s}' % ns):] tag = tag[len('{%s}' % ns):]
return tag return tag
if not isinstance(elem.tag, six.string_types): if not isinstance(elem.tag, str):
# elem is a comment element. # elem is a comment element.
return return
@ -136,8 +135,6 @@ class _Element(lxml.etree.ElementBase):
""" """
utf-8 wrapper property of lxml.etree.Element.text utf-8 wrapper property of lxml.etree.Element.text
""" """
if six.PY2:
return utf8encode(lxml.etree.ElementBase.text.__get__(self))
return lxml.etree.ElementBase.text.__get__(self) return lxml.etree.ElementBase.text.__get__(self)
@text.setter @text.setter

View File

@ -144,7 +144,7 @@ https://github.com/swiftstack/s3compat in detail.
from cgi import parse_header from cgi import parse_header
import json import json
from paste.deploy import loadwsgi from paste.deploy import loadwsgi
from six.moves.urllib.parse import parse_qs from urllib.parse import parse_qs
from swift.common.constraints import valid_api_version from swift.common.constraints import valid_api_version
from swift.common.middleware.listing_formats import \ from swift.common.middleware.listing_formats import \

View File

@ -20,9 +20,8 @@ from email.header import Header
from hashlib import sha1, sha256 from hashlib import sha1, sha256
import hmac import hmac
import re import re
import six
# pylint: disable-msg=import-error # pylint: disable-msg=import-error
from six.moves.urllib.parse import quote, unquote, parse_qsl from urllib.parse import quote, unquote, parse_qsl
import string import string
from swift.common.utils import split_path, json, close_if_possible, md5, \ from swift.common.utils import split_path, json, close_if_possible, md5, \
@ -421,7 +420,7 @@ class SigV4Mixin(object):
else: # mostly-functional fallback else: # mostly-functional fallback
headers_lower_dict = dict( headers_lower_dict = dict(
(k.lower().strip(), ' '.join(_header_strip(v or '').split())) (k.lower().strip(), ' '.join(_header_strip(v or '').split()))
for (k, v) in six.iteritems(self.headers)) for (k, v) in self.headers.items())
if 'host' in headers_lower_dict and re.match( if 'host' in headers_lower_dict and re.match(
'Boto/2.[0-9].[0-2]', 'Boto/2.[0-9].[0-2]',
@ -636,9 +635,8 @@ class S3Request(swob.Request):
secret = utf8encode(secret) secret = utf8encode(secret)
user_signature = self.signature user_signature = self.signature
valid_signature = base64.b64encode(hmac.new( valid_signature = base64.b64encode(hmac.new(
secret, self.string_to_sign, sha1).digest()).strip() secret, self.string_to_sign, sha1
if not six.PY2: ).digest()).strip().decode('ascii')
valid_signature = valid_signature.decode('ascii')
return streq_const_time(user_signature, valid_signature) return streq_const_time(user_signature, valid_signature)
@property @property
@ -1488,8 +1486,6 @@ class S3Request(swob.Request):
self.user_id = "%s:%s" % ( self.user_id = "%s:%s" % (
sw_resp.environ['HTTP_X_TENANT_NAME'], sw_resp.environ['HTTP_X_TENANT_NAME'],
sw_resp.environ['HTTP_X_USER_NAME']) sw_resp.environ['HTTP_X_USER_NAME'])
if six.PY2 and not isinstance(self.user_id, bytes):
self.user_id = self.user_id.encode('utf8')
else: else:
# tempauth # tempauth
self.user_id = self.access_key self.user_id = self.access_key
@ -1687,8 +1683,6 @@ class S3AclRequest(S3Request):
# keystone # keystone
self.user_id = "%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'], self.user_id = "%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'],
sw_resp.environ['HTTP_X_USER_NAME']) sw_resp.environ['HTTP_X_USER_NAME'])
if six.PY2 and not isinstance(self.user_id, bytes):
self.user_id = self.user_id.encode('utf8')
else: else:
# tempauth # tempauth
self.user_id = self.access_key self.user_id = self.access_key

View File

@ -14,10 +14,7 @@
# limitations under the License. # limitations under the License.
import re import re
try: from collections.abc import MutableMapping
from collections.abc import MutableMapping
except ImportError:
from collections import MutableMapping # py2
from functools import partial from functools import partial
from swift.common import header_key_dict from swift.common import header_key_dict

View File

@ -61,8 +61,7 @@ from keystoneclient.v3 import client as keystone_client
from keystoneauth1 import session as keystone_session from keystoneauth1 import session as keystone_session
from keystoneauth1 import loading as keystone_loading from keystoneauth1 import loading as keystone_loading
import requests import requests
import six import urllib
from six.moves import urllib
from swift.common.swob import Request, HTTPBadRequest, HTTPUnauthorized, \ from swift.common.swob import Request, HTTPBadRequest, HTTPUnauthorized, \
HTTPException, str_to_wsgi HTTPException, str_to_wsgi
@ -217,9 +216,7 @@ class S3Token(object):
error_msg = ('<?xml version="1.0" encoding="UTF-8"?>\r\n' error_msg = ('<?xml version="1.0" encoding="UTF-8"?>\r\n'
'<Error>\r\n <Code>%s</Code>\r\n ' '<Error>\r\n <Code>%s</Code>\r\n '
'<Message>%s</Message>\r\n</Error>\r\n' % '<Message>%s</Message>\r\n</Error>\r\n' %
(code, message)) (code, message)).encode()
if six.PY3:
error_msg = error_msg.encode()
resp.body = error_msg resp.body = error_msg
return resp return resp
@ -266,18 +263,18 @@ class S3Token(object):
return self._app(environ, start_response) return self._app(environ, start_response)
access = s3_auth_details['access_key'] access = s3_auth_details['access_key']
if isinstance(access, six.binary_type): if isinstance(access, bytes):
access = access.decode('utf-8') access = access.decode('utf-8')
signature = s3_auth_details['signature'] signature = s3_auth_details['signature']
if isinstance(signature, six.binary_type): if isinstance(signature, bytes):
signature = signature.decode('utf-8') signature = signature.decode('utf-8')
string_to_sign = s3_auth_details['string_to_sign'] string_to_sign = s3_auth_details['string_to_sign']
if isinstance(string_to_sign, six.text_type): if isinstance(string_to_sign, str):
string_to_sign = string_to_sign.encode('utf-8') string_to_sign = string_to_sign.encode('utf-8')
token = base64.urlsafe_b64encode(string_to_sign) token = base64.urlsafe_b64encode(string_to_sign)
if isinstance(token, six.binary_type): if isinstance(token, bytes):
token = token.decode('ascii') token = token.decode('ascii')
# NOTE(chmou): This is to handle the special case with nova # NOTE(chmou): This is to handle the special case with nova
@ -399,8 +396,6 @@ class S3Token(object):
req.headers.update(headers) req.headers.update(headers)
tenant_to_connect = force_tenant or tenant['id'] tenant_to_connect = force_tenant or tenant['id']
if six.PY2 and isinstance(tenant_to_connect, six.text_type):
tenant_to_connect = tenant_to_connect.encode('utf-8')
self._logger.debug('Connecting with tenant: %s', tenant_to_connect) self._logger.debug('Connecting with tenant: %s', tenant_to_connect)
new_tenant_name = '%s%s' % (self._reseller_prefix, tenant_to_connect) new_tenant_name = '%s%s' % (self._reseller_prefix, tenant_to_connect)
environ['PATH_INFO'] = environ['PATH_INFO'].replace( environ['PATH_INFO'] = environ['PATH_INFO'].replace(

View File

@ -43,8 +43,6 @@ http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
""" """
from functools import partial from functools import partial
import six
from swift.common.utils import json from swift.common.utils import json
from swift.common.middleware.s3api.s3response import InvalidArgument, \ from swift.common.middleware.s3api.s3response import InvalidArgument, \
@ -233,7 +231,7 @@ class Owner(object):
""" """
def __init__(self, id, name): def __init__(self, id, name):
self.id = id self.id = id
if not (name is None or isinstance(name, six.string_types)): if not (name is None or isinstance(name, str)):
raise TypeError('name must be a string or None') raise TypeError('name must be a string or None')
self.name = name self.name = name
@ -429,8 +427,6 @@ class ACL(object):
return tostring(self.elem()) return tostring(self.elem())
def __repr__(self): def __repr__(self):
if six.PY2:
return self.__bytes__()
return self.__bytes__().decode('utf8') return self.__bytes__().decode('utf8')
@classmethod @classmethod

View File

@ -18,7 +18,6 @@ import calendar
import datetime import datetime
import email.utils import email.utils
import re import re
import six
import time import time
import uuid import uuid
@ -54,8 +53,6 @@ def snake_to_camel(snake):
def unique_id(): def unique_id():
result = base64.urlsafe_b64encode(str(uuid.uuid4()).encode('ascii')) result = base64.urlsafe_b64encode(str(uuid.uuid4()).encode('ascii'))
if six.PY2:
return result
return result.decode('ascii') return result.decode('ascii')

View File

@ -347,8 +347,6 @@ import mimetypes
import re import re
import time import time
import six
from swift.cli.container_deleter import make_delete_jobs from swift.cli.container_deleter import make_delete_jobs
from swift.common.header_key_dict import HeaderKeyDict from swift.common.header_key_dict import HeaderKeyDict
from swift.common.exceptions import ListingIterError, SegmentError from swift.common.exceptions import ListingIterError, SegmentError
@ -361,7 +359,7 @@ from swift.common.swob import Request, HTTPBadRequest, HTTPServerError, \
HTTPServiceUnavailable, Response, Range, normalize_etag, \ HTTPServiceUnavailable, Response, Range, normalize_etag, \
RESPONSE_REASONS, str_to_wsgi, bytes_to_wsgi, wsgi_to_str, wsgi_quote RESPONSE_REASONS, str_to_wsgi, bytes_to_wsgi, wsgi_to_str, wsgi_quote
from swift.common.utils import get_logger, config_true_value, \ from swift.common.utils import get_logger, config_true_value, \
get_valid_utf8_str, override_bytes_from_content_type, split_path, \ override_bytes_from_content_type, split_path, \
RateLimitedIterator, quote, closing_if_possible, \ RateLimitedIterator, quote, closing_if_possible, \
LRUCache, StreamingPile, strict_b64decode, Timestamp, friendly_close, \ LRUCache, StreamingPile, strict_b64decode, Timestamp, friendly_close, \
get_expirer_container, md5 get_expirer_container, md5
@ -462,12 +460,12 @@ def parse_and_validate_input(req_body, req_path):
continue continue
if segment_type == 'path': if segment_type == 'path':
if not isinstance(seg_dict['path'], six.string_types): if not isinstance(seg_dict['path'], str):
errors.append(b"Index %d: \"path\" must be a string" % errors.append(b"Index %d: \"path\" must be a string" %
seg_index) seg_index)
continue continue
if not (seg_dict.get('etag') is None or if not (seg_dict.get('etag') is None or
isinstance(seg_dict['etag'], six.string_types)): isinstance(seg_dict['etag'], str)):
errors.append(b'Index %d: "etag" must be a string or null ' errors.append(b'Index %d: "etag" must be a string or null '
b'(if provided)' % seg_index) b'(if provided)' % seg_index)
continue continue
@ -761,9 +759,7 @@ class SloGetContext(WSGIContext):
if not sub_resp.is_success: if not sub_resp.is_success:
# Error message should be short # Error message should be short
body = sub_resp.body body = sub_resp.body.decode('utf-8')
if not six.PY2:
body = body.decode('utf-8')
msg = ('while fetching %s, GET of submanifest %s ' msg = ('while fetching %s, GET of submanifest %s '
'failed with status %d (%s)') 'failed with status %d (%s)')
raise ListingIterError(msg % ( raise ListingIterError(msg % (
@ -873,9 +869,6 @@ class SloGetContext(WSGIContext):
"While processing manifest %r, " "While processing manifest %r, "
"max recursion depth was exceeded" % req.path) "max recursion depth was exceeded" % req.path)
if six.PY2:
sub_path = get_valid_utf8_str(seg_dict['name'])
else:
sub_path = seg_dict['name'] sub_path = seg_dict['name']
sub_cont, sub_obj = split_path(sub_path, 2, 2, True) sub_cont, sub_obj = split_path(sub_path, 2, 2, True)
if last_sub_path != sub_path: if last_sub_path != sub_path:
@ -895,8 +888,6 @@ class SloGetContext(WSGIContext):
recursion_depth=recursion_depth + 1): recursion_depth=recursion_depth + 1):
yield sub_seg_dict yield sub_seg_dict
else: else:
if six.PY2 and isinstance(seg_dict['name'], six.text_type):
seg_dict['name'] = seg_dict['name'].encode("utf-8")
yield dict(seg_dict, yield dict(seg_dict,
first_byte=max(0, first_byte) + range_start, first_byte=max(0, first_byte) + range_start,
last_byte=min(range_end, range_start + last_byte)) last_byte=min(range_end, range_start + last_byte))
@ -1211,9 +1202,7 @@ class SloGetContext(WSGIContext):
seg_dict['etag'] = seg_dict.pop('hash', None) seg_dict['etag'] = seg_dict.pop('hash', None)
json_data = json.dumps(segments, sort_keys=True) # convert to string json_data = json.dumps(segments, sort_keys=True) # convert to string
if six.PY3: return json_data.encode('utf-8')
json_data = json_data.encode('utf-8')
return json_data
def _get_manifest_read(self, resp_iter): def _get_manifest_read(self, resp_iter):
with closing_if_possible(resp_iter): with closing_if_possible(resp_iter):
@ -1402,10 +1391,6 @@ class StaticLargeObject(object):
path2indices[seg_dict['path']].append(index) path2indices[seg_dict['path']].append(index)
def do_head(obj_name): def do_head(obj_name):
if six.PY2:
obj_path = '/'.join(['', vrs, account,
get_valid_utf8_str(obj_name).lstrip('/')])
else:
obj_path = '/'.join(['', vrs, account, obj_path = '/'.join(['', vrs, account,
str_to_wsgi(obj_name.lstrip('/'))]) str_to_wsgi(obj_name.lstrip('/'))])
obj_path = wsgi_quote(obj_path) obj_path = wsgi_quote(obj_path)
@ -1559,7 +1544,7 @@ class StaticLargeObject(object):
r = '%s:%s;' % (seg_data['hash'], seg_data['range']) r = '%s:%s;' % (seg_data['hash'], seg_data['range'])
else: else:
r = seg_data['hash'] r = seg_data['hash']
slo_etag.update(r.encode('ascii') if six.PY3 else r) slo_etag.update(r.encode('ascii'))
slo_etag = slo_etag.hexdigest() slo_etag = slo_etag.hexdigest()
client_etag = normalize_etag(req.headers.get('Etag')) client_etag = normalize_etag(req.headers.get('Etag'))
@ -1569,7 +1554,7 @@ class StaticLargeObject(object):
resp_dict = {} resp_dict = {}
resp_dict['Response Status'] = err.status resp_dict['Response Status'] = err.status
err_body = err.body err_body = err.body
if six.PY3 and isinstance(err_body, bytes): if isinstance(err_body, bytes):
err_body = err_body.decode('utf-8', errors='replace') err_body = err_body.decode('utf-8', errors='replace')
resp_dict['Response Body'] = err_body or '\n'.join( resp_dict['Response Body'] = err_body or '\n'.join(
RESPONSE_REASONS.get(err.status_int, [''])) RESPONSE_REASONS.get(err.status_int, ['']))
@ -1581,9 +1566,7 @@ class StaticLargeObject(object):
yield chunk yield chunk
return return
json_data = json.dumps(data_for_storage) json_data = json.dumps(data_for_storage).encode('utf-8')
if six.PY3:
json_data = json_data.encode('utf-8')
req.body = json_data req.body = json_data
req.headers.update({ req.headers.update({
SYSMETA_SLO_ETAG: slo_etag, SYSMETA_SLO_ETAG: slo_etag,
@ -1618,7 +1601,7 @@ class StaticLargeObject(object):
if heartbeat: if heartbeat:
resp_body = resp.body resp_body = resp.body
if six.PY3 and isinstance(resp_body, bytes): if isinstance(resp_body, bytes):
resp_body = resp_body.decode('utf-8') resp_body = resp_body.decode('utf-8')
resp_dict['Response Body'] = resp_body resp_dict['Response Body'] = resp_body
yield separator + get_response_body( yield separator + get_response_body(
@ -1644,9 +1627,6 @@ class StaticLargeObject(object):
raise HTTPPreconditionFailed( raise HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL') request=req, body='Invalid UTF8 or contains NULL')
vrs, account, container, obj = req.split_path(4, 4, True) vrs, account, container, obj = req.split_path(4, 4, True)
if six.PY2:
obj_path = ('/%s/%s' % (container, obj)).decode('utf-8')
else:
obj_path = '/%s/%s' % (wsgi_to_str(container), wsgi_to_str(obj)) obj_path = '/%s/%s' % (wsgi_to_str(container), wsgi_to_str(obj))
segments = [{ segments = [{
@ -1675,7 +1655,7 @@ class StaticLargeObject(object):
except HTTPException as err: except HTTPException as err:
# allow bulk delete response to report errors # allow bulk delete response to report errors
err_body = err.body err_body = err.body
if six.PY3 and isinstance(err_body, bytes): if isinstance(err_body, bytes):
err_body = err_body.decode('utf-8', errors='replace') err_body = err_body.decode('utf-8', errors='replace')
seg_data['error'] = {'code': err.status_int, seg_data['error'] = {'code': err.status_int,
'message': err_body} 'message': err_body}
@ -1684,8 +1664,6 @@ class StaticLargeObject(object):
seg_data['sub_slo'] = False seg_data['sub_slo'] = False
segments.append(seg_data) segments.append(seg_data)
else: else:
if six.PY2:
seg_data['name'] = seg_data['name'].encode('utf-8')
yield seg_data yield seg_data
def get_slo_segments(self, obj_name, req): def get_slo_segments(self, obj_name, req):
@ -1714,12 +1692,6 @@ class StaticLargeObject(object):
new_env['HTTP_USER_AGENT'] = \ new_env['HTTP_USER_AGENT'] = \
'%s MultipartDELETE' % new_env.get('HTTP_USER_AGENT') '%s MultipartDELETE' % new_env.get('HTTP_USER_AGENT')
new_env['swift.source'] = 'SLO' new_env['swift.source'] = 'SLO'
if six.PY2:
new_env['PATH_INFO'] = (
'/%s/%s/%s' % (vrs, account,
obj_name.lstrip('/').encode('utf-8'))
)
else:
new_env['PATH_INFO'] = ( new_env['PATH_INFO'] = (
'/%s/%s/%s' % (vrs, account, str_to_wsgi(obj_name.lstrip('/'))) '/%s/%s/%s' % (vrs, account, str_to_wsgi(obj_name.lstrip('/')))
) )
@ -1757,9 +1729,6 @@ class StaticLargeObject(object):
raise HTTPPreconditionFailed( raise HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL') request=req, body='Invalid UTF8 or contains NULL')
vrs, account, container, obj = req.split_path(4, 4, True) vrs, account, container, obj = req.split_path(4, 4, True)
if six.PY2:
obj_path = ('/%s/%s' % (container, obj)).decode('utf-8')
else:
obj_path = '/%s/%s' % (wsgi_to_str(container), wsgi_to_str(obj)) obj_path = '/%s/%s' % (wsgi_to_str(container), wsgi_to_str(obj))
segments = [seg for seg in self.get_slo_segments(obj_path, req) segments = [seg for seg in self.get_slo_segments(obj_path, req)
if 'data' not in seg] if 'data' not in seg]

View File

@ -135,13 +135,12 @@ Example usage of this middleware via ``swift``:
""" """
import html
import json import json
import six
import time import time
from six.moves.urllib.parse import urlparse from urllib.parse import urlparse
from swift.common.request_helpers import html_escape
from swift.common.utils import human_readable, split_path, config_true_value, \ from swift.common.utils import human_readable, split_path, config_true_value, \
quote, get_logger quote, get_logger
from swift.common.registry import register_swift_info from swift.common.registry import register_swift_info
@ -256,7 +255,7 @@ class _StaticWebContext(WSGIContext):
body = '<!DOCTYPE html>\n' \ body = '<!DOCTYPE html>\n' \
'<html>\n' \ '<html>\n' \
'<head>\n' \ '<head>\n' \
'<title>Listing of %s</title>\n' % html_escape(label) '<title>Listing of %s</title>\n' % html.escape(label)
if self._listings_css: if self._listings_css:
body += ' <link rel="stylesheet" type="text/css" ' \ body += ' <link rel="stylesheet" type="text/css" ' \
'href="%s" />\n' % self._build_css_path(prefix or '') 'href="%s" />\n' % self._build_css_path(prefix or '')
@ -322,7 +321,7 @@ class _StaticWebContext(WSGIContext):
'<html>\n' \ '<html>\n' \
' <head>\n' \ ' <head>\n' \
' <title>Listing of %s</title>\n' % \ ' <title>Listing of %s</title>\n' % \
html_escape(label) html.escape(label)
if self._listings_css: if self._listings_css:
body += ' <link rel="stylesheet" type="text/css" ' \ body += ' <link rel="stylesheet" type="text/css" ' \
'href="%s" />\n' % (self._build_css_path(prefix)) 'href="%s" />\n' % (self._build_css_path(prefix))
@ -341,7 +340,7 @@ class _StaticWebContext(WSGIContext):
' <th class="colname">Name</th>\n' \ ' <th class="colname">Name</th>\n' \
' <th class="colsize">Size</th>\n' \ ' <th class="colsize">Size</th>\n' \
' <th class="coldate">Date</th>\n' \ ' <th class="coldate">Date</th>\n' \
' </tr>\n' % html_escape(label) ' </tr>\n' % html.escape(label)
if len(prefix) > len(tempurl_prefix): if len(prefix) > len(tempurl_prefix):
body += ' <tr id="parent" class="item">\n' \ body += ' <tr id="parent" class="item">\n' \
' <td class="colname"><a href="../%s">../</a></td>\n' \ ' <td class="colname"><a href="../%s">../</a></td>\n' \
@ -350,8 +349,7 @@ class _StaticWebContext(WSGIContext):
' </tr>\n' % tempurl_qs ' </tr>\n' % tempurl_qs
for item in listing: for item in listing:
if 'subdir' in item: if 'subdir' in item:
subdir = item['subdir'] if six.PY3 else \ subdir = item['subdir']
item['subdir'].encode('utf-8')
if prefix: if prefix:
subdir = subdir[len(wsgi_to_str(prefix)):] subdir = subdir[len(wsgi_to_str(prefix)):]
body += ' <tr class="item subdir">\n' \ body += ' <tr class="item subdir">\n' \
@ -359,28 +357,25 @@ class _StaticWebContext(WSGIContext):
' <td class="colsize">&nbsp;</td>\n' \ ' <td class="colsize">&nbsp;</td>\n' \
' <td class="coldate">&nbsp;</td>\n' \ ' <td class="coldate">&nbsp;</td>\n' \
' </tr>\n' % \ ' </tr>\n' % \
(quote(subdir) + tempurl_qs, html_escape(subdir)) (quote(subdir) + tempurl_qs, html.escape(subdir))
for item in listing: for item in listing:
if 'name' in item: if 'name' in item:
name = item['name'] if six.PY3 else \ name = item['name']
item['name'].encode('utf-8')
if prefix: if prefix:
name = name[len(wsgi_to_str(prefix)):] name = name[len(wsgi_to_str(prefix)):]
content_type = item['content_type'] if six.PY3 else \ content_type = item['content_type']
item['content_type'].encode('utf-8')
bytes = human_readable(item['bytes']) bytes = human_readable(item['bytes'])
last_modified = ( last_modified = (
html_escape(item['last_modified'] if six.PY3 else html.escape(item['last_modified']).
item['last_modified'].encode('utf-8')).
split('.')[0].replace('T', ' ')) split('.')[0].replace('T', ' '))
body += ' <tr class="item %s">\n' \ body += ' <tr class="item %s">\n' \
' <td class="colname"><a href="%s">%s</a></td>\n' \ ' <td class="colname"><a href="%s">%s</a></td>\n' \
' <td class="colsize">%s</td>\n' \ ' <td class="colsize">%s</td>\n' \
' <td class="coldate">%s</td>\n' \ ' <td class="coldate">%s</td>\n' \
' </tr>\n' % \ ' </tr>\n' % \
(' '.join('type-' + html_escape(t.lower()) (' '.join('type-' + html.escape(t.lower())
for t in content_type.split('/')), for t in content_type.split('/')),
quote(name) + tempurl_qs, html_escape(name), quote(name) + tempurl_qs, html.escape(name),
bytes, last_modified) bytes, last_modified)
body += ' </table>\n' \ body += ' </table>\n' \
' </body>\n' \ ' </body>\n' \

View File

@ -182,7 +182,6 @@ from uuid import uuid4
import base64 import base64
from eventlet import Timeout from eventlet import Timeout
import six
from swift.common.memcached import MemcacheConnectionError from swift.common.memcached import MemcacheConnectionError
from swift.common.swob import ( from swift.common.swob import (
Response, Request, wsgi_to_str, str_to_wsgi, wsgi_unquote, Response, Request, wsgi_to_str, str_to_wsgi, wsgi_unquote,
@ -246,12 +245,9 @@ class TempAuth(object):
# Because trailing equal signs would screw up config file # Because trailing equal signs would screw up config file
# parsing, we auto-pad with '=' chars. # parsing, we auto-pad with '=' chars.
account += '=' * (len(account) % 4) account += '=' * (len(account) % 4)
account = base64.b64decode(account) account = base64.b64decode(account).decode('utf8')
username += '=' * (len(username) % 4) username += '=' * (len(username) % 4)
username = base64.b64decode(username) username = base64.b64decode(username).decode('utf8')
if not six.PY2:
account = account.decode('utf8')
username = username.decode('utf8')
values = conf[conf_key].split() values = conf[conf_key].split()
if not values: if not values:
raise ValueError('%s has no key set' % conf_key) raise ValueError('%s has no key set' % conf_key)
@ -451,8 +447,6 @@ class TempAuth(object):
expires, groups = cached_auth_data expires, groups = cached_auth_data
if expires < time(): if expires < time():
groups = None groups = None
elif six.PY2:
groups = groups.encode('utf8')
s3_auth_details = env.get('s3api.auth_details') or\ s3_auth_details = env.get('s3api.auth_details') or\
env.get('swift3.auth_details') env.get('swift3.auth_details')
@ -530,7 +524,7 @@ class TempAuth(object):
if not isinstance(result[key], list): if not isinstance(result[key], list):
return "Value for key %s must be a list" % json.dumps(key) return "Value for key %s must be a list" % json.dumps(key)
for grantee in result[key]: for grantee in result[key]:
if not isinstance(grantee, six.string_types): if not isinstance(grantee, str):
return "Elements of %s list must be strings" % json.dumps( return "Elements of %s list must be strings" % json.dumps(
key) key)
@ -838,8 +832,7 @@ class TempAuth(object):
cached_auth_data = memcache_client.get(memcache_token_key) cached_auth_data = memcache_client.get(memcache_token_key)
if cached_auth_data: if cached_auth_data:
expires, old_groups = cached_auth_data expires, old_groups = cached_auth_data
old_groups = [group.encode('utf8') if six.PY2 else group old_groups = [group for group in old_groups.split(',')]
for group in old_groups.split(',')]
new_groups = self._get_user_groups(account, account_user, new_groups = self._get_user_groups(account, account_user,
account_id) account_id)

View File

@ -299,13 +299,11 @@ __all__ = ['TempURL', 'filter_factory',
'DEFAULT_OUTGOING_ALLOW_HEADERS'] 'DEFAULT_OUTGOING_ALLOW_HEADERS']
from calendar import timegm from calendar import timegm
import six
from os.path import basename from os.path import basename
from time import time, strftime, strptime, gmtime from time import time, strftime, strptime, gmtime
from ipaddress import ip_address, ip_network from ipaddress import ip_address, ip_network
from six.moves.urllib.parse import parse_qs from urllib.parse import parse_qs, urlencode
from six.moves.urllib.parse import urlencode
from swift.proxy.controllers.base import get_account_info, get_container_info from swift.proxy.controllers.base import get_account_info, get_container_info
from swift.common.header_key_dict import HeaderKeyDict from swift.common.header_key_dict import HeaderKeyDict
@ -314,7 +312,7 @@ from swift.common.digest import get_allowed_digests, \
extract_digest_and_algorithm, DEFAULT_ALLOWED_DIGESTS, get_hmac extract_digest_and_algorithm, DEFAULT_ALLOWED_DIGESTS, get_hmac
from swift.common.swob import header_to_environ_key, HTTPUnauthorized, \ from swift.common.swob import header_to_environ_key, HTTPUnauthorized, \
HTTPBadRequest, wsgi_to_str HTTPBadRequest, wsgi_to_str
from swift.common.utils import split_path, get_valid_utf8_str, \ from swift.common.utils import split_path, \
streq_const_time, quote, get_logger, close_if_possible streq_const_time, quote, get_logger, close_if_possible
from swift.common.registry import register_swift_info, register_sensitive_param from swift.common.registry import register_swift_info, register_sensitive_param
from swift.common.wsgi import WSGIContext from swift.common.wsgi import WSGIContext
@ -361,8 +359,7 @@ def get_tempurl_keys_from_metadata(meta):
meta = get_account_info(...)['meta'] meta = get_account_info(...)['meta']
keys = get_tempurl_keys_from_metadata(meta) keys = get_tempurl_keys_from_metadata(meta)
""" """
return [(get_valid_utf8_str(value) if six.PY2 else value) return [value for key, value in meta.items()
for key, value in meta.items()
if key.lower() in ('temp-url-key', 'temp-url-key-2')] if key.lower() in ('temp-url-key', 'temp-url-key-2')]
@ -575,8 +572,8 @@ class TempURL(object):
if client_address is None: if client_address is None:
return self._invalid(env, start_response) return self._invalid(env, start_response)
try: try:
allowed_ip_ranges = ip_network(six.u(temp_url_ip_range)) allowed_ip_ranges = ip_network(str(temp_url_ip_range))
if ip_address(six.u(client_address)) not in allowed_ip_ranges: if ip_address(str(client_address)) not in allowed_ip_ranges:
return self._invalid(env, start_response) return self._invalid(env, start_response)
except ValueError: except ValueError:
return self._invalid(env, start_response) return self._invalid(env, start_response)

View File

@ -145,11 +145,10 @@ the option ``allow_object_versioning`` to ``True``.
import calendar import calendar
import itertools import itertools
import json import json
import six
import time import time
from cgi import parse_header from cgi import parse_header
from six.moves.urllib.parse import unquote from urllib.parse import unquote
from swift.common.constraints import MAX_FILE_SIZE, valid_api_version, \ from swift.common.constraints import MAX_FILE_SIZE, valid_api_version, \
ACCOUNT_LISTING_LIMIT, CONTAINER_LISTING_LIMIT ACCOUNT_LISTING_LIMIT, CONTAINER_LISTING_LIMIT
@ -1190,7 +1189,6 @@ class ContainerContext(ObjectVersioningContext):
name, ts = self._split_version_from_name(linked_name) name, ts = self._split_version_from_name(linked_name)
if ts is None: if ts is None:
continue continue
name = name.decode('utf8') if six.PY2 else name
is_latest = False is_latest = False
if name not in is_latest_set: if name not in is_latest_set:
is_latest_set.add(name) is_latest_set.add(name)
@ -1231,8 +1229,7 @@ class ContainerContext(ObjectVersioningContext):
path = '/v1/%s/%s/%s' % ( path = '/v1/%s/%s/%s' % (
wsgi_to_str(account), wsgi_to_str(account),
wsgi_to_str(location), wsgi_to_str(location),
item['name'].encode('utf8') item['name'])
if six.PY2 else item['name'])
if path in current_versions: if path in current_versions:
item['is_latest'] = True item['is_latest'] = True
@ -1260,7 +1257,7 @@ class ContainerContext(ObjectVersioningContext):
if ts is None: if ts is None:
continue continue
broken_listing.append({ broken_listing.append({
'name': name.decode('utf8') if six.PY2 else name, 'name': name,
'is_latest': True, 'is_latest': True,
'version_id': ts.internal, 'version_id': ts.internal,
'content_type': item['content_type'], 'content_type': item['content_type'],

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import html
import os import os
import random import random
import re import re
@ -26,7 +27,6 @@ from swift.common.middleware.x_profile.exceptions import MethodNotAllowed
from swift.common.middleware.x_profile.exceptions import DataLoadFailure from swift.common.middleware.x_profile.exceptions import DataLoadFailure
from swift.common.middleware.x_profile.exceptions import ProfileException from swift.common.middleware.x_profile.exceptions import ProfileException
from swift.common.middleware.x_profile.profile_model import Stats2 from swift.common.middleware.x_profile.profile_model import Stats2
from swift.common.request_helpers import html_escape
PLOTLIB_INSTALLED = True PLOTLIB_INSTALLED = True
try: try:
@ -453,7 +453,7 @@ class HTMLViewer(object):
fmt = '<span id="L%d" rel="#L%d">%' + max_width\ fmt = '<span id="L%d" rel="#L%d">%' + max_width\
+ 'd|<code>%s</code></span>' + 'd|<code>%s</code></span>'
for line in lines: for line in lines:
el = html_escape(line) el = html.escape(line)
i = i + 1 i = i + 1
if i == lineno: if i == lineno:
fmt2 = '<span id="L%d" style="background-color: \ fmt2 = '<span id="L%d" style="background-color: \
@ -517,7 +517,7 @@ class HTMLViewer(object):
html.append('<td>-</td>') html.append('<td>-</td>')
else: else:
html.append('<td>%f</td>' % (float(ct) / cc)) html.append('<td>%f</td>' % (float(ct) / cc))
nfls = html_escape(stats.func_std_string(func)) nfls = html.escape(stats.func_std_string(func))
if nfls.split(':')[0] not in ['', 'profile'] and\ if nfls.split(':')[0] not in ['', 'profile'] and\
os.path.isfile(nfls.split(':')[0]): os.path.isfile(nfls.split(':')[0]):
html.append('<td><a href="%s/%s%s?format=python#L%d">\ html.append('<td><a href="%s/%s%s?format=python#L%d">\

View File

@ -85,8 +85,7 @@ import time
from eventlet import greenthread, GreenPool, patcher from eventlet import greenthread, GreenPool, patcher
import eventlet.green.profile as eprofile import eventlet.green.profile as eprofile
import six import urllib
from six.moves import urllib
from swift.common.utils import get_logger, config_true_value from swift.common.utils import get_logger, config_true_value
from swift.common.swob import Request from swift.common.swob import Request
@ -112,10 +111,7 @@ PROFILE_EXEC_LAZY = """
app_iter_ = self.app(environ, start_response) app_iter_ = self.app(environ, start_response)
""" """
if six.PY3: thread = patcher.original('_thread') # non-monkeypatched module needed
thread = patcher.original('_thread') # non-monkeypatched module needed
else:
thread = patcher.original('thread') # non-monkeypatched module needed
# This monkey patch code fix the problem of eventlet profile tool # This monkey patch code fix the problem of eventlet profile tool
@ -217,7 +213,7 @@ class ProfileMiddleware(object):
query_dict, query_dict,
self.renew_profile) self.renew_profile)
start_response('200 OK', headers) start_response('200 OK', headers)
if isinstance(content, six.text_type): if isinstance(content, str):
content = content.encode('utf-8') content = content.encode('utf-8')
return [content] return [content]
except MethodNotAllowed as mx: except MethodNotAllowed as mx:

View File

@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import six
RECON_RELINKER_FILE = 'relinker.recon' RECON_RELINKER_FILE = 'relinker.recon'
RECON_OBJECT_FILE = 'object.recon' RECON_OBJECT_FILE = 'object.recon'
RECON_CONTAINER_FILE = 'container.recon' RECON_CONTAINER_FILE = 'container.recon'
@ -24,7 +22,7 @@ DEFAULT_RECON_CACHE_PATH = '/var/cache/swift'
def server_type_to_recon_file(server_type): def server_type_to_recon_file(server_type):
if not isinstance(server_type, six.string_types) or \ if not isinstance(server_type, str) or \
server_type.lower() not in ('account', 'container', 'object'): server_type.lower() not in ('account', 'container', 'object'):
raise ValueError('Invalid server_type') raise ValueError('Invalid server_type')
return "%s.recon" % server_type.lower() return "%s.recon" % server_type.lower()

View File

@ -16,7 +16,6 @@
# Used by get_swift_info and register_swift_info to store information about # Used by get_swift_info and register_swift_info to store information about
# the swift cluster. # the swift cluster.
from copy import deepcopy from copy import deepcopy
import six
_swift_info = {} _swift_info = {}
_swift_admin_info = {} _swift_admin_info = {}
@ -115,9 +114,6 @@ def register_sensitive_header(header):
""" """
if not isinstance(header, str): if not isinstance(header, str):
raise TypeError raise TypeError
if six.PY2:
header.decode('ascii')
else:
header.encode('ascii') header.encode('ascii')
_sensitive_headers.add(header.lower()) _sensitive_headers.add(header.lower())
@ -147,8 +143,5 @@ def register_sensitive_param(query_param):
""" """
if not isinstance(query_param, str): if not isinstance(query_param, str):
raise TypeError raise TypeError
if six.PY2:
query_param.decode('ascii')
else:
query_param.encode('ascii') query_param.encode('ascii')
_sensitive_params.add(query_param) _sensitive_params.add(query_param)

View File

@ -21,10 +21,8 @@ from swob in here without creating circular imports.
""" """
import itertools import itertools
import sys
import time import time
import six
from swift.common.header_key_dict import HeaderKeyDict from swift.common.header_key_dict import HeaderKeyDict
from swift.common.constraints import AUTO_CREATE_ACCOUNT_PREFIX, \ from swift.common.constraints import AUTO_CREATE_ACCOUNT_PREFIX, \
@ -51,15 +49,6 @@ USE_REPLICATION_NETWORK_HEADER = 'x-backend-use-replication-network'
MISPLACED_OBJECTS_ACCOUNT = '.misplaced_objects' MISPLACED_OBJECTS_ACCOUNT = '.misplaced_objects'
if six.PY2:
import cgi
def html_escape(s, quote=True):
return cgi.escape(s, quote=quote)
else:
from html import escape as html_escape # noqa: F401
def get_param(req, name, default=None): def get_param(req, name, default=None):
""" """
Get a parameter from an HTTP request ensuring proper handling UTF-8 Get a parameter from an HTTP request ensuring proper handling UTF-8
@ -68,20 +57,10 @@ def get_param(req, name, default=None):
:param req: request object :param req: request object
:param name: parameter name :param name: parameter name
:param default: result to return if the parameter is not found :param default: result to return if the parameter is not found
:returns: HTTP request parameter value, as a native string :returns: HTTP request parameter value, as a native (not WSGI) string
(in py2, as UTF-8 encoded str, not unicode object)
:raises HTTPBadRequest: if param not valid UTF-8 byte sequence :raises HTTPBadRequest: if param not valid UTF-8 byte sequence
""" """
value = req.params.get(name, default) value = req.params.get(name, default)
if six.PY2:
if value and not isinstance(value, six.text_type):
try:
value.decode('utf8') # Ensure UTF8ness
except UnicodeDecodeError:
raise HTTPBadRequest(
request=req, content_type='text/plain',
body='"%s" parameter not valid UTF-8' % name)
else:
if value: if value:
# req.params is a dict of WSGI strings, so encoding will succeed # req.params is a dict of WSGI strings, so encoding will succeed
value = value.encode('latin1') value = value.encode('latin1')
@ -606,11 +585,10 @@ class SegmentedIterable(object):
pending_etag = seg_etag pending_etag = seg_etag
pending_size = seg_size pending_size = seg_size
except ListingIterError: except ListingIterError as e:
e_type, e_value, e_traceback = sys.exc_info()
if pending_req: if pending_req:
yield pending_req, pending_etag, pending_size yield pending_req, pending_etag, pending_size
six.reraise(e_type, e_value, e_traceback) raise e
if pending_req: if pending_req:
yield pending_req, pending_etag, pending_size yield pending_req, pending_etag, pending_size
@ -629,9 +607,7 @@ class SegmentedIterable(object):
seg_resp = seg_req.get_response(self.app) seg_resp = seg_req.get_response(self.app)
if not is_success(seg_resp.status_int): if not is_success(seg_resp.status_int):
# Error body should be short # Error body should be short
body = seg_resp.body body = seg_resp.body.decode('utf8')
if not six.PY2:
body = body.decode('utf8')
msg = 'While processing manifest %s, got %d (%s) ' \ msg = 'While processing manifest %s, got %d (%s) ' \
'while retrieving %s' % ( 'while retrieving %s' % (
self.name, seg_resp.status_int, self.name, seg_resp.status_int,

View File

@ -22,14 +22,12 @@ import math
import random import random
import uuid import uuid
import six.moves.cPickle as pickle import pickle # nosec: B403
from copy import deepcopy from copy import deepcopy
from contextlib import contextmanager from contextlib import contextmanager
from array import array from array import array
from collections import defaultdict from collections import defaultdict
import six
from six.moves import range
from time import time from time import time
from swift.common import exceptions from swift.common import exceptions
@ -646,8 +644,7 @@ class RingBuilder(object):
dispersion_graph = {} dispersion_graph = {}
# go over all the devices holding each replica part by part # go over all the devices holding each replica part by part
for part_id, dev_ids in enumerate( for part_id, dev_ids in enumerate(zip(*self._replica2part2dev)):
six.moves.zip(*self._replica2part2dev)):
# count the number of replicas of this part for each tier of each # count the number of replicas of this part for each tier of each
# device, some devices may have overlapping tiers! # device, some devices may have overlapping tiers!
replicas_at_tier = defaultdict(int) replicas_at_tier = defaultdict(int)
@ -1741,7 +1738,7 @@ class RingBuilder(object):
else: else:
with fp: with fp:
try: try:
builder = pickle.load(fp) builder = pickle.load(fp) # nosec: B301
except Exception: except Exception:
# raise error during unpickling as UnPicklingError # raise error during unpickling as UnPicklingError
raise exceptions.UnPicklingError( raise exceptions.UnPicklingError(

View File

@ -16,7 +16,7 @@
import array import array
import contextlib import contextlib
import six.moves.cPickle as pickle import pickle # nosec: B403
import json import json
from collections import defaultdict from collections import defaultdict
from gzip import GzipFile from gzip import GzipFile
@ -29,9 +29,6 @@ from tempfile import NamedTemporaryFile
import sys import sys
import zlib import zlib
import six
from six.moves import range
from swift.common.exceptions import RingLoadError from swift.common.exceptions import RingLoadError
from swift.common.utils import hash_path, validate_configuration, md5 from swift.common.utils import hash_path, validate_configuration, md5
from swift.common.ring.utils import tiers_for_dev from swift.common.ring.utils import tiers_for_dev
@ -206,7 +203,7 @@ class RingData(object):
else: else:
# Assume old-style pickled ring # Assume old-style pickled ring
gz_file.seek(0) gz_file.seek(0)
ring_data = pickle.load(gz_file) ring_data = pickle.load(gz_file) # nosec: B301
if hasattr(ring_data, 'devs'): if hasattr(ring_data, 'devs'):
# pickled RingData; make sure we've got region/replication info # pickled RingData; make sure we've got region/replication info
@ -244,11 +241,6 @@ class RingData(object):
file_obj.write(struct.pack('!I', json_len)) file_obj.write(struct.pack('!I', json_len))
file_obj.write(json_text) file_obj.write(json_text)
for part2dev_id in ring['replica2part2dev_id']: for part2dev_id in ring['replica2part2dev_id']:
if six.PY2:
# Can't just use tofile() because a GzipFile apparently
# doesn't count as an 'open file'
file_obj.write(part2dev_id.tostring())
else:
part2dev_id.tofile(file_obj) part2dev_id.tofile(file_obj)
def save(self, filename, mtime=1300507380.0): def save(self, filename, mtime=1300507380.0):

View File

@ -18,8 +18,6 @@ Bindings to the `tee` and `splice` system calls
''' '''
import os import os
import operator
import six
import ctypes import ctypes
import ctypes.util import ctypes.util
@ -82,8 +80,10 @@ class Tee(object):
if not self.available: if not self.available:
raise EnvironmentError('tee not available') raise EnvironmentError('tee not available')
if not isinstance(flags, six.integer_types): if not isinstance(flags, int):
c_flags = six.moves.reduce(operator.or_, flags, 0) c_flags = 0
for flag in flags:
c_flags |= flag
else: else:
c_flags = flags c_flags = flags
@ -174,8 +174,10 @@ class Splice(object):
if not self.available: if not self.available:
raise EnvironmentError('splice not available') raise EnvironmentError('splice not available')
if not isinstance(flags, six.integer_types): if not isinstance(flags, int):
c_flags = six.moves.reduce(operator.or_, flags, 0) c_flags = 0
for flag in flags:
c_flags |= flag
else: else:
c_flags = flags c_flags = flags

View File

@ -21,7 +21,6 @@ from contextlib import closing
from random import random from random import random
from eventlet.green import socket from eventlet.green import socket
import six
def get_statsd_client(conf=None, tail_prefix='', logger=None): def get_statsd_client(conf=None, tail_prefix='', logger=None):
@ -164,7 +163,6 @@ class StatsdClient(object):
parts.append('@%s' % (sample_rate,)) parts.append('@%s' % (sample_rate,))
else: else:
return return
if six.PY3:
parts = [part.encode('utf-8') for part in parts] parts = [part.encode('utf-8') for part in parts]
# Ideally, we'd cache a sending socket in self, but that # Ideally, we'd cache a sending socket in self, but that
# results in a socket getting shared by multiple green threads. # results in a socket getting shared by multiple green threads.

View File

@ -17,8 +17,7 @@ import os
import string import string
import sys import sys
import textwrap import textwrap
import six from configparser import ConfigParser
from six.moves.configparser import ConfigParser
from swift.common.utils import ( from swift.common.utils import (
config_true_value, quorum_size, whataremyips, list_from_csv, config_true_value, quorum_size, whataremyips, list_from_csv,
config_positive_int_value, get_zero_indexed_base_string, load_pkg_resource) config_positive_int_value, get_zero_indexed_base_string, load_pkg_resource)
@ -80,8 +79,10 @@ class BindPortsCache(object):
# the first one we notice. # the first one we notice.
# Return the requested set of ports from our (now-freshened) cache # Return the requested set of ports from our (now-freshened) cache
return six.moves.reduce(set.union, res = set()
self.portsets_by_ring_path.values(), set()) for ports in self.portsets_by_ring_path.values():
res.update(ports)
return res
class PolicyError(ValueError): class PolicyError(ValueError):
@ -975,11 +976,8 @@ def reload_storage_policies():
Reload POLICIES from ``swift.conf``. Reload POLICIES from ``swift.conf``.
""" """
global _POLICIES global _POLICIES
if six.PY2: # Python disallows section or option duplicates by default
policy_conf = ConfigParser() # strict=False allows them, which Swift has always done
else:
# Python 3.2 disallows section or option duplicates by default
# strict=False allows us to preserve the older behavior
policy_conf = ConfigParser(strict=False) policy_conf = ConfigParser(strict=False)
policy_conf.read(utils.SWIFT_CONF_FILE) policy_conf.read(utils.SWIFT_CONF_FILE)
try: try:

View File

@ -36,10 +36,7 @@ needs to change.
""" """
from collections import defaultdict from collections import defaultdict
try: from collections.abc import MutableMapping
from collections.abc import MutableMapping
except ImportError:
from collections import MutableMapping # py2
import time import time
from functools import partial from functools import partial
from datetime import datetime from datetime import datetime
@ -49,9 +46,8 @@ import random
import functools import functools
from io import BytesIO from io import BytesIO
import six from io import StringIO
from six import StringIO import urllib
from six.moves import urllib
from swift.common.header_key_dict import HeaderKeyDict from swift.common.header_key_dict import HeaderKeyDict
from swift.common.utils import UTC, reiterate, split_path, Timestamp, pairs, \ from swift.common.utils import UTC, reiterate, split_path, Timestamp, pairs, \
@ -157,7 +153,7 @@ def _datetime_property(header):
return None return None
def setter(self, value): def setter(self, value):
if isinstance(value, (float,) + six.integer_types): if isinstance(value, (float, int)):
self.headers[header] = time.strftime( self.headers[header] = time.strftime(
"%a, %d %b %Y %H:%M:%S GMT", time.gmtime(value)) "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(value))
elif isinstance(value, datetime): elif isinstance(value, datetime):
@ -251,9 +247,7 @@ class HeaderEnvironProxy(MutableMapping):
def __setitem__(self, key, value): def __setitem__(self, key, value):
if value is None: if value is None:
self.environ.pop(header_to_environ_key(key), None) self.environ.pop(header_to_environ_key(key), None)
elif six.PY2 and isinstance(value, six.text_type): elif isinstance(value, bytes):
self.environ[header_to_environ_key(key)] = value.encode('utf-8')
elif not six.PY2 and isinstance(value, six.binary_type):
self.environ[header_to_environ_key(key)] = value.decode('latin1') self.environ[header_to_environ_key(key)] = value.decode('latin1')
else: else:
self.environ[header_to_environ_key(key)] = str(value) self.environ[header_to_environ_key(key)] = str(value)
@ -279,70 +273,42 @@ class HeaderEnvironProxy(MutableMapping):
def wsgi_to_bytes(wsgi_str): def wsgi_to_bytes(wsgi_str):
if wsgi_str is None: if wsgi_str is None:
return None return None
if six.PY2:
return wsgi_str
return wsgi_str.encode('latin1') return wsgi_str.encode('latin1')
def wsgi_to_str(wsgi_str): def wsgi_to_str(wsgi_str):
if wsgi_str is None: if wsgi_str is None:
return None return None
if six.PY2:
return wsgi_str
return wsgi_to_bytes(wsgi_str).decode('utf8', errors='surrogateescape') return wsgi_to_bytes(wsgi_str).decode('utf8', errors='surrogateescape')
def bytes_to_wsgi(byte_str): def bytes_to_wsgi(byte_str):
if six.PY2:
return byte_str
return byte_str.decode('latin1') return byte_str.decode('latin1')
def str_to_wsgi(native_str): def str_to_wsgi(native_str):
if six.PY2:
return native_str
return bytes_to_wsgi(native_str.encode('utf8', errors='surrogateescape')) return bytes_to_wsgi(native_str.encode('utf8', errors='surrogateescape'))
def wsgi_quote(wsgi_str, safe='/'): def wsgi_quote(wsgi_str, safe='/'):
if six.PY2:
if not isinstance(wsgi_str, bytes):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.quote(wsgi_str, safe=safe)
if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str): if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str) raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.quote(wsgi_str, safe=safe, encoding='latin-1') return urllib.parse.quote(wsgi_str, safe=safe, encoding='latin-1')
def wsgi_unquote(wsgi_str): def wsgi_unquote(wsgi_str):
if six.PY2:
if not isinstance(wsgi_str, bytes):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.unquote(wsgi_str)
if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str): if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str) raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.unquote(wsgi_str, encoding='latin-1') return urllib.parse.unquote(wsgi_str, encoding='latin-1')
def wsgi_quote_plus(wsgi_str): def wsgi_quote_plus(wsgi_str):
if six.PY2:
if not isinstance(wsgi_str, bytes):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.quote_plus(wsgi_str)
if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str): if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str) raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.quote_plus(wsgi_str, encoding='latin-1') return urllib.parse.quote_plus(wsgi_str, encoding='latin-1')
def wsgi_unquote_plus(wsgi_str): def wsgi_unquote_plus(wsgi_str):
if six.PY2:
if not isinstance(wsgi_str, bytes):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.unquote_plus(wsgi_str)
if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str): if not isinstance(wsgi_str, str) or any(ord(x) > 255 for x in wsgi_str):
raise TypeError('Expected a WSGI string; got %r' % wsgi_str) raise TypeError('Expected a WSGI string; got %r' % wsgi_str)
return urllib.parse.unquote_plus(wsgi_str, encoding='latin-1') return urllib.parse.unquote_plus(wsgi_str, encoding='latin-1')
@ -360,7 +326,7 @@ def _resp_status_property():
return '%s %s' % (self.status_int, self.title) return '%s %s' % (self.status_int, self.title)
def setter(self, value): def setter(self, value):
if isinstance(value, six.integer_types): if isinstance(value, int):
self.status_int = value self.status_int = value
self.explanation = self.title = RESPONSE_REASONS[value][0] self.explanation = self.title = RESPONSE_REASONS[value][0]
else: else:
@ -388,9 +354,9 @@ def _resp_body_property():
return self._body return self._body
def setter(self, value): def setter(self, value):
if isinstance(value, six.text_type): if isinstance(value, str):
raise TypeError('WSGI responses must be bytes') raise TypeError('WSGI responses must be bytes')
if isinstance(value, six.binary_type): if isinstance(value, bytes):
self.content_length = len(value) self.content_length = len(value)
close_if_possible(self._app_iter) close_if_possible(self._app_iter)
self._app_iter = None self._app_iter = None
@ -805,12 +771,6 @@ def _req_environ_property(environ_field, is_wsgi_string_field=True):
return self.environ.get(environ_field, None) return self.environ.get(environ_field, None)
def setter(self, value): def setter(self, value):
if six.PY2:
if isinstance(value, six.text_type):
self.environ[environ_field] = value.encode('utf-8')
else:
self.environ[environ_field] = value
else:
if is_wsgi_string_field: if is_wsgi_string_field:
# Check that input is valid before setting # Check that input is valid before setting
if isinstance(value, str): if isinstance(value, str):
@ -835,7 +795,7 @@ def _req_body_property():
return body return body
def setter(self, value): def setter(self, value):
if not isinstance(value, six.binary_type): if not isinstance(value, bytes):
value = value.encode('utf8') value = value.encode('utf8')
self.environ['wsgi.input'] = WsgiBytesIO(value) self.environ['wsgi.input'] = WsgiBytesIO(value)
self.environ['CONTENT_LENGTH'] = str(len(value)) self.environ['CONTENT_LENGTH'] = str(len(value))
@ -932,11 +892,7 @@ class Request(object):
""" """
headers = headers or {} headers = headers or {}
environ = environ or {} environ = environ or {}
if six.PY2: if isinstance(path, bytes):
if isinstance(path, six.text_type):
path = path.encode('utf-8')
else:
if isinstance(path, six.binary_type):
path = path.decode('latin1') path = path.decode('latin1')
else: else:
# Check that the input is valid # Check that the input is valid
@ -970,7 +926,7 @@ class Request(object):
} }
env.update(environ) env.update(environ)
if body is not None: if body is not None:
if not isinstance(body, six.binary_type): if not isinstance(body, bytes):
body = body.encode('utf8') body = body.encode('utf8')
env['wsgi.input'] = WsgiBytesIO(body) env['wsgi.input'] = WsgiBytesIO(body)
env['CONTENT_LENGTH'] = str(len(body)) env['CONTENT_LENGTH'] = str(len(body))
@ -996,10 +952,6 @@ class Request(object):
"Provides QUERY_STRING parameters as a dictionary" "Provides QUERY_STRING parameters as a dictionary"
if self._params_cache is None: if self._params_cache is None:
if 'QUERY_STRING' in self.environ: if 'QUERY_STRING' in self.environ:
if six.PY2:
self._params_cache = dict(urllib.parse.parse_qsl(
self.environ['QUERY_STRING'], True))
else:
self._params_cache = dict(urllib.parse.parse_qsl( self._params_cache = dict(urllib.parse.parse_qsl(
self.environ['QUERY_STRING'], self.environ['QUERY_STRING'],
keep_blank_values=True, encoding='latin-1')) keep_blank_values=True, encoding='latin-1'))
@ -1011,9 +963,6 @@ class Request(object):
@params.setter @params.setter
def params(self, param_pairs): def params(self, param_pairs):
self._params_cache = None self._params_cache = None
if six.PY2:
self.query_string = urllib.parse.urlencode(param_pairs)
else:
self.query_string = urllib.parse.urlencode(param_pairs, self.query_string = urllib.parse.urlencode(param_pairs,
encoding='latin-1') encoding='latin-1')
@ -1265,7 +1214,7 @@ class Response(object):
self.request = request self.request = request
self._app_iter = None self._app_iter = None
# Allow error messages to come as natural strings on py3. # Allow error messages to come as natural strings on py3.
if isinstance(body, six.text_type): if isinstance(body, str):
body = body.encode('utf8') body = body.encode('utf8')
self.body = body self.body = body
self.app_iter = app_iter self.app_iter = app_iter

View File

@ -64,15 +64,12 @@ from eventlet.event import Event
from eventlet.green import socket from eventlet.green import socket
import eventlet.hubs import eventlet.hubs
import eventlet.queue import eventlet.queue
import six
from six.moves import cPickle as pickle import pickle # nosec: B403
from six.moves.configparser import (ConfigParser, NoSectionError, from configparser import (ConfigParser, NoSectionError,
NoOptionError) NoOptionError)
from six.moves import range from urllib.parse import unquote, urlparse
from six.moves.urllib.parse import unquote from collections import UserList
from six.moves.urllib.parse import urlparse
from six.moves import UserList
import swift.common.exceptions import swift.common.exceptions
from swift.common.http import is_server_error from swift.common.http import is_server_error
@ -373,26 +370,18 @@ def validate_hash_conf():
if not HASH_PATH_SUFFIX and not HASH_PATH_PREFIX: if not HASH_PATH_SUFFIX and not HASH_PATH_PREFIX:
hash_conf = ConfigParser() hash_conf = ConfigParser()
if six.PY3:
# Use Latin1 to accept arbitrary bytes in the hash prefix/suffix # Use Latin1 to accept arbitrary bytes in the hash prefix/suffix
with open(SWIFT_CONF_FILE, encoding='latin1') as swift_conf_file: with open(SWIFT_CONF_FILE, encoding='latin1') as swift_conf_file:
hash_conf.read_file(swift_conf_file) hash_conf.read_file(swift_conf_file)
else:
with open(SWIFT_CONF_FILE) as swift_conf_file:
hash_conf.readfp(swift_conf_file)
try: try:
HASH_PATH_SUFFIX = hash_conf.get('swift-hash', HASH_PATH_SUFFIX = hash_conf.get(
'swift_hash_path_suffix') 'swift-hash', 'swift_hash_path_suffix').encode('latin1')
if six.PY3:
HASH_PATH_SUFFIX = HASH_PATH_SUFFIX.encode('latin1')
except (NoSectionError, NoOptionError): except (NoSectionError, NoOptionError):
pass pass
try: try:
HASH_PATH_PREFIX = hash_conf.get('swift-hash', HASH_PATH_PREFIX = hash_conf.get(
'swift_hash_path_prefix') 'swift-hash', 'swift_hash_path_prefix').encode('latin1')
if six.PY3:
HASH_PATH_PREFIX = HASH_PATH_PREFIX.encode('latin1')
except (NoSectionError, NoOptionError): except (NoSectionError, NoOptionError):
pass pass
@ -498,7 +487,7 @@ class FileLikeIter(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
""" """
next(x) -> the next value, or raise StopIteration next(x) -> the next value, or raise StopIteration
""" """
@ -510,7 +499,6 @@ class FileLikeIter(object):
return rv return rv
else: else:
return next(self.iterator) return next(self.iterator)
__next__ = next
def read(self, size=-1): def read(self, size=-1):
""" """
@ -949,7 +937,7 @@ class RateLimitedIterator(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
next_value = next(self.iterator) next_value = next(self.iterator)
if self.ratelimit_if(next_value): if self.ratelimit_if(next_value):
@ -958,7 +946,6 @@ class RateLimitedIterator(object):
else: else:
self.rate_limiter.wait() self.rate_limiter.wait()
return next_value return next_value
__next__ = next
class GreenthreadSafeIterator(object): class GreenthreadSafeIterator(object):
@ -980,10 +967,9 @@ class GreenthreadSafeIterator(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
with self.semaphore: with self.semaphore:
return next(self.unsafe_iter) return next(self.unsafe_iter)
__next__ = next
def timing_stats(**dec_kwargs): def timing_stats(**dec_kwargs):
@ -1238,13 +1224,13 @@ def hash_path(account, container=None, object=None, raw_digest=False):
""" """
if object and not container: if object and not container:
raise ValueError('container is required if object is provided') raise ValueError('container is required if object is provided')
paths = [account if isinstance(account, six.binary_type) paths = [account if isinstance(account, bytes)
else account.encode('utf8')] else account.encode('utf8')]
if container: if container:
paths.append(container if isinstance(container, six.binary_type) paths.append(container if isinstance(container, bytes)
else container.encode('utf8')) else container.encode('utf8'))
if object: if object:
paths.append(object if isinstance(object, six.binary_type) paths.append(object if isinstance(object, bytes)
else object.encode('utf8')) else object.encode('utf8'))
if raw_digest: if raw_digest:
return md5(HASH_PATH_PREFIX + b'/' + b'/'.join(paths) return md5(HASH_PATH_PREFIX + b'/' + b'/'.join(paths)
@ -2006,7 +1992,7 @@ class GreenAsyncPile(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
while True: while True:
try: try:
rv = self._responses.get_nowait() rv = self._responses.get_nowait()
@ -2018,7 +2004,6 @@ class GreenAsyncPile(object):
if rv is DEAD: if rv is DEAD:
continue continue
return rv return rv
__next__ = next
class StreamingPile(GreenAsyncPile): class StreamingPile(GreenAsyncPile):
@ -2460,8 +2445,6 @@ class ClosingIterator(object):
self.close() self.close()
raise raise
next = __next__ # py2
def close(self): def close(self):
if not self.closed: if not self.closed:
for wrapped in self.closeables: for wrapped in self.closeables:
@ -3085,7 +3068,6 @@ def parse_mime_headers(doc_file):
while True: while True:
line = doc_file.readline() line = doc_file.readline()
done = line in (b'\r\n', b'\n', b'') done = line in (b'\r\n', b'\n', b'')
if six.PY3:
try: try:
line = line.decode('utf-8') line = line.decode('utf-8')
except UnicodeDecodeError: except UnicodeDecodeError:
@ -3093,10 +3075,7 @@ def parse_mime_headers(doc_file):
headers.append(line) headers.append(line)
if done: if done:
break break
if six.PY3:
header_string = ''.join(headers) header_string = ''.join(headers)
else:
header_string = b''.join(headers)
headers = email.parser.Parser().parsestr(header_string) headers = email.parser.Parser().parsestr(header_string)
return HeaderKeyDict(headers) return HeaderKeyDict(headers)
@ -3111,7 +3090,7 @@ def mime_to_document_iters(input_file, boundary, read_chunk_size=4096):
(e.g. "divider", not "--divider") (e.g. "divider", not "--divider")
:param read_chunk_size: size of strings read via input_file.read() :param read_chunk_size: size of strings read via input_file.read()
""" """
if six.PY3 and isinstance(boundary, str): if isinstance(boundary, str):
# Since the boundary is in client-supplied headers, it can contain # Since the boundary is in client-supplied headers, it can contain
# garbage that trips us and we don't like client-induced 500. # garbage that trips us and we don't like client-induced 500.
boundary = boundary.encode('latin-1', errors='replace') boundary = boundary.encode('latin-1', errors='replace')
@ -3351,8 +3330,6 @@ class NamespaceOuterBound(object):
def __bool__(self): def __bool__(self):
return False return False
__nonzero__ = __bool__
@functools.total_ordering @functools.total_ordering
class Namespace(object): class Namespace(object):
@ -3451,9 +3428,7 @@ class Namespace(object):
@classmethod @classmethod
def _encode(cls, value): def _encode(cls, value):
if six.PY2 and isinstance(value, six.text_type): if isinstance(value, bytes):
return value.encode('utf-8')
if six.PY3 and isinstance(value, six.binary_type):
# This should never fail -- the value should always be coming from # This should never fail -- the value should always be coming from
# valid swift paths, which means UTF-8 # valid swift paths, which means UTF-8
return value.decode('utf-8') return value.decode('utf-8')
@ -3462,8 +3437,8 @@ class Namespace(object):
def _encode_bound(self, bound): def _encode_bound(self, bound):
if isinstance(bound, NamespaceOuterBound): if isinstance(bound, NamespaceOuterBound):
return bound return bound
if not (isinstance(bound, six.text_type) or if not (isinstance(bound, str) or
isinstance(bound, six.binary_type)): isinstance(bound, bytes)):
raise TypeError('must be a string type') raise TypeError('must be a string type')
return self._encode(bound) return self._encode(bound)
@ -4364,7 +4339,8 @@ class ShardRangeList(UserList):
""" """
def __getitem__(self, index): def __getitem__(self, index):
# workaround for py3 - not needed for py2.7,py3.8 # workaround for py36,py37 - not needed for py3.8+
# see https://github.com/python/cpython/commit/b1c3167c
result = self.data[index] result = self.data[index]
return ShardRangeList(result) if type(result) is list else result return ShardRangeList(result) if type(result) is list else result
@ -4593,7 +4569,7 @@ def strict_b64decode(value, allow_line_breaks=False):
value = value.decode('ascii') value = value.decode('ascii')
except UnicodeDecodeError: except UnicodeDecodeError:
raise ValueError raise ValueError
if not isinstance(value, six.text_type): if not isinstance(value, str):
raise ValueError raise ValueError
# b64decode will silently discard bad characters, but we want to # b64decode will silently discard bad characters, but we want to
# treat them as an error # treat them as an error
@ -4604,10 +4580,7 @@ def strict_b64decode(value, allow_line_breaks=False):
strip_chars += '\r\n' strip_chars += '\r\n'
if any(c not in valid_chars for c in value.strip(strip_chars)): if any(c not in valid_chars for c in value.strip(strip_chars)):
raise ValueError raise ValueError
try:
return base64.b64decode(value) return base64.b64decode(value)
except (TypeError, binascii.Error): # (py2 error, py3 error)
raise ValueError
def cap_length(value, max_length): def cap_length(value, max_length):

View File

@ -23,8 +23,7 @@ This module should not import from other utils modules.
import codecs import codecs
import hashlib import hashlib
import six from urllib.parse import quote as _quote
from six.moves.urllib.parse import quote as _quote
try: try:
@ -50,10 +49,9 @@ except TypeError:
utf8_decoder = codecs.getdecoder('utf-8') utf8_decoder = codecs.getdecoder('utf-8')
utf8_encoder = codecs.getencoder('utf-8') utf8_encoder = codecs.getencoder('utf-8')
if not six.PY2: # Apparently under py3 we need to go to utf-16 to collapse surrogates?
# Apparently under py3 we need to go to utf-16 to collapse surrogates? utf16_decoder = codecs.getdecoder('utf-16')
utf16_decoder = codecs.getdecoder('utf-16') utf16_encoder = codecs.getencoder('utf-16')
utf16_encoder = codecs.getencoder('utf-16')
def get_valid_utf8_str(str_or_unicode): def get_valid_utf8_str(str_or_unicode):
@ -62,12 +60,7 @@ def get_valid_utf8_str(str_or_unicode):
:param str_or_unicode: a string or an unicode which can be invalid utf-8 :param str_or_unicode: a string or an unicode which can be invalid utf-8
""" """
if six.PY2: if isinstance(str_or_unicode, bytes):
if isinstance(str_or_unicode, six.text_type):
(str_or_unicode, _len) = utf8_encoder(str_or_unicode, 'replace')
(valid_unicode_str, _len) = utf8_decoder(str_or_unicode, 'replace')
else:
if isinstance(str_or_unicode, six.binary_type):
try: try:
(str_or_unicode, _len) = utf8_decoder(str_or_unicode, (str_or_unicode, _len) = utf8_decoder(str_or_unicode,
'surrogatepass') 'surrogatepass')
@ -84,7 +77,7 @@ def quote(value, safe='/'):
Patched version of urllib.quote that encodes utf-8 strings before quoting Patched version of urllib.quote that encodes utf-8 strings before quoting
""" """
quoted = _quote(get_valid_utf8_str(value), safe) quoted = _quote(get_valid_utf8_str(value), safe)
if isinstance(value, six.binary_type): if isinstance(value, bytes):
quoted = quoted.encode('utf-8') quoted = quoted.encode('utf-8')
return quoted return quoted

View File

@ -13,12 +13,11 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import six
import os import os
import operator import operator
import re import re
from six.moves import configparser import configparser
from six.moves.configparser import (ConfigParser, RawConfigParser) from configparser import ConfigParser, RawConfigParser
# Used when reading config values # Used when reading config values
TRUE_VALUES = {'true', '1', 'yes', 'on', 't', 'y'} TRUE_VALUES = {'true', '1', 'yes', 'on', 't', 'y'}
@ -30,7 +29,7 @@ def config_true_value(value):
Returns False otherwise. Returns False otherwise.
""" """
return value is True or \ return value is True or \
(isinstance(value, six.string_types) and value.lower() in TRUE_VALUES) (isinstance(value, str) and value.lower() in TRUE_VALUES)
def _non_negative_number(value, expected_type_f=float, def _non_negative_number(value, expected_type_f=float,
@ -105,7 +104,7 @@ def config_auto_int_value(value, default):
Returns value as an int or raises ValueError otherwise. Returns value as an int or raises ValueError otherwise.
""" """
if value is None or \ if value is None or \
(isinstance(value, six.string_types) and value.lower() == 'auto'): (isinstance(value, str) and value.lower() == 'auto'):
return default return default
try: try:
value = int(value) value = int(value)
@ -338,10 +337,7 @@ def read_conf_dir(parser, conf_dir):
return parser.read(sorted(conf_files)) return parser.read(sorted(conf_files))
if six.PY2: class NicerInterpolation(configparser.BasicInterpolation):
NicerInterpolation = None # just don't cause ImportErrors over in wsgi.py
else:
class NicerInterpolation(configparser.BasicInterpolation):
def before_get(self, parser, section, option, value, defaults): def before_get(self, parser, section, option, value, defaults):
if '%(' not in value: if '%(' not in value:
return value return value
@ -369,9 +365,6 @@ def readconf(conf_path, section_name=None, log_name=None, defaults=None,
defaults = {} defaults = {}
if raw: if raw:
c = RawConfigParser(defaults) c = RawConfigParser(defaults)
else:
if six.PY2:
c = ConfigParser(defaults)
else: else:
# In general, we haven't really thought much about interpolation # In general, we haven't really thought much about interpolation
# in configs. Python's default ConfigParser has always supported # in configs. Python's default ConfigParser has always supported
@ -387,9 +380,6 @@ def readconf(conf_path, section_name=None, log_name=None, defaults=None,
if hasattr(conf_path, 'readline'): if hasattr(conf_path, 'readline'):
if hasattr(conf_path, 'seek'): if hasattr(conf_path, 'seek'):
conf_path.seek(0) conf_path.seek(0)
if six.PY2:
c.readfp(conf_path)
else:
c.read_file(conf_path) c.read_file(conf_path)
else: else:
if os.path.isdir(conf_path): if os.path.isdir(conf_path):

View File

@ -27,7 +27,6 @@ import sys
import time import time
import fcntl import fcntl
import eventlet import eventlet
import six
import datetime import datetime
from swift.common.utils.base import md5, quote, split_path from swift.common.utils.base import md5, quote, split_path
@ -41,11 +40,8 @@ from swift.common.utils.config import config_true_value
# we do the same here # we do the same here
import swift.common.exceptions import swift.common.exceptions
if six.PY2: from eventlet.green.http import client as green_http_client
from eventlet.green import httplib as green_http_client import http.client
else:
from eventlet.green.http import client as green_http_client
from six.moves import http_client
from eventlet.green import threading from eventlet.green import threading
@ -350,7 +346,7 @@ class SwiftLogAdapter(logging.LoggerAdapter, object):
_junk, exc, _junk = sys.exc_info() _junk, exc, _junk = sys.exc_info()
call = self.error call = self.error
emsg = '' emsg = ''
if isinstance(exc, (http_client.BadStatusLine, if isinstance(exc, (http.client.BadStatusLine,
green_http_client.BadStatusLine)): green_http_client.BadStatusLine)):
# Use error(); not really exceptional # Use error(); not really exceptional
emsg = repr(exc) emsg = repr(exc)
@ -503,9 +499,8 @@ class LoggerFileObject(object):
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
raise IOError(errno.EBADF, 'Bad file descriptor') raise IOError(errno.EBADF, 'Bad file descriptor')
__next__ = next
def read(self, size=-1): def read(self, size=-1):
raise IOError(errno.EBADF, 'Bad file descriptor') raise IOError(errno.EBADF, 'Bad file descriptor')
@ -744,8 +739,7 @@ class StrAnonymizer(str):
def __new__(cls, data, method, salt): def __new__(cls, data, method, salt):
method = method.lower() method = method.lower()
if method not in (hashlib.algorithms if six.PY2 else if method not in hashlib.algorithms_guaranteed:
hashlib.algorithms_guaranteed):
raise ValueError('Unsupported hashing method: %r' % method) raise ValueError('Unsupported hashing method: %r' % method)
s = str.__new__(cls, data or '') s = str.__new__(cls, data or '')
s.method = method s.method = method
@ -762,8 +756,8 @@ class StrAnonymizer(str):
else: else:
h = getattr(hashlib, self.method)() h = getattr(hashlib, self.method)()
if self.salt: if self.salt:
h.update(six.b(self.salt)) h.update(self.salt.encode('latin1'))
h.update(six.b(self)) h.update(self.encode('latin1'))
return '{%s%s}%s' % ('S' if self.salt else '', self.method.upper(), return '{%s%s}%s' % ('S' if self.salt else '', self.method.upper(),
h.hexdigest()) h.hexdigest())
@ -880,7 +874,7 @@ def get_policy_index(req_headers, res_headers):
""" """
header = 'X-Backend-Storage-Policy-Index' header = 'X-Backend-Storage-Policy-Index'
policy_index = res_headers.get(header, req_headers.get(header)) policy_index = res_headers.get(header, req_headers.get(header))
if isinstance(policy_index, six.binary_type) and not six.PY2: if isinstance(policy_index, bytes):
policy_index = policy_index.decode('ascii') policy_index = policy_index.decode('ascii')
return str(policy_index) if policy_index is not None else None return str(policy_index) if policy_index is not None else None

View File

@ -21,8 +21,6 @@ import math
import sys import sys
import time import time
import six
NORMAL_FORMAT = "%016.05f" NORMAL_FORMAT = "%016.05f"
INTERNAL_FORMAT = NORMAL_FORMAT + '_%016x' INTERNAL_FORMAT = NORMAL_FORMAT + '_%016x'
@ -90,7 +88,7 @@ class Timestamp(object):
""" """
if isinstance(timestamp, bytes): if isinstance(timestamp, bytes):
timestamp = timestamp.decode('ascii') timestamp = timestamp.decode('ascii')
if isinstance(timestamp, six.string_types): if isinstance(timestamp, str):
base, base_offset = timestamp.partition('_')[::2] base, base_offset = timestamp.partition('_')[::2]
self.timestamp = float(base) self.timestamp = float(base)
if '_' in base_offset: if '_' in base_offset:
@ -140,11 +138,8 @@ class Timestamp(object):
def __int__(self): def __int__(self):
return int(self.timestamp) return int(self.timestamp)
def __nonzero__(self):
return bool(self.timestamp or self.offset)
def __bool__(self): def __bool__(self):
return self.__nonzero__() return bool(self.timestamp or self.offset)
@property @property
def normal(self): def normal(self):
@ -176,7 +171,6 @@ class Timestamp(object):
:return: an isoformat string :return: an isoformat string
""" """
t = float(self.normal) t = float(self.normal)
if six.PY3:
# On Python 3, round manually using ROUND_HALF_EVEN rounding # On Python 3, round manually using ROUND_HALF_EVEN rounding
# method, to use the same rounding method than Python 2. Python 3 # method, to use the same rounding method than Python 2. Python 3
# used a different rounding method, but Python 3.4.4 and 3.5.1 use # used a different rounding method, but Python 3.4.4 and 3.5.1 use
@ -192,8 +186,6 @@ class Timestamp(object):
us += 1000000 us += 1000000
dt = datetime.datetime.fromtimestamp(t, UTC) dt = datetime.datetime.fromtimestamp(t, UTC)
dt = dt.replace(microsecond=us) dt = dt.replace(microsecond=us)
else:
dt = datetime.datetime.fromtimestamp(t, UTC)
isoformat = dt.isoformat() isoformat = dt.isoformat()
# need to drop tzinfo # need to drop tzinfo
@ -316,7 +308,7 @@ def decode_timestamps(encoded, explicit=False):
# TODO: some tests, e.g. in test_replicator, put float timestamps values # TODO: some tests, e.g. in test_replicator, put float timestamps values
# into container db's, hence this defensive check, but in real world # into container db's, hence this defensive check, but in real world
# this may never happen. # this may never happen.
if not isinstance(encoded, six.string_types): if not isinstance(encoded, str):
ts = Timestamp(encoded) ts = Timestamp(encoded)
return ts, ts, ts return ts, ts, ts

View File

@ -18,7 +18,6 @@
from __future__ import print_function from __future__ import print_function
import errno import errno
import fcntl
import os import os
import signal import signal
import sys import sys
@ -31,10 +30,7 @@ import eventlet.debug
from eventlet import greenio, GreenPool, sleep, wsgi, listen, Timeout from eventlet import greenio, GreenPool, sleep, wsgi, listen, Timeout
from paste.deploy import loadwsgi from paste.deploy import loadwsgi
from eventlet.green import socket, ssl, os as green_os from eventlet.green import socket, ssl, os as green_os
from io import BytesIO from io import BytesIO, StringIO
import six
from six import StringIO
from swift.common import utils, constraints from swift.common import utils, constraints
from swift.common.http_protocol import SwiftHttpProtocol, \ from swift.common.http_protocol import SwiftHttpProtocol, \
@ -67,7 +63,6 @@ class NamedConfigLoader(loadwsgi.ConfigLoader):
""" """
def get_context(self, object_type, name=None, global_conf=None): def get_context(self, object_type, name=None, global_conf=None):
if not six.PY2:
self.parser._interpolation = NicerInterpolation() self.parser._interpolation = NicerInterpolation()
context = super(NamedConfigLoader, self).get_context( context = super(NamedConfigLoader, self).get_context(
object_type, name=name, global_conf=global_conf) object_type, name=name, global_conf=global_conf)
@ -128,9 +123,6 @@ class ConfigString(NamedConfigLoader):
self.parser.optionxform = str # Don't lower-case keys self.parser.optionxform = str # Don't lower-case keys
# Defaults don't need interpolation (crazy PasteDeploy...) # Defaults don't need interpolation (crazy PasteDeploy...)
self.parser.defaults = lambda: dict(self.parser._defaults, **defaults) self.parser.defaults = lambda: dict(self.parser._defaults, **defaults)
if six.PY2:
self.parser.readfp(self.contents)
else:
self.parser.read_file(self.contents) self.parser.read_file(self.contents)
def readline(self, *args, **kwargs): def readline(self, *args, **kwargs):
@ -198,9 +190,6 @@ def get_socket(conf):
sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)), sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)),
family=address_family) family=address_family)
if 'cert_file' in conf: if 'cert_file' in conf:
if six.PY2:
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
else:
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.verify_mode = ssl.CERT_NONE context.verify_mode = ssl.CERT_NONE
context.load_cert_chain(conf['cert_file'], conf['key_file']) context.load_cert_chain(conf['cert_file'], conf['key_file'])
@ -513,9 +502,6 @@ class StrategyBase(object):
""" """
for sock in self.iter_sockets(): for sock in self.iter_sockets():
if six.PY2:
fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
else:
# Python 3.4 and later default to sockets having close-on-exec # Python 3.4 and later default to sockets having close-on-exec
# set (what PEP 0446 calls "non-inheritable"). This new method # set (what PEP 0446 calls "non-inheritable"). This new method
# on socket objects is provided to toggle it. # on socket objects is provided to toggle it.

View File

@ -20,9 +20,7 @@ import errno
import os import os
from uuid import uuid4 from uuid import uuid4
import six from urllib.parse import unquote
from six.moves import range
from six.moves.urllib.parse import unquote
import sqlite3 import sqlite3
from eventlet import tpool from eventlet import tpool
@ -33,7 +31,7 @@ from swift.common.utils import Timestamp, encode_timestamps, \
ShardRange, renamer, MD5_OF_EMPTY_STRING, mkdirs, get_db_files, \ ShardRange, renamer, MD5_OF_EMPTY_STRING, mkdirs, get_db_files, \
parse_db_filename, make_db_file_path, split_path, RESERVED_BYTE, \ parse_db_filename, make_db_file_path, split_path, RESERVED_BYTE, \
ShardRangeList, Namespace ShardRangeList, Namespace
from swift.common.db import DatabaseBroker, utf8encode, BROKER_TIMEOUT, \ from swift.common.db import DatabaseBroker, BROKER_TIMEOUT, \
zero_like, DatabaseAlreadyExists, SQLITE_ARG_LIMIT zero_like, DatabaseAlreadyExists, SQLITE_ARG_LIMIT
DATADIR = 'containers' DATADIR = 'containers'
@ -1138,9 +1136,6 @@ class ContainerBroker(DatabaseBroker):
if transform_func is None: if transform_func is None:
transform_func = self._transform_record transform_func = self._transform_record
delim_force_gte = False delim_force_gte = False
if six.PY2:
(marker, end_marker, prefix, delimiter, path) = utf8encode(
marker, end_marker, prefix, delimiter, path)
self._commit_puts_stale_ok() self._commit_puts_stale_ok()
if reverse: if reverse:
# Reverse the markers if we are reversing the listing. # Reverse the markers if we are reversing the listing.
@ -1335,9 +1330,7 @@ class ContainerBroker(DatabaseBroker):
:param source: if defined, update incoming_sync with the source :param source: if defined, update incoming_sync with the source
""" """
for item in item_list: for item in item_list:
if six.PY2 and isinstance(item['name'], six.text_type): if isinstance(item['name'], bytes):
item['name'] = item['name'].encode('utf-8')
elif not six.PY2 and isinstance(item['name'], six.binary_type):
item['name'] = item['name'].decode('utf-8') item['name'] = item['name'].decode('utf-8')
def _really_really_merge_items(conn): def _really_really_merge_items(conn):
@ -1433,9 +1426,7 @@ class ContainerBroker(DatabaseBroker):
if isinstance(item, ShardRange): if isinstance(item, ShardRange):
item = dict(item) item = dict(item)
for col in ('name', 'lower', 'upper'): for col in ('name', 'lower', 'upper'):
if six.PY2 and isinstance(item[col], six.text_type): if isinstance(item[col], bytes):
item[col] = item[col].encode('utf-8')
elif not six.PY2 and isinstance(item[col], six.binary_type):
item[col] = item[col].decode('utf-8') item[col] = item[col].decode('utf-8')
item_list.append(item) item_list.append(item)

View File

@ -19,7 +19,6 @@ import itertools
import logging import logging
from eventlet import GreenPile, GreenPool, Timeout from eventlet import GreenPile, GreenPool, Timeout
import six
from swift.common import constraints from swift.common import constraints
from swift.common.daemon import Daemon, run_daemon from swift.common.daemon import Daemon, run_daemon
@ -272,11 +271,7 @@ def parse_raw_obj(obj_info):
:returns: a queue entry dict with the keys: q_policy_index, account, :returns: a queue entry dict with the keys: q_policy_index, account,
container, obj, q_op, q_ts, q_record, and path container, obj, q_op, q_ts, q_record, and path
""" """
if six.PY2:
raw_obj_name = obj_info['name'].encode('utf-8')
else:
raw_obj_name = obj_info['name'] raw_obj_name = obj_info['name']
policy_index, obj_name = raw_obj_name.split(':', 1) policy_index, obj_name = raw_obj_name.split(':', 1)
q_policy_index = int(policy_index) q_policy_index = int(policy_index)
account, container, obj = split_path(obj_name, 3, 3, rest_with_last=True) account, container, obj = split_path(obj_name, 3, 3, rest_with_last=True)
@ -758,9 +753,6 @@ class ContainerReconciler(Daemon):
# reversed order since we expect older containers to be empty # reversed order since we expect older containers to be empty
for c in reversed(one_page): for c in reversed(one_page):
container = c['name'] container = c['name']
if six.PY2:
# encoding here is defensive
container = container.encode('utf8')
if container == current_container: if container == current_container:
continue # we've already hit this one this pass continue # we've already hit this one this pass
yield container yield container

View File

@ -21,8 +21,7 @@ import traceback
from eventlet import Timeout from eventlet import Timeout
import six from urllib.parse import quote
from six.moves.urllib.parse import quote
import swift.common.db import swift.common.db
from swift.container.sync_store import ContainerSyncStore from swift.container.sync_store import ContainerSyncStore
@ -237,10 +236,7 @@ class ContainerController(BaseStorageServer):
return HTTPBadRequest(req=req) return HTTPBadRequest(req=req)
if account_partition: if account_partition:
# zip is lazy on py3, but we need a list, so force evaluation. # zip is lazy, but we need a list, so force evaluation.
# On py2 it's an extra list copy, but the list is so small
# (one element per replica in account ring, usually 3) that it
# doesn't matter.
updates = list(zip(account_hosts, account_devices)) updates = list(zip(account_hosts, account_devices))
else: else:
updates = [] updates = []
@ -644,11 +640,10 @@ class ContainerController(BaseStorageServer):
""" """
# record is object info # record is object info
(name, created, size, content_type, etag) = record[:5] (name, created, size, content_type, etag) = record[:5]
name_ = name.decode('utf8') if six.PY2 else name
if content_type is None: if content_type is None:
return {'subdir': name_} return {'subdir': name}
response = { response = {
'bytes': size, 'hash': etag, 'name': name_, 'bytes': size, 'hash': etag, 'name': name,
'content_type': content_type} 'content_type': content_type}
override_bytes_from_content_type(response, logger=self.logger) override_bytes_from_content_type(response, logger=self.logger)
response['last_modified'] = Timestamp(created).isoformat response['last_modified'] = Timestamp(created).isoformat

View File

@ -24,8 +24,7 @@ from operator import itemgetter
from random import random from random import random
import os import os
import six from urllib.parse import quote
from six.moves.urllib.parse import quote
from eventlet import Timeout from eventlet import Timeout
from contextlib import contextmanager from contextlib import contextmanager
@ -657,18 +656,13 @@ class CleavingContext(object):
return '%s(%s)' % (self.__class__.__name__, ', '.join( return '%s(%s)' % (self.__class__.__name__, ', '.join(
'%s=%r' % prop for prop in self)) '%s=%r' % prop for prop in self))
def _encode(cls, value):
if value is not None and six.PY2 and isinstance(value, six.text_type):
return value.encode('utf-8')
return value
@property @property
def cursor(self): def cursor(self):
return self._cursor return self._cursor
@cursor.setter @cursor.setter
def cursor(self, value): def cursor(self, value):
self._cursor = self._encode(value) self._cursor = value
@property @property
def marker(self): def marker(self):

View File

@ -22,7 +22,7 @@ from random import choice, random
from struct import unpack_from from struct import unpack_from
from eventlet import sleep, Timeout from eventlet import sleep, Timeout
from six.moves.urllib.parse import urlparse from urllib.parse import urlparse
import swift.common.db import swift.common.db
from swift.common.db import DatabaseConnectionError from swift.common.db import DatabaseConnectionError

View File

@ -30,7 +30,7 @@ The remaining methods in this module are considered implementation specific and
are also not considered part of the backend API. are also not considered part of the backend API.
""" """
import six.moves.cPickle as pickle import pickle # nosec: B403
import binascii import binascii
import copy import copy
import errno import errno
@ -52,7 +52,6 @@ from datetime import timedelta
from eventlet import Timeout, tpool from eventlet import Timeout, tpool
from eventlet.hubs import trampoline from eventlet.hubs import trampoline
import six
from pyeclib.ec_iface import ECDriverError, ECInvalidFragmentMetadata, \ from pyeclib.ec_iface import ECDriverError, ECInvalidFragmentMetadata, \
ECBadFragmentChecksum, ECInvalidParameter ECBadFragmentChecksum, ECInvalidParameter
@ -154,14 +153,8 @@ def _encode_metadata(metadata):
:param metadata: a dict :param metadata: a dict
""" """
if six.PY2:
def encode_str(item): def encode_str(item):
if isinstance(item, six.text_type): if isinstance(item, str):
return item.encode('utf8')
return item
else:
def encode_str(item):
if isinstance(item, six.text_type):
return item.encode('utf8', 'surrogateescape') return item.encode('utf8', 'surrogateescape')
return item return item
@ -175,17 +168,6 @@ def _decode_metadata(metadata, metadata_written_by_py3):
:param metadata: a dict :param metadata: a dict
:param metadata_written_by_py3: :param metadata_written_by_py3:
""" """
if six.PY2:
def to_str(item, is_name=False):
# For years, py2 and py3 handled non-ascii metadata differently;
# see https://bugs.launchpad.net/swift/+bug/2012531
if metadata_written_by_py3 and not is_name:
# do our best to read new-style data replicated from a py3 node
item = item.decode('utf8').encode('latin1')
if isinstance(item, six.text_type):
return item.encode('utf8')
return item
else:
def to_str(item, is_name=False): def to_str(item, is_name=False):
# For years, py2 and py3 handled non-ascii metadata differently; # For years, py2 and py3 handled non-ascii metadata differently;
# see https://bugs.launchpad.net/swift/+bug/2012531 # see https://bugs.launchpad.net/swift/+bug/2012531
@ -193,7 +175,7 @@ def _decode_metadata(metadata, metadata_written_by_py3):
and not is_name: and not is_name:
# do our best to read old py2 data # do our best to read old py2 data
item = item.decode('latin1') item = item.decode('latin1')
if isinstance(item, six.binary_type): if isinstance(item, bytes):
return item.decode('utf8', 'surrogateescape') return item.decode('utf8', 'surrogateescape')
return item return item
@ -255,10 +237,7 @@ def read_metadata(fd, add_missing_checksum=False):
# strings are utf-8 encoded when written, but have not always been # strings are utf-8 encoded when written, but have not always been
# (see https://bugs.launchpad.net/swift/+bug/1678018) so encode them again # (see https://bugs.launchpad.net/swift/+bug/1678018) so encode them again
# when read # when read
if six.PY2: metadata = pickle.loads(metadata, encoding='bytes') # nosec: B301
metadata = pickle.loads(metadata)
else:
metadata = pickle.loads(metadata, encoding='bytes')
return _decode_metadata(metadata, metadata_written_by_py3) return _decode_metadata(metadata, metadata_written_by_py3)
@ -360,7 +339,7 @@ def quarantine_renamer(device_path, corrupted_file_path):
def valid_suffix(value): def valid_suffix(value):
if not isinstance(value, six.string_types) or len(value) != 3: if not isinstance(value, str) or len(value) != 3:
return False return False
return all(c in '0123456789abcdef' for c in value) return all(c in '0123456789abcdef' for c in value)
@ -381,7 +360,7 @@ def read_hashes(partition_dir):
pass pass
else: else:
try: try:
hashes = pickle.loads(pickled_hashes) hashes = pickle.loads(pickled_hashes) # nosec: B301
except Exception: except Exception:
# pickle.loads() can raise a wide variety of exceptions when # pickle.loads() can raise a wide variety of exceptions when
# given invalid input depending on the way in which the # given invalid input depending on the way in which the
@ -626,11 +605,7 @@ def get_auditor_status(datadir_path, logger, auditor_type):
datadir_path, "auditor_status_%s.json" % auditor_type) datadir_path, "auditor_status_%s.json" % auditor_type)
status = {} status = {}
try: try:
if six.PY3: with open(auditor_status, encoding='utf8') as statusfile:
statusfile = open(auditor_status, encoding='utf8')
else:
statusfile = open(auditor_status, 'rb')
with statusfile:
status = statusfile.read() status = statusfile.read()
except (OSError, IOError) as e: except (OSError, IOError) as e:
if e.errno != errno.ENOENT and logger: if e.errno != errno.ENOENT and logger:
@ -648,9 +623,7 @@ def get_auditor_status(datadir_path, logger, auditor_type):
def update_auditor_status(datadir_path, logger, partitions, auditor_type): def update_auditor_status(datadir_path, logger, partitions, auditor_type):
status = json.dumps({'partitions': partitions}) status = json.dumps({'partitions': partitions}).encode('utf8')
if six.PY3:
status = status.encode('utf8')
auditor_status = os.path.join( auditor_status = os.path.join(
datadir_path, "auditor_status_%s.json" % auditor_type) datadir_path, "auditor_status_%s.json" % auditor_type)
try: try:
@ -1170,9 +1143,6 @@ class BaseDiskFileManager(object):
:param path: full path to directory :param path: full path to directory
:param policy: storage policy used :param policy: storage policy used
""" """
if six.PY2:
hashes = defaultdict(lambda: md5(usedforsecurity=False))
else:
class shim(object): class shim(object):
def __init__(self): def __init__(self):
self.md5 = md5(usedforsecurity=False) self.md5 = md5(usedforsecurity=False)
@ -3206,7 +3176,7 @@ class ECDiskFileReader(BaseDiskFileReader):
def _check_frag(self, frag): def _check_frag(self, frag):
if not frag: if not frag:
return return
if not isinstance(frag, six.binary_type): if not isinstance(frag, bytes):
# ECInvalidParameter can be returned if the frag violates the input # ECInvalidParameter can be returned if the frag violates the input
# format so for safety, check the input chunk if it's binary to # format so for safety, check the input chunk if it's binary to
# avoid quarantining a valid fragment archive. # avoid quarantining a valid fragment archive.

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import six import urllib
from six.moves import urllib
from random import random from random import random
from time import time from time import time
@ -344,7 +343,7 @@ class ObjectExpirer(Daemon):
task_container, task_container,
acceptable_statuses=[2]): acceptable_statuses=[2]):
container_empty = False container_empty = False
task_object = o['name'].encode('utf8') if six.PY2 else o['name'] task_object = o['name']
try: try:
delete_timestamp, target_account, target_container, \ delete_timestamp, target_account, target_container, \
target_object = parse_task_obj(task_object) target_object = parse_task_obj(task_object)

View File

@ -21,8 +21,7 @@ from os.path import join
import random import random
import time import time
from collections import defaultdict from collections import defaultdict
import six import pickle # nosec: B403
import six.moves.cPickle as pickle
import shutil import shutil
from eventlet import (GreenPile, GreenPool, Timeout, sleep, tpool, spawn) from eventlet import (GreenPile, GreenPool, Timeout, sleep, tpool, spawn)
@ -84,7 +83,7 @@ def _full_path(node, part, relative_path, policy):
:class:`~swift.common.storage_policy.BaseStoragePolicy` :class:`~swift.common.storage_policy.BaseStoragePolicy`
:return: string representation of absolute path on node plus policy index :return: string representation of absolute path on node plus policy index
""" """
if not isinstance(relative_path, six.text_type): if not isinstance(relative_path, str):
relative_path = relative_path.decode('utf8') relative_path = relative_path.decode('utf8')
return '%(node)s/%(part)s%(path)s policy#%(policy)d' % { return '%(node)s/%(part)s%(path)s policy#%(policy)d' % {
'node': node_to_string(node, replication=True), 'node': node_to_string(node, replication=True),
@ -935,7 +934,7 @@ class ObjectReconstructor(Daemon):
"Invalid response %(resp)s from %(full_path)s", "Invalid response %(resp)s from %(full_path)s",
{'resp': resp.status, 'full_path': full_path}) {'resp': resp.status, 'full_path': full_path})
else: else:
remote_suffixes = pickle.loads(resp.read()) remote_suffixes = pickle.loads(resp.read()) # nosec: B301
except (Exception, Timeout): except (Exception, Timeout):
# all exceptions are logged here so that our caller can # all exceptions are logged here so that our caller can
# safely catch our exception and continue to the next node # safely catch our exception and continue to the next node
@ -1286,11 +1285,11 @@ class ObjectReconstructor(Daemon):
policy2devices = {} policy2devices = {}
for policy in self.policies: for policy in self.policies:
self.load_object_ring(policy) self.load_object_ring(policy)
local_devices = list(six.moves.filter( local_devices = [
lambda dev: dev and is_local_device( dev for dev in policy.object_ring.devs
if dev and is_local_device(
ips, self.port, ips, self.port,
dev['replication_ip'], dev['replication_port']), dev['replication_ip'], dev['replication_port'])]
policy.object_ring.devs))
policy2devices[policy] = local_devices policy2devices[policy] = local_devices
return policy2devices return policy2devices

View File

@ -22,8 +22,7 @@ import random
import shutil import shutil
import time import time
import itertools import itertools
from six import viewkeys import pickle # nosec: B403
import six.moves.cPickle as pickle
import eventlet import eventlet
from eventlet import GreenPool, queue, tpool, Timeout, sleep from eventlet import GreenPool, queue, tpool, Timeout, sleep
@ -554,8 +553,8 @@ class ObjectReplicator(Daemon):
failure_devs_info.add((node['replication_ip'], failure_devs_info.add((node['replication_ip'],
node['device'])) node['device']))
if success and node['region'] != job['region']: if success and node['region'] != job['region']:
synced_remote_regions[node['region']] = viewkeys( synced_remote_regions[node['region']] = \
candidates) candidates.keys()
responses.append(success) responses.append(success)
for cand_objs in synced_remote_regions.values(): for cand_objs in synced_remote_regions.values():
if delete_objs is None: if delete_objs is None:
@ -710,7 +709,8 @@ class ObjectReplicator(Daemon):
failure_devs_info.add((node['replication_ip'], failure_devs_info.add((node['replication_ip'],
node['device'])) node['device']))
continue continue
remote_hash = pickle.loads(resp.read()) remote_hash = pickle.loads(
resp.read()) # nosec: B301
finally: finally:
conn.close() conn.close()
del resp del resp

View File

@ -15,9 +15,8 @@
""" Object Server for Swift """ """ Object Server for Swift """
import six import pickle # nosec: B403
import six.moves.cPickle as pickle from urllib.parse import unquote
from six.moves.urllib.parse import unquote
import json import json
import os import os
import multiprocessing import multiprocessing
@ -200,8 +199,8 @@ class ObjectController(BaseStorageServer):
# disk_chunk_size parameter. However, it affects all created sockets # disk_chunk_size parameter. However, it affects all created sockets
# using this class so we have chosen to tie it to the # using this class so we have chosen to tie it to the
# network_chunk_size parameter value instead. # network_chunk_size parameter value instead.
if six.PY2: # if six.PY2:
socket._fileobject.default_bufsize = self.network_chunk_size # socket._fileobject.default_bufsize = self.network_chunk_size
# TODO: find a way to enable similar functionality in py3 # TODO: find a way to enable similar functionality in py3
# Provide further setup specific to an object server implementation. # Provide further setup specific to an object server implementation.

View File

@ -17,7 +17,7 @@
import eventlet.greenio import eventlet.greenio
import eventlet.wsgi import eventlet.wsgi
from eventlet import sleep from eventlet import sleep
from six.moves import urllib import urllib
from swift.common import exceptions from swift.common import exceptions
from swift.common import http from swift.common import http

View File

@ -14,8 +14,7 @@
# limitations under the License. # limitations under the License.
from eventlet import sleep from eventlet import sleep
import six import urllib
from six.moves import urllib
from swift.common import bufferedhttp from swift.common import bufferedhttp
from swift.common import exceptions from swift.common import exceptions
@ -306,7 +305,7 @@ class Sender(object):
frag_index=self.job.get('frag_index'), frag_index=self.job.get('frag_index'),
frag_prefs=frag_prefs) frag_prefs=frag_prefs)
if self.remote_check_objs is not None: if self.remote_check_objs is not None:
hash_gen = six.moves.filter( hash_gen = filter(
lambda objhash_timestamps: lambda objhash_timestamps:
objhash_timestamps[0] in objhash_timestamps[0] in
self.remote_check_objs, hash_gen) self.remote_check_objs, hash_gen)
@ -353,7 +352,6 @@ class Sender(object):
if line == b':MISSING_CHECK: START': if line == b':MISSING_CHECK: START':
break break
elif line: elif line:
if not six.PY2:
try: try:
line = line.decode('ascii') line = line.decode('ascii')
except UnicodeDecodeError: except UnicodeDecodeError:
@ -442,7 +440,6 @@ class Sender(object):
if line == b':UPDATES: START': if line == b':UPDATES: START':
break break
elif line: elif line:
if not six.PY2:
try: try:
line = line.decode('ascii') line = line.decode('ascii')
except UnicodeDecodeError: except UnicodeDecodeError:
@ -459,7 +456,6 @@ class Sender(object):
if line == b':UPDATES: END': if line == b':UPDATES: END':
break break
elif line: elif line:
if not six.PY2:
try: try:
line = line.decode('ascii') line = line.decode('ascii')
except UnicodeDecodeError: except UnicodeDecodeError:

View File

@ -12,9 +12,9 @@
# implied. # implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from six.moves import queue import queue
import six.moves.cPickle as pickle import pickle # nosec: B403
import errno import errno
import os import os
import signal import signal
@ -62,8 +62,6 @@ class RateLimiterBucket(EventletRateLimiter):
def __bool__(self): def __bool__(self):
return bool(self.deque) return bool(self.deque)
__nonzero__ = __bool__ # py2
def __lt__(self, other): def __lt__(self, other):
# used to sort RateLimiterBuckets by readiness # used to sort RateLimiterBuckets by readiness
if isinstance(other, RateLimiterBucket): if isinstance(other, RateLimiterBucket):
@ -145,7 +143,7 @@ class BucketizedUpdateSkippingLimiter(object):
def _get_time(self): def _get_time(self):
return time.time() return time.time()
def next(self): def __next__(self):
# first iterate over the wrapped iterator... # first iterate over the wrapped iterator...
for update_ctx in self.iterator: for update_ctx in self.iterator:
bucket = self.buckets[self._bucket_key(update_ctx['update'])] bucket = self.buckets[self._bucket_key(update_ctx['update'])]
@ -213,8 +211,6 @@ class BucketizedUpdateSkippingLimiter(object):
raise StopIteration() raise StopIteration()
__next__ = next
class OldestAsyncPendingTracker: class OldestAsyncPendingTracker:
""" """
@ -648,7 +644,7 @@ class ObjectUpdater(Daemon):
def _load_update(self, device, update_path): def _load_update(self, device, update_path):
try: try:
return pickle.load(open(update_path, 'rb')) return pickle.load(open(update_path, 'rb')) # nosec: B301
except Exception as e: except Exception as e:
if getattr(e, 'errno', None) == errno.ENOENT: if getattr(e, 'errno', None) == errno.ENOENT:
return return

View File

@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from six.moves.urllib.parse import unquote from urllib.parse import unquote
from swift.account.utils import account_listing_response from swift.account.utils import account_listing_response
from swift.common.middleware.acl import parse_acl, format_acl from swift.common.middleware.acl import parse_acl, format_acl

View File

@ -24,7 +24,7 @@
# These shenanigans are to ensure all related objects can be garbage # These shenanigans are to ensure all related objects can be garbage
# collected. We've seen objects hang around forever otherwise. # collected. We've seen objects hang around forever otherwise.
from six.moves.urllib.parse import quote from urllib.parse import quote
import time import time
import json import json
@ -34,10 +34,8 @@ import itertools
import operator import operator
import random import random
from copy import deepcopy from copy import deepcopy
from sys import exc_info
from eventlet.timeout import Timeout from eventlet.timeout import Timeout
import six
from swift.common.memcached import MemcacheConnectionError from swift.common.memcached import MemcacheConnectionError
from swift.common.wsgi import make_pre_authed_env, make_pre_authed_request from swift.common.wsgi import make_pre_authed_env, make_pre_authed_request
@ -626,12 +624,6 @@ def get_cache_key(account, container=None, obj=None, shard=None):
with obj) with obj)
:returns: a (native) string cache_key :returns: a (native) string cache_key
""" """
if six.PY2:
def to_native(s):
if s is None or isinstance(s, str):
return s
return s.encode('utf8')
else:
def to_native(s): def to_native(s):
if s is None or isinstance(s, str): if s is None or isinstance(s, str):
return s return s
@ -844,27 +836,6 @@ def _get_info_from_memcache(app, env, account, container=None):
else: else:
info = memcache.get(cache_key) info = memcache.get(cache_key)
cache_state = 'hit' if info else 'miss' cache_state = 'hit' if info else 'miss'
if info and six.PY2:
# Get back to native strings
new_info = {}
for key in info:
new_key = key.encode("utf-8") if isinstance(
key, six.text_type) else key
if isinstance(info[key], six.text_type):
new_info[new_key] = info[key].encode("utf-8")
elif isinstance(info[key], dict):
new_info[new_key] = {}
for subkey, value in info[key].items():
new_subkey = subkey.encode("utf-8") if isinstance(
subkey, six.text_type) else subkey
if isinstance(value, six.text_type):
new_info[new_key][new_subkey] = \
value.encode("utf-8")
else:
new_info[new_key][new_subkey] = value
else:
new_info[new_key] = info[key]
info = new_info
if info: if info:
env.setdefault('swift.infocache', {})[cache_key] = info env.setdefault('swift.infocache', {})[cache_key] = info
return info, cache_state return info, cache_state
@ -921,12 +892,6 @@ def get_namespaces_from_cache(req, cache_key, skip_chance):
cache_state = 'error' cache_state = 'error'
if bounds: if bounds:
if six.PY2:
# json.loads() in memcache.get will convert json 'string' to
# 'unicode' with python2, here we cast 'unicode' back to 'str'
bounds = [
[lower.encode('utf-8'), name.encode('utf-8')]
for lower, name in bounds]
ns_bound_list = NamespaceBoundList(bounds) ns_bound_list = NamespaceBoundList(bounds)
infocache[cache_key] = ns_bound_list infocache[cache_key] = ns_bound_list
else: else:
@ -1439,14 +1404,13 @@ class GetOrHeadHandler(GetterBase):
chunk = part_file.read(self.app.object_chunk_size) chunk = part_file.read(self.app.object_chunk_size)
if nbytes is not None: if nbytes is not None:
nbytes -= len(chunk) nbytes -= len(chunk)
except (ChunkReadTimeout, ShortReadError): except (ChunkReadTimeout, ShortReadError) as e:
exc_type, exc_value, exc_traceback = exc_info()
if self.newest or self.server_type != 'Object': if self.newest or self.server_type != 'Object':
raise raise
try: try:
self.fast_forward(self.bytes_used_from_backend) self.fast_forward(self.bytes_used_from_backend)
except (HTTPException, ValueError): except (HTTPException, ValueError):
six.reraise(exc_type, exc_value, exc_traceback) raise e
except RangeAlreadyComplete: except RangeAlreadyComplete:
break break
if self._replace_source( if self._replace_source(
@ -1458,10 +1422,10 @@ class GetOrHeadHandler(GetterBase):
# Tried to find a new node from which to # Tried to find a new node from which to
# finish the GET, but failed. There's # finish the GET, but failed. There's
# nothing more we can do here. # nothing more we can do here.
six.reraise(exc_type, exc_value, exc_traceback) raise e
part_file = ByteCountEnforcer(part_file, nbytes) part_file = ByteCountEnforcer(part_file, nbytes)
else: else:
six.reraise(exc_type, exc_value, exc_traceback) raise e
else: else:
if not chunk: if not chunk:
break break
@ -1880,7 +1844,7 @@ class NodeIter(object):
return dict(node, use_replication=is_use_replication_network( return dict(node, use_replication=is_use_replication_network(
self.request.headers)) self.request.headers))
def next(self): def __next__(self):
node = None node = None
if self._node_provider: if self._node_provider:
# give node provider the opportunity to inject a node # give node provider the opportunity to inject a node
@ -1889,9 +1853,6 @@ class NodeIter(object):
node = next(self._node_iter) node = next(self._node_iter)
return self._annotate_node(node) return self._annotate_node(node)
def __next__(self):
return self.next()
class Controller(object): class Controller(object):
"""Base WSGI controller class for the proxy""" """Base WSGI controller class for the proxy"""

View File

@ -15,8 +15,7 @@
import json import json
import six from urllib.parse import unquote
from six.moves.urllib.parse import unquote
from swift.common.utils import public, private, csv_append, Timestamp, \ from swift.common.utils import public, private, csv_append, Timestamp, \
config_true_value, cache_from_env, filter_namespaces, NamespaceBoundList config_true_value, cache_from_env, filter_namespaces, NamespaceBoundList
@ -508,8 +507,6 @@ class ContainerController(Controller):
else: else:
last_name = objects[-1]['name'] last_name = objects[-1]['name']
if six.PY2:
last_name = last_name.encode('utf8')
params['marker'] = str_to_wsgi(last_name) params['marker'] = str_to_wsgi(last_name)
elif marker: elif marker:
params['marker'] = str_to_wsgi(marker) params['marker'] = str_to_wsgi(marker)
@ -594,8 +591,6 @@ class ContainerController(Controller):
break break
last_name = objects[-1].get('name', last_name = objects[-1].get('name',
objects[-1].get('subdir', u'')) objects[-1].get('subdir', u''))
if six.PY2:
last_name = last_name.encode('utf8')
if end_marker and reverse and end_marker >= last_name: if end_marker and reverse and end_marker >= last_name:
break break
if end_marker and not reverse and end_marker <= last_name: if end_marker and not reverse and end_marker <= last_name:

View File

@ -24,9 +24,7 @@
# These shenanigans are to ensure all related objects can be garbage # These shenanigans are to ensure all related objects can be garbage
# collected. We've seen objects hang around forever otherwise. # collected. We've seen objects hang around forever otherwise.
import six from urllib.parse import quote, unquote
from six.moves.urllib.parse import quote, unquote
from six.moves import zip
import collections import collections
import itertools import itertools
@ -35,7 +33,6 @@ import mimetypes
import time import time
import math import math
import random import random
import sys
from greenlet import GreenletExit from greenlet import GreenletExit
from eventlet import GreenPile from eventlet import GreenPile
@ -1301,8 +1298,6 @@ class ECAppIter(object):
def __next__(self): def __next__(self):
return next(self.stashed_iter) return next(self.stashed_iter)
next = __next__ # py2
def _real_iter(self, req, resp_headers): def _real_iter(self, req, resp_headers):
if not self.range_specs: if not self.range_specs:
client_asked_for_range = False client_asked_for_range = False
@ -2490,13 +2485,12 @@ class ECFragGetter(GetterBase):
buf += chunk buf += chunk
if nbytes is not None: if nbytes is not None:
nbytes -= len(chunk) nbytes -= len(chunk)
except (ChunkReadTimeout, ShortReadError): except (ChunkReadTimeout, ShortReadError) as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
try: try:
self.fast_forward(self.bytes_used_from_backend) self.fast_forward(self.bytes_used_from_backend)
except (HTTPException, ValueError): except (HTTPException, ValueError):
self.logger.exception('Unable to fast forward') self.logger.exception('Unable to fast forward')
six.reraise(exc_type, exc_value, exc_traceback) raise e
except RangeAlreadyComplete: except RangeAlreadyComplete:
break break
buf = b'' buf = b''
@ -2509,10 +2503,10 @@ class ECFragGetter(GetterBase):
# it's not clear to me how to make # it's not clear to me how to make
# _get_next_response_part raise StopIteration for the # _get_next_response_part raise StopIteration for the
# first doc part of a new request # first doc part of a new request
six.reraise(exc_type, exc_value, exc_traceback) raise e
part_file = ByteCountEnforcer(part_file, nbytes) part_file = ByteCountEnforcer(part_file, nbytes)
else: else:
six.reraise(exc_type, exc_value, exc_traceback) raise e
else: else:
if buf and self.skip_bytes: if buf and self.skip_bytes:
if self.skip_bytes < len(buf): if self.skip_bytes < len(buf):

View File

@ -18,7 +18,6 @@ import sys
from contextlib import contextmanager from contextlib import contextmanager
import os import os
from six import reraise
from unittest.util import safe_repr from unittest.util import safe_repr
@ -105,15 +104,15 @@ def annotate_failure(msg):
try: try:
yield yield
except AssertionError as err: except AssertionError as err:
err_typ, err_val, err_tb = sys.exc_info() if err.args:
if err_val.args: msg = '%s Failed with %s' % (msg, err.args[0])
msg = '%s Failed with %s' % (msg, err_val.args[0]) err.args = (msg, ) + err.args[1:]
err_val.args = (msg, ) + err_val.args[1:] raise err
else: else:
# workaround for some IDE's raising custom AssertionErrors # workaround for some IDE's raising custom AssertionErrors
err_val = '%s Failed with %s' % (msg, err) raise AssertionError(
err_typ = AssertionError '%s Failed with %s' % (msg, err)
reraise(err_typ, err_val, err_tb) ).with_traceback(err.__traceback__) from err.__cause__
class BaseTestCase(unittest.TestCase): class BaseTestCase(unittest.TestCase):

View File

@ -24,9 +24,9 @@ import threading
import time import time
import traceback import traceback
from six.moves import urllib import urllib.parse
from six.moves import socketserver import socketserver
from six.moves import SimpleHTTPServer import http.server
try: try:
import selenium.webdriver import selenium.webdriver
@ -51,12 +51,14 @@ TEST_TIMEOUT = 120.0 # seconds
STEPS = 500 STEPS = 500
# Hack up stdlib so SimpleHTTPRequestHandler works well on py2, too class CORSSiteHandler(http.server.SimpleHTTPRequestHandler):
this_dir = os.path.realpath(os.path.dirname(__file__)) def __init__(self, *args, **kwargs):
os.getcwd = lambda: this_dir super().__init__(
*args,
directory=os.path.realpath(os.path.dirname(__file__)),
**kwargs,
)
class CORSSiteHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def log_message(self, fmt, *args): def log_message(self, fmt, *args):
pass # quiet, you! pass # quiet, you!
@ -67,7 +69,7 @@ class CORSSiteServer(socketserver.TCPServer):
class CORSSite(threading.Thread): class CORSSite(threading.Thread):
def __init__(self, bind_port=8000): def __init__(self, bind_port=8000):
super(CORSSite, self).__init__() super().__init__()
self.server = None self.server = None
self.bind_port = bind_port self.bind_port = bind_port

View File

@ -20,8 +20,7 @@ import contextlib
import mock import mock
import os import os
import six from urllib.parse import urlparse, urlsplit, urlunsplit
from six.moves.urllib.parse import urlparse, urlsplit, urlunsplit
import sys import sys
import pickle import pickle
import socket import socket
@ -39,9 +38,9 @@ from shutil import rmtree
from tempfile import mkdtemp from tempfile import mkdtemp
from unittest import SkipTest from unittest import SkipTest
from six.moves.configparser import ConfigParser from configparser import ConfigParser
from six.moves import http_client import http.client
from six.moves.http_client import HTTPException from http.client import HTTPException
from swift.common.middleware.memcache import MemcacheMiddleware from swift.common.middleware.memcache import MemcacheMiddleware
from swift.common.storage_policy import parse_storage_policies, PolicyError from swift.common.storage_policy import parse_storage_policies, PolicyError
@ -65,7 +64,7 @@ from swift.container import server as container_server
from swift.obj import server as object_server, mem_server as mem_object_server from swift.obj import server as object_server, mem_server as mem_object_server
import swift.proxy.controllers.obj import swift.proxy.controllers.obj
http_client._MAXHEADERS = constraints.MAX_HEADER_COUNT http.client._MAXHEADERS = constraints.MAX_HEADER_COUNT
DEBUG = True DEBUG = True
# In order to get the proper blocking behavior of sockets without using # In order to get the proper blocking behavior of sockets without using
@ -357,9 +356,7 @@ def _load_encryption(proxy_conf_file, swift_conf_file, **kwargs):
conf, conf,
"proxy-logging proxy-server", "proxy-logging proxy-server",
"keymaster encryption proxy-logging proxy-server") "keymaster encryption proxy-logging proxy-server")
root_secret = base64.b64encode(os.urandom(32)) root_secret = base64.b64encode(os.urandom(32)).decode('ascii')
if not six.PY2:
root_secret = root_secret.decode('ascii')
conf.set('filter:keymaster', 'encryption_root_secret', root_secret) conf.set('filter:keymaster', 'encryption_root_secret', root_secret)
conf.set('filter:versioned_writes', 'allow_object_versioning', 'true') conf.set('filter:versioned_writes', 'allow_object_versioning', 'true')
conf.set('filter:etag-quoter', 'enable_by_default', 'true') conf.set('filter:etag-quoter', 'enable_by_default', 'true')
@ -1129,10 +1126,6 @@ def get_url_token(user_index, os_options):
swift_test_user[user_index], swift_test_user[user_index],
swift_test_key[user_index], swift_test_key[user_index],
**authargs) **authargs)
if six.PY2 and not isinstance(url, bytes):
url = url.encode('utf-8')
if six.PY2 and not isinstance(token, bytes):
token = token.encode('utf-8')
return url, token return url, token

View File

@ -15,7 +15,7 @@
import logging import logging
import os import os
from six.moves.urllib.parse import urlparse from urllib.parse import urlparse
import test.functional as tf import test.functional as tf
import boto3 import boto3
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
@ -27,7 +27,6 @@ try:
) )
except ImportError: except ImportError:
S3Connection = OrdinaryCallingFormat = S3ResponseError = None S3Connection = OrdinaryCallingFormat = S3ResponseError = None
import six
import sys import sys
import traceback import traceback
@ -96,21 +95,11 @@ class Connection(object):
break break
for bucket in buckets: for bucket in buckets:
if six.PY2 and not isinstance(bucket.name, bytes):
bucket.name = bucket.name.encode('utf-8')
try: try:
for upload in bucket.list_multipart_uploads(): for upload in bucket.list_multipart_uploads():
upload.cancel_upload() upload.cancel_upload()
for obj in bucket.list_versions(): for obj in bucket.list_versions():
if six.PY2:
if not isinstance(obj.name, bytes):
obj.name = obj.name.encode('utf-8')
if obj.version_id is not None and \
not isinstance(obj.version_id, bytes):
obj.version_id = \
obj.version_id.encode('utf-8')
bucket.delete_key( bucket.delete_key(
obj.name, version_id=obj.version_id) obj.name, version_id=obj.version_id)

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import six
import unittest import unittest
import os import os
import test.functional as tf import test.functional as tf
@ -83,8 +82,6 @@ class TestS3ApiMultiDelete(S3ApiBase):
self.assertEqual(len(resp_objects), len(req_objects)) self.assertEqual(len(resp_objects), len(req_objects))
for o in resp_objects: for o in resp_objects:
key = o.find('Key').text key = o.find('Key').text
if six.PY2:
key = key.decode('utf-8')
self.assertTrue(key in req_objects) self.assertTrue(key in req_objects)
# Delete 2 objects via MultiDelete API # Delete 2 objects via MultiDelete API
@ -101,8 +98,6 @@ class TestS3ApiMultiDelete(S3ApiBase):
self.assertEqual(len(resp_objects), len(req_objects)) self.assertEqual(len(resp_objects), len(req_objects))
for o in resp_objects: for o in resp_objects:
key = o.find('Key').text key = o.find('Key').text
if six.PY2:
key = key.decode('utf-8')
self.assertTrue(key in req_objects) self.assertTrue(key in req_objects)
if with_non_ascii: if with_non_ascii:
@ -124,8 +119,6 @@ class TestS3ApiMultiDelete(S3ApiBase):
self.assertEqual(len(resp_objects), len(req_objects)) self.assertEqual(len(resp_objects), len(req_objects))
for o in resp_objects: for o in resp_objects:
key = o.find('Key').text key = o.find('Key').text
if six.PY2:
key = key.decode('utf-8')
self.assertTrue(key in req_objects) self.assertTrue(key in req_objects)
# Delete 2 objects via MultiDelete API but no objects exist # Delete 2 objects via MultiDelete API but no objects exist
@ -142,8 +135,6 @@ class TestS3ApiMultiDelete(S3ApiBase):
self.assertEqual(len(resp_objects), len(req_objects)) self.assertEqual(len(resp_objects), len(req_objects))
for o in resp_objects: for o in resp_objects:
key = o.find('Key').text key = o.find('Key').text
if six.PY2:
key = key.decode('utf-8')
self.assertTrue(key in req_objects) self.assertTrue(key in req_objects)
def test_delete_multi_objects(self): def test_delete_multi_objects(self):

View File

@ -17,8 +17,8 @@ import base64
import binascii import binascii
import unittest import unittest
import six import urllib.parse
from six.moves import urllib, zip, zip_longest from itertools import zip_longest
import test.functional as tf import test.functional as tf
from swift.common.middleware.s3api.etree import fromstring, tostring, \ from swift.common.middleware.s3api.etree import fromstring, tostring, \
@ -135,8 +135,6 @@ class TestS3ApiMultiUpload(S3ApiBase):
elem = fromstring(body, 'InitiateMultipartUploadResult') elem = fromstring(body, 'InitiateMultipartUploadResult')
self.assertEqual(elem.find('Bucket').text, bucket) self.assertEqual(elem.find('Bucket').text, bucket)
key = elem.find('Key').text key = elem.find('Key').text
if six.PY2:
expected_key = expected_key.encode('utf-8')
self.assertEqual(expected_key, key) self.assertEqual(expected_key, key)
upload_id = elem.find('UploadId').text upload_id = elem.find('UploadId').text
self.assertIsNotNone(upload_id) self.assertIsNotNone(upload_id)
@ -475,9 +473,6 @@ class TestS3ApiMultiUpload(S3ApiBase):
resp_objects = list(elem.findall('./Contents')) resp_objects = list(elem.findall('./Contents'))
self.assertEqual(len(resp_objects), 1) self.assertEqual(len(resp_objects), 1)
o = resp_objects[0] o = resp_objects[0]
if six.PY2:
expected_key = keys[0].encode('utf-8')
else:
expected_key = keys[0] expected_key = keys[0]
self.assertEqual(o.find('Key').text, expected_key) self.assertEqual(o.find('Key').text, expected_key)
self.assertIsNotNone(o.find('LastModified').text) self.assertIsNotNone(o.find('LastModified').text)

View File

@ -20,7 +20,6 @@ import calendar
import email.parser import email.parser
from email.utils import formatdate, parsedate from email.utils import formatdate, parsedate
from time import mktime from time import mktime
import six
import test.functional as tf import test.functional as tf
from swift.common import utils from swift.common import utils
@ -787,9 +786,6 @@ class TestS3ApiObject(S3ApiBase):
# TODO: Using swift.common.utils.multipart_byteranges_to_document_iters # TODO: Using swift.common.utils.multipart_byteranges_to_document_iters
# could be easy enough. # could be easy enough.
if six.PY2:
parser = email.parser.FeedParser()
else:
parser = email.parser.BytesFeedParser() parser = email.parser.BytesFeedParser()
parser.feed( parser.feed(
b"Content-Type: multipart/byterange; boundary=%s\r\n\r\n" % b"Content-Type: multipart/byterange; boundary=%s\r\n\r\n" %

View File

@ -15,7 +15,6 @@
# limitations under the License. # limitations under the License.
import requests import requests
import six
import botocore import botocore
@ -62,11 +61,10 @@ class TestS3ApiXxeInjection(S3ApiBaseBoto3):
finally: finally:
self.conn.meta.events.unregister( self.conn.meta.events.unregister(
'before-sign.s3.*', self._clear_data) 'before-sign.s3.*', self._clear_data)
if not params.get('Key') and '/?' not in url and not six.PY2: if not params.get('Key') and '/?' not in url:
# Some combination of dependencies seems to cause bucket requests # Some combination of dependencies seems to cause bucket requests
# to not get the trailing slash despite signing with it? But only # to not get the trailing slash despite signing with it? But only
# new-enough versions sign with the trailing slash; py2 is stuck # new-enough versions sign with the trailing slash
# with old.
url = url.replace('?', '/?') url = url.replace('?', '/?')
return url return url

View File

@ -25,9 +25,8 @@ import time
from unittest import SkipTest from unittest import SkipTest
from xml.dom import minidom from xml.dom import minidom
import six import http.client
from six.moves import http_client import urllib.parse
from six.moves import urllib
from swiftclient import get_auth from swiftclient import get_auth
from swift.common import constraints from swift.common import constraints
@ -37,7 +36,7 @@ from swift.common.utils import config_true_value, md5
from test import safe_repr from test import safe_repr
http_client._MAXHEADERS = constraints.MAX_HEADER_COUNT http.client._MAXHEADERS = constraints.MAX_HEADER_COUNT
class AuthenticationFailed(Exception): class AuthenticationFailed(Exception):
@ -138,10 +137,10 @@ def putrequest(self, method, url, skip_host=False, skip_accept_encoding=False):
and self._HTTPConnection__response.isclosed(): and self._HTTPConnection__response.isclosed():
self._HTTPConnection__response = None self._HTTPConnection__response = None
if self._HTTPConnection__state == http_client._CS_IDLE: if self._HTTPConnection__state == http.client._CS_IDLE:
self._HTTPConnection__state = http_client._CS_REQ_STARTED self._HTTPConnection__state = http.client._CS_REQ_STARTED
else: else:
raise http_client.CannotSendRequest(self._HTTPConnection__state) raise http.client.CannotSendRequest(self._HTTPConnection__state)
self._method = method self._method = method
if not url: if not url:
@ -225,15 +224,12 @@ class Connection(object):
@storage_url.setter @storage_url.setter
def storage_url(self, value): def storage_url(self, value):
if six.PY2 and not isinstance(value, bytes):
value = value.encode('utf-8')
url = urllib.parse.urlparse(value) url = urllib.parse.urlparse(value)
if url.scheme == 'http': if url.scheme == 'http':
self.conn_class = http_client.HTTPConnection self.conn_class = http.client.HTTPConnection
elif url.scheme == 'https': elif url.scheme == 'https':
self.conn_class = http_client.HTTPSConnection self.conn_class = http.client.HTTPSConnection
else: else:
raise ValueError('unexpected protocol %s' % (url.scheme)) raise ValueError('unexpected protocol %s' % (url.scheme))
@ -250,7 +246,7 @@ class Connection(object):
def storage_scheme(self): def storage_scheme(self):
if self.conn_class is None: if self.conn_class is None:
return None return None
if issubclass(self.conn_class, http_client.HTTPSConnection): if issubclass(self.conn_class, http.client.HTTPSConnection):
return 'https' return 'https'
return 'http' return 'http'
@ -411,7 +407,7 @@ class Connection(object):
except socket.timeout as e: except socket.timeout as e:
fail_messages.append(safe_repr(e)) fail_messages.append(safe_repr(e))
continue continue
except http_client.HTTPException as e: except http.client.HTTPException as e:
fail_messages.append(safe_repr(e)) fail_messages.append(safe_repr(e))
continue continue
@ -500,7 +496,7 @@ class Base(object):
'x-container-bytes-used', 'x-container-bytes-used',
) )
# NB: on py2, headers are always lower; on py3, they match the bytes # NB: on py2, headers were always lower; on py3, they match the bytes
# on the wire # on the wire
headers = dict((wsgi_to_str(h).lower(), wsgi_to_str(v)) headers = dict((wsgi_to_str(h).lower(), wsgi_to_str(v))
for h, v in self.conn.response.getheaders()) for h, v in self.conn.response.getheaders())
@ -568,9 +564,6 @@ class Account(Base):
if status == 200: if status == 200:
if format_type == 'json': if format_type == 'json':
conts = json.loads(self.conn.response.read()) conts = json.loads(self.conn.response.read())
if six.PY2:
for cont in conts:
cont['name'] = cont['name'].encode('utf-8')
return conts return conts
elif format_type == 'xml': elif format_type == 'xml':
conts = [] conts = []
@ -582,8 +575,6 @@ class Account(Base):
childNodes[0].nodeValue childNodes[0].nodeValue
conts.append(cont) conts.append(cont)
for cont in conts: for cont in conts:
if six.PY2:
cont['name'] = cont['name'].encode('utf-8')
for key in ('count', 'bytes'): for key in ('count', 'bytes'):
cont[key] = int(cont[key]) cont[key] = int(cont[key])
return conts return conts
@ -591,8 +582,6 @@ class Account(Base):
lines = self.conn.response.read().split(b'\n') lines = self.conn.response.read().split(b'\n')
if lines and not lines[-1]: if lines and not lines[-1]:
lines = lines[:-1] lines = lines[:-1]
if six.PY2:
return lines
return [line.decode('utf-8') for line in lines] return [line.decode('utf-8') for line in lines]
elif status == 204: elif status == 204:
return [] return []
@ -716,15 +705,7 @@ class Container(Base):
parms=parms, cfg=cfg) parms=parms, cfg=cfg)
if status == 200: if status == 200:
if format_type == 'json' or 'versions' in parms: if format_type == 'json' or 'versions' in parms:
files = json.loads(self.conn.response.read()) return json.loads(self.conn.response.read())
if six.PY2:
for file_item in files:
for key in ('name', 'subdir', 'content_type',
'version_id'):
if key in file_item:
file_item[key] = file_item[key].encode('utf-8')
return files
elif format_type == 'xml': elif format_type == 'xml':
files = [] files = []
tree = minidom.parseString(self.conn.response.read()) tree = minidom.parseString(self.conn.response.read())
@ -745,15 +726,7 @@ class Container(Base):
files.append(file_item) files.append(file_item)
for file_item in files: for file_item in files:
if 'subdir' in file_item: if 'bytes' in file_item:
if six.PY2:
file_item['subdir'] = \
file_item['subdir'].encode('utf-8')
else:
if six.PY2:
file_item.update({
k: file_item[k].encode('utf-8')
for k in ('name', 'content_type')})
file_item['bytes'] = int(file_item['bytes']) file_item['bytes'] = int(file_item['bytes'])
return files return files
else: else:
@ -762,8 +735,6 @@ class Container(Base):
lines = content.split(b'\n') lines = content.split(b'\n')
if lines and not lines[-1]: if lines and not lines[-1]:
lines = lines[:-1] lines = lines[:-1]
if six.PY2:
return lines
return [line.decode('utf-8') for line in lines] return [line.decode('utf-8') for line in lines]
else: else:
return [] return []

View File

@ -15,7 +15,7 @@
# limitations under the License. # limitations under the License.
import unittest import unittest
from six.moves.urllib.parse import urlparse, urlunparse from urllib.parse import urlparse, urlunparse
import uuid import uuid
from random import shuffle from random import shuffle

View File

@ -17,11 +17,10 @@
import unittest import unittest
import json import json
import urllib.parse
from uuid import uuid4 from uuid import uuid4
from string import ascii_letters from string import ascii_letters
import six
from six.moves import range, urllib
from swift.common.middleware.acl import format_acl from swift.common.middleware.acl import format_acl
from swift.common.utils import distribute_evenly from swift.common.utils import distribute_evenly
@ -756,40 +755,18 @@ class TestAccount(unittest.TestCase):
def head(url, token, parsed, conn): def head(url, token, parsed, conn):
conn.request('HEAD', parsed.path, '', {'X-Auth-Token': token}) conn.request('HEAD', parsed.path, '', {'X-Auth-Token': token})
return check_response(conn) return check_response(conn)
uni_key = u'X-Account-Meta-uni\u0E12'
uni_value = u'uni\u0E12' uni_value = u'uni\u0E12'
# Note that py3 has issues with non-ascii header names; see # Note that py3 has issues with non-ascii header names; see
# https://bugs.python.org/issue37093 # https://bugs.python.org/issue37093 -- so we won't test with unicode
if (tf.web_front_end == 'integral' and six.PY2): # header names
resp = retry(post, uni_key, '1')
resp.read()
self.assertIn(resp.status, (201, 204))
resp = retry(head)
resp.read()
self.assertIn(resp.status, (200, 204))
self.assertEqual(resp.getheader(uni_key.encode('utf-8')), '1')
resp = retry(post, 'X-Account-Meta-uni', uni_value) resp = retry(post, 'X-Account-Meta-uni', uni_value)
resp.read() resp.read()
self.assertEqual(resp.status, 204) self.assertEqual(resp.status, 204)
resp = retry(head) resp = retry(head)
resp.read() resp.read()
self.assertIn(resp.status, (200, 204)) self.assertIn(resp.status, (200, 204))
if six.PY2:
self.assertEqual(resp.getheader('X-Account-Meta-uni'),
uni_value.encode('utf8'))
else:
self.assertEqual(resp.getheader('X-Account-Meta-uni'), self.assertEqual(resp.getheader('X-Account-Meta-uni'),
uni_value) uni_value)
# See above note about py3 and non-ascii header names
if (tf.web_front_end == 'integral' and six.PY2):
resp = retry(post, uni_key, uni_value)
resp.read()
self.assertEqual(resp.status, 204)
resp = retry(head)
resp.read()
self.assertIn(resp.status, (200, 204))
self.assertEqual(resp.getheader(uni_key.encode('utf-8')),
uni_value.encode('utf-8'))
def test_multi_metadata(self): def test_multi_metadata(self):
if tf.skip: if tf.skip:

View File

@ -17,15 +17,13 @@
import json import json
import unittest import unittest
import urllib.parse
from uuid import uuid4 from uuid import uuid4
from test.functional import check_response, cluster_info, retry, \ from test.functional import check_response, cluster_info, retry, \
requires_acls, load_constraint, requires_policies, SkipTest requires_acls, load_constraint, requires_policies, SkipTest
import test.functional as tf import test.functional as tf
import six
from six.moves import range, urllib
def setUpModule(): def setUpModule():
tf.setup_package() tf.setup_package()
@ -72,11 +70,7 @@ class TestContainer(unittest.TestCase):
return check_response(conn) return check_response(conn)
def delete(url, token, parsed, conn, container, obj): def delete(url, token, parsed, conn, container, obj):
if six.PY2: path = '/'.join([parsed.path, container, obj['name']])
obj_name = obj['name'].encode('utf8')
else:
obj_name = obj['name']
path = '/'.join([parsed.path, container, obj_name])
conn.request('DELETE', path, '', {'X-Auth-Token': token}) conn.request('DELETE', path, '', {'X-Auth-Token': token})
return check_response(conn) return check_response(conn)
@ -219,40 +213,18 @@ class TestContainer(unittest.TestCase):
{'X-Auth-Token': token}) {'X-Auth-Token': token})
return check_response(conn) return check_response(conn)
uni_key = u'X-Container-Meta-uni\u0E12'
uni_value = u'uni\u0E12' uni_value = u'uni\u0E12'
# Note that py3 has issues with non-ascii header names; see # Note that py3 has issues with non-ascii header names; see
# https://bugs.python.org/issue37093 # https://bugs.python.org/issue37093 -- so we won't test with unicode
if (tf.web_front_end == 'integral' and six.PY2): # header names
resp = retry(post, uni_key, '1')
resp.read()
self.assertEqual(resp.status, 204)
resp = retry(head)
resp.read()
self.assertIn(resp.status, (200, 204))
self.assertEqual(resp.getheader(uni_key.encode('utf-8')), '1')
resp = retry(post, 'X-Container-Meta-uni', uni_value) resp = retry(post, 'X-Container-Meta-uni', uni_value)
resp.read() resp.read()
self.assertEqual(resp.status, 204) self.assertEqual(resp.status, 204)
resp = retry(head) resp = retry(head)
resp.read() resp.read()
self.assertIn(resp.status, (200, 204)) self.assertIn(resp.status, (200, 204))
if six.PY2:
self.assertEqual(resp.getheader('X-Container-Meta-uni'),
uni_value.encode('utf-8'))
else:
self.assertEqual(resp.getheader('X-Container-Meta-uni'), self.assertEqual(resp.getheader('X-Container-Meta-uni'),
uni_value) uni_value)
# See above note about py3 and non-ascii header names
if (tf.web_front_end == 'integral' and six.PY2):
resp = retry(post, uni_key, uni_value)
resp.read()
self.assertEqual(resp.status, 204)
resp = retry(head)
resp.read()
self.assertIn(resp.status, (200, 204))
self.assertEqual(resp.getheader(uni_key.encode('utf-8')),
uni_value.encode('utf-8'))
def test_PUT_metadata(self): def test_PUT_metadata(self):
if tf.skip: if tf.skip:
@ -844,9 +816,7 @@ class TestContainer(unittest.TestCase):
# read-only can list containers # read-only can list containers
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIn(self.name, listing) self.assertIn(self.name, listing)
@ -861,9 +831,7 @@ class TestContainer(unittest.TestCase):
resp.read() resp.read()
self.assertEqual(resp.status, 201) self.assertEqual(resp.status, 201)
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIn(new_container_name, listing) self.assertIn(new_container_name, listing)
@ -963,9 +931,7 @@ class TestContainer(unittest.TestCase):
# can list containers # can list containers
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIn(self.name, listing) self.assertIn(self.name, listing)
@ -975,9 +941,7 @@ class TestContainer(unittest.TestCase):
resp.read() resp.read()
self.assertIn(resp.status, (201, 202)) self.assertIn(resp.status, (201, 202))
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIn(new_container_name, listing) self.assertIn(new_container_name, listing)
@ -986,9 +950,7 @@ class TestContainer(unittest.TestCase):
resp.read() resp.read()
self.assertIn(resp.status, (204, 404)) self.assertIn(resp.status, (204, 404))
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertNotIn(new_container_name, listing) self.assertNotIn(new_container_name, listing)
@ -1111,9 +1073,7 @@ class TestContainer(unittest.TestCase):
# can list containers # can list containers
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIn(self.name, listing) self.assertIn(self.name, listing)
@ -1123,9 +1083,7 @@ class TestContainer(unittest.TestCase):
resp.read() resp.read()
self.assertEqual(resp.status, 201) self.assertEqual(resp.status, 201)
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIn(new_container_name, listing) self.assertIn(new_container_name, listing)
@ -1134,9 +1092,7 @@ class TestContainer(unittest.TestCase):
resp.read() resp.read()
self.assertEqual(resp.status, 204) self.assertEqual(resp.status, 204)
resp = retry(get, use_account=3) resp = retry(get, use_account=3)
listing = resp.read() listing = resp.read().decode('utf8')
if not six.PY2:
listing = listing.decode('utf8')
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertNotIn(new_container_name, listing) self.assertNotIn(new_container_name, listing)

Some files were not shown because too many files have changed in this diff Show More