[PATCH] Eliminate the most of explicit py3 conditionals

Michał Górny <[email protected]>
Newsgroups gmane.linux.gentoo.portage.devel
Message-ID <[email protected]>
Eliminate the most of py2/py3 conditions in the code.  Leave a few
where the relevant code is unclear, they will be addressed later.

Closes: https://github.com/gentoo/portage/pull/574
Signed-off-by: Michał Górny <[email protected]>
---
 bin/check-implicit-pointer-usage.py           | 25 ++--------
 bin/chmod-lite.py                             | 11 ++---
 bin/dohtml.py                                 | 11 ++---
 bin/doins.py                                  |  7 ++-
 bin/ebuild                                    | 15 +-----
 bin/filter-bash-environment.py                | 11 ++---
 bin/install.py                                | 19 ++++---
 bin/pid-ns-init                               | 10 ++--
 bin/xattr-helper.py                           | 32 +++---------
 lib/_emerge/DependencyArg.py                  | 10 ----
 lib/_emerge/JobStatusDisplay.py               |  4 +-
 lib/_emerge/Package.py                        |  8 ---
 lib/_emerge/PackageVirtualDbapi.py            |  3 --
 lib/_emerge/SequentialTaskQueue.py            |  3 --
 lib/_emerge/TaskSequence.py                   |  3 --
 lib/_emerge/UseFlagDisplay.py                 |  8 ---
 lib/_emerge/UserQuery.py                      | 17 +++----
 lib/_emerge/actions.py                        |  2 -
 lib/_emerge/resolver/DbapiProvidesIndex.py    |  3 --
 lib/_emerge/resolver/output_helpers.py        | 16 ------
 lib/_emerge/resolver/slot_collision.py        |  8 ---
 lib/portage/__init__.py                       | 49 +++++++------------
 lib/portage/_emirrordist/Config.py            |  4 --
 lib/portage/_selinux.py                       | 12 -----
 lib/portage/_sets/base.py                     |  3 --
 lib/portage/dbapi/porttree.py                 |  7 +--
 lib/portage/dep/__init__.py                   | 18 +------
 lib/portage/dep/soname/SonameAtom.py          |  8 ---
 lib/portage/elog/mod_save_summary.py          |  2 -
 lib/portage/elog/mod_syslog.py                |  4 --
 lib/portage/exception.py                      | 45 ++++-------------
 lib/portage/mail.py                           | 49 +++----------------
 lib/portage/manifest.py                       |  7 ---
 lib/portage/output.py                         |  4 +-
 lib/portage/process.py                        | 16 +-----
 lib/portage/proxy/objectproxy.py              |  6 ---
 lib/portage/repository/config.py              |  6 ---
 .../tests/unicode/test_string_format.py       | 44 ++++-------------
 lib/portage/util/_ShelveUnicodeWrapper.py     | 45 -----------------
 39 files changed, 102 insertions(+), 453 deletions(-)
 delete mode 100644 lib/portage/util/_ShelveUnicodeWrapper.py

diff --git a/bin/check-implicit-pointer-usage.py b/bin/check-implicit-pointer-usage.py
index a49db8107..868e4b3c8 100755
--- a/bin/check-implicit-pointer-usage.py
+++ b/bin/check-implicit-pointer-usage.py
@@ -33,22 +33,10 @@ pointer_pattern = (
     + r"|"
     + r"cast to pointer from integer of different size)")
 
-if sys.hexversion < 0x3000000:
-    # Use encoded byte strings in python-2.x, since the python ebuilds are
-    # known to remove the encodings module when USE=build is enabled (thus
-    # disabling unicode decoding/encoding). The portage module has a
-    # workaround for this, but currently we don't import that here since we
-    # don't want to trigger potential sandbox violations due to stale pyc
-    # files for the portage module.
-    unicode_quote_open = '\xE2\x80\x98'
-    unicode_quote_close = '\xE2\x80\x99'
-    def write(msg):
-        sys.stdout.write(msg)
-else:
-    unicode_quote_open = '\u2018'
-    unicode_quote_close = '\u2019'
-    def write(msg):
-        sys.stdout.buffer.write(msg.encode('utf_8', 'backslashreplace'))
+unicode_quote_open = '\u2018'
+unicode_quote_close = '\u2019'
+def write(msg):
+    sys.stdout.buffer.write(msg.encode('utf_8', 'backslashreplace'))
 
 pointer_pattern = re.compile(pointer_pattern)
 
@@ -57,10 +45,7 @@ last_implicit_linenum = -1
 last_implicit_func = ""
 
 while True:
-    if sys.hexversion >= 0x3000000:
-        line = sys.stdin.buffer.readline().decode('utf_8', 'replace')
-    else:
-        line = sys.stdin.readline()
+    line = sys.stdin.buffer.readline().decode('utf_8', 'replace')
     if not line:
         break
     # translate unicode open/close quotes to ascii ones
diff --git a/bin/chmod-lite.py b/bin/chmod-lite.py
index 177be7eab..7fe743ed1 100755
--- a/bin/chmod-lite.py
+++ b/bin/chmod-lite.py
@@ -12,12 +12,11 @@ os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
 
 def main(files):
 
-	if sys.hexversion >= 0x3000000:
-		# We can't trust that the filesystem encoding (locale dependent)
-		# correctly matches the arguments, so use surrogateescape to
-		# pass through the original argv bytes for Python 3.
-		fs_encoding = sys.getfilesystemencoding()
-		files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
+	# We can't trust that the filesystem encoding (locale dependent)
+	# correctly matches the arguments, so use surrogateescape to
+	# pass through the original argv bytes for Python 3.
+	fs_encoding = sys.getfilesystemencoding()
+	files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
 
 	for filename in files:
 		# Emulate 'chmod -fR a+rX,u+w,g-w,o-w' with minimal chmod calls.
diff --git a/bin/dohtml.py b/bin/dohtml.py
index df8552b83..67c5eb9d1 100755
--- a/bin/dohtml.py
+++ b/bin/dohtml.py
@@ -163,12 +163,11 @@ def print_help():
 def parse_args():
 	argv = sys.argv[:]
 
-	if sys.hexversion >= 0x3000000:
-		# We can't trust that the filesystem encoding (locale dependent)
-		# correctly matches the arguments, so use surrogateescape to
-		# pass through the original argv bytes for Python 3.
-		fs_encoding = sys.getfilesystemencoding()
-		argv = [x.encode(fs_encoding, 'surrogateescape') for x in argv]
+	# We can't trust that the filesystem encoding (locale dependent)
+	# correctly matches the arguments, so use surrogateescape to
+	# pass through the original argv bytes for Python 3.
+	fs_encoding = sys.getfilesystemencoding()
+	argv = [x.encode(fs_encoding, 'surrogateescape') for x in argv]
 
 	for x, arg in enumerate(argv):
 		try:
diff --git a/bin/doins.py b/bin/doins.py
index 6bc30c90b..98dc4f810 100644
--- a/bin/doins.py
+++ b/bin/doins.py
@@ -514,10 +514,9 @@ def _parse_args(argv):
 
 	# Encode back to the original byte stream. Please see
 	# http://bugs.python.org/issue8776.
-	if sys.version_info.major >= 3:
-		opts.distdir = os.fsencode(opts.distdir) + b'/'
-		opts.dest = os.fsencode(opts.dest)
-		opts.sources = [os.fsencode(source) for source in opts.sources]
+	opts.distdir = os.fsencode(opts.distdir) + b'/'
+	opts.dest = os.fsencode(opts.dest)
+	opts.sources = [os.fsencode(source) for source in opts.sources]
 
 	return opts
 
diff --git a/bin/ebuild b/bin/ebuild
index 460aa0fd1..ea02fa95a 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -144,9 +144,6 @@ if not os.path.isabs(ebuild):
 	# the canonical path returned from os.getcwd() may may be unusable in
 	# cases where the directory stucture is built from symlinks.
 	pwd = os.environ.get('PWD', '')
-	if sys.hexversion < 0x3000000:
-		pwd = _unicode_decode(pwd, encoding=_encodings['content'],
-			errors='strict')
 	if pwd and pwd != mycwd and \
 		os.path.realpath(pwd) == mycwd:
 		mycwd = portage.normalize_path(pwd)
@@ -163,16 +160,8 @@ vdb_path = os.path.realpath(os.path.join(portage.settings['EROOT'], VDB_PATH))
 if ebuild_portdir != vdb_path and \
 	ebuild_portdir not in portage.portdb.porttrees:
 	portdir_overlay = portage.settings.get("PORTDIR_OVERLAY", "")
-	if sys.hexversion >= 0x3000000:
-		os.environ["PORTDIR_OVERLAY"] = \
-			portdir_overlay + \
-			" " + _shell_quote(ebuild_portdir)
-	else:
-		os.environ["PORTDIR_OVERLAY"] = \
-			_unicode_encode(portdir_overlay,
-			encoding=_encodings['content'], errors='strict') + \
-			" " + _unicode_encode(_shell_quote(ebuild_portdir),
-			encoding=_encodings['content'], errors='strict')
+	os.environ["PORTDIR_OVERLAY"] = (
+		portdir_overlay + " " + _shell_quote(ebuild_portdir))
 
 	print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
 	portage._reset_legacy_globals()
diff --git a/bin/filter-bash-environment.py b/bin/filter-bash-environment.py
index 045ea6f52..5e82fc91c 100755
--- a/bin/filter-bash-environment.py
+++ b/bin/filter-bash-environment.py
@@ -136,14 +136,9 @@ if __name__ == "__main__":
 		sys.stderr.flush()
 		sys.exit(2)
 
-	file_in = sys.stdin
-	file_out = sys.stdout
-	if sys.hexversion >= 0x3000000:
-		file_in = sys.stdin.buffer
-		file_out = sys.stdout.buffer
-		var_pattern = os.fsencode(args[0]).split()
-	else:
-		var_pattern = args[0].split()
+	file_in = sys.stdin.buffer
+	file_out = sys.stdout.buffer
+	var_pattern = os.fsencode(args[0]).split()
 
 	# Filter invalid variable names that are not supported by bash.
 	var_pattern.append(br'\d.*')
diff --git a/bin/install.py b/bin/install.py
index 495534d33..c013f07e5 100755
--- a/bin/install.py
+++ b/bin/install.py
@@ -232,16 +232,15 @@ def main(args):
 	cmdline = [install_binary]
 	cmdline += args
 
-	if sys.hexversion >= 0x3000000:
-		# We can't trust that the filesystem encoding (locale dependent)
-		# correctly matches the arguments, so use surrogateescape to
-		# pass through the original argv bytes for Python 3.
-		fs_encoding = sys.getfilesystemencoding()
-		cmdline = [x.encode(fs_encoding, 'surrogateescape') for x in cmdline]
-		files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
-		if opts.target_directory is not None:
-			opts.target_directory = \
-				opts.target_directory.encode(fs_encoding, 'surrogateescape')
+	# We can't trust that the filesystem encoding (locale dependent)
+	# correctly matches the arguments, so use surrogateescape to
+	# pass through the original argv bytes for Python 3.
+	fs_encoding = sys.getfilesystemencoding()
+	cmdline = [x.encode(fs_encoding, 'surrogateescape') for x in cmdline]
+	files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
+	if opts.target_directory is not None:
+		opts.target_directory = \
+			opts.target_directory.encode(fs_encoding, 'surrogateescape')
 
 	returncode = subprocess.call(cmdline)
 	if returncode == os.EX_OK:
diff --git a/bin/pid-ns-init b/bin/pid-ns-init
index 18c74f799..3a218a5df 100644
--- a/bin/pid-ns-init
+++ b/bin/pid-ns-init
@@ -39,7 +39,7 @@ def preexec_fn(uid, gid, groups, umask):
 		os.umask(umask)
 
 	# CPython >= 3 subprocess.Popen handles this internally.
-	if sys.version_info.major < 3 or platform.python_implementation() != 'CPython':
+	if platform.python_implementation() != 'CPython':
 		for signum in (
 			signal.SIGHUP,
 			signal.SIGINT,
@@ -70,10 +70,10 @@ def main(argv):
 		groups = tuple(int(group) for group in groups.split(',')) if groups else None
 		umask = int(umask) if umask else None
 
-		popen_kwargs = {}
-		popen_kwargs['preexec_fn'] = functools.partial(preexec_fn, uid, gid, groups, umask)
-		if sys.version_info.major > 2:
-			popen_kwargs['pass_fds'] = pass_fds
+		popen_kwargs = {
+			'preexec_fn': functools.partial(preexec_fn, uid, gid, groups, umask),
+			'pass_fds': pass_fds,
+		}
 		# Isolate parent process from process group SIGSTOP (bug 675870)
 		setsid = True
 		os.setsid()
diff --git a/bin/xattr-helper.py b/bin/xattr-helper.py
index 49c981580..7658934a0 100755
--- a/bin/xattr-helper.py
+++ b/bin/xattr-helper.py
@@ -26,24 +26,14 @@ _UNQUOTE_RE = re.compile(br'\\[0-7]{3}')
 _FS_ENCODING = sys.getfilesystemencoding()
 
 
-if sys.hexversion < 0x3000000:
+def octal_quote_byte(b):
+	return ('\\%03o' % ord(b)).encode('ascii')
 
-	def octal_quote_byte(b):
-		return b'\\%03o' % ord(b)
 
-	def unicode_encode(s):
-		if isinstance(s, unicode):
-			s = s.encode(_FS_ENCODING)
-		return s
-else:
-
-	def octal_quote_byte(b):
-		return ('\\%03o' % ord(b)).encode('ascii')
-
-	def unicode_encode(s):
-		if isinstance(s, str):
-			s = s.encode(_FS_ENCODING, 'surrogateescape')
-		return s
+def unicode_encode(s):
+	if isinstance(s, str):
+		s = s.encode(_FS_ENCODING, 'surrogateescape')
+	return s
 
 
 def quote(s, quote_chars):
@@ -157,20 +147,14 @@ def main(argv):
 
 	options = parser.parse_args(argv)
 
-	if sys.hexversion >= 0x3000000:
-		file_in = sys.stdin.buffer.raw
-	else:
-		file_in = sys.stdin
+	file_in = sys.stdin.buffer.raw
 
 	if options.dump:
 		if options.paths:
 			options.paths = [unicode_encode(x) for x in options.paths]
 		else:
 			options.paths = [x for x in file_in.read().split(b'\0') if x]
-		if sys.hexversion >= 0x3000000:
-			file_out = sys.stdout.buffer
-		else:
-			file_out = sys.stdout
+		file_out = sys.stdout.buffer
 		dump_xattrs(options.paths, file_out)
 
 	elif options.restore:
diff --git a/lib/_emerge/DependencyArg.py b/lib/_emerge/DependencyArg.py
index 87f255f10..a997f0f90 100644
--- a/lib/_emerge/DependencyArg.py
+++ b/lib/_emerge/DependencyArg.py
@@ -31,14 +31,4 @@ class DependencyArg(object):
 		return hash((self.arg, self.root_config.root))
 
 	def __str__(self):
-		# Use unicode_literals format string for python-2.x safety,
-		# ensuring that self.arg.__unicode__() is used
-		# when necessary.
 		return "%s" % (self.arg,)
-
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(), encoding=_encodings['content'])
diff --git a/lib/_emerge/JobStatusDisplay.py b/lib/_emerge/JobStatusDisplay.py
index b3160a4cc..2ef3f8465 100644
--- a/lib/_emerge/JobStatusDisplay.py
+++ b/lib/_emerge/JobStatusDisplay.py
@@ -83,9 +83,7 @@ class JobStatusDisplay(object):
 		# avoid potential UnicodeEncodeError
 		s = _unicode_encode(s,
 			encoding=_encodings['stdio'], errors='backslashreplace')
-		out = self.out
-		if sys.hexversion >= 0x3000000:
-			out = out.buffer
+		out = self.out.buffer
 		out.write(s)
 		out.flush()
 
diff --git a/lib/_emerge/Package.py b/lib/_emerge/Package.py
index 76f4066bb..1fb0bb20b 100644
--- a/lib/_emerge/Package.py
+++ b/lib/_emerge/Package.py
@@ -528,14 +528,6 @@ class Package(Task):
 		s += ")"
 		return s
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'])
-
 	class _use_class(object):
 
 		__slots__ = ("enabled", "_expand", "_expand_hidden",
diff --git a/lib/_emerge/PackageVirtualDbapi.py b/lib/_emerge/PackageVirtualDbapi.py
index 26293dd98..957eab594 100644
--- a/lib/_emerge/PackageVirtualDbapi.py
+++ b/lib/_emerge/PackageVirtualDbapi.py
@@ -41,9 +41,6 @@ class PackageVirtualDbapi(dbapi):
 	def __bool__(self):
 		return bool(self._cpv_map)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
 	def __iter__(self):
 		return iter(self._cpv_map.values())
 
diff --git a/lib/_emerge/SequentialTaskQueue.py b/lib/_emerge/SequentialTaskQueue.py
index d2551b1c6..1cadbca41 100644
--- a/lib/_emerge/SequentialTaskQueue.py
+++ b/lib/_emerge/SequentialTaskQueue.py
@@ -85,8 +85,5 @@ class SequentialTaskQueue(SlotObject):
 	def __bool__(self):
 		return bool(self._task_queue or self.running_tasks)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
 	def __len__(self):
 		return len(self._task_queue) + len(self.running_tasks)
diff --git a/lib/_emerge/TaskSequence.py b/lib/_emerge/TaskSequence.py
index 1f2ba94c2..2fd349810 100644
--- a/lib/_emerge/TaskSequence.py
+++ b/lib/_emerge/TaskSequence.py
@@ -54,8 +54,5 @@ class TaskSequence(CompositeTask):
 	def __bool__(self):
 		return bool(self._task_queue)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
 	def __len__(self):
 		return len(self._task_queue)
diff --git a/lib/_emerge/UseFlagDisplay.py b/lib/_emerge/UseFlagDisplay.py
index c16e7ba0d..6f6e27fb8 100644
--- a/lib/_emerge/UseFlagDisplay.py
+++ b/lib/_emerge/UseFlagDisplay.py
@@ -30,14 +30,6 @@ class UseFlagDisplay(object):
 			s = '(%s)' % s
 		return s
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'])
-
 	def _cmp_combined(a, b):
 		"""
 		Sort by name, combining enabled and disabled flags.
diff --git a/lib/_emerge/UserQuery.py b/lib/_emerge/UserQuery.py
index faa32cf50..a9b3a4865 100644
--- a/lib/_emerge/UserQuery.py
+++ b/lib/_emerge/UserQuery.py
@@ -54,17 +54,12 @@ class UserQuery(object):
 		print(bold(prompt), end=' ')
 		try:
 			while True:
-				if sys.hexversion >= 0x3000000:
-					try:
-						response = input("[%s] " %
-							"/".join([colours[i](responses[i])
-							for i in range(len(responses))]))
-					except UnicodeDecodeError as e:
-						response = _unicode_decode(e.object).rstrip('\n')
-				else:
-					response=raw_input("["+"/".join([colours[i](responses[i])
-									  for i in range(len(responses))])+"] ")
-					response = _unicode_decode(response)
+				try:
+					response = input("[%s] " %
+						"/".join([colours[i](responses[i])
+						for i in range(len(responses))]))
+				except UnicodeDecodeError as e:
+					response = _unicode_decode(e.object).rstrip('\n')
 				if response or not enter_invalid:
 					for key in responses:
 						# An empty response will match the
diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
index dc54372a3..e717bc828 100644
--- a/lib/_emerge/actions.py
+++ b/lib/_emerge/actions.py
@@ -3194,8 +3194,6 @@ def run_action(emerge_config):
 
 	if not "--pretend" in emerge_config.opts:
 		time_fmt = "%b %d, %Y %H:%M:%S"
-		if sys.hexversion < 0x3000000:
-			time_fmt = portage._unicode_encode(time_fmt)
 		time_str = time.strftime(time_fmt, time.localtime(time.time()))
 		# Avoid potential UnicodeDecodeError in Python 2, since strftime
 		# returns bytes in Python 2, and %b may contain non-ascii chars.
diff --git a/lib/_emerge/resolver/DbapiProvidesIndex.py b/lib/_emerge/resolver/DbapiProvidesIndex.py
index 1650edd4e..9d122a7e5 100644
--- a/lib/_emerge/resolver/DbapiProvidesIndex.py
+++ b/lib/_emerge/resolver/DbapiProvidesIndex.py
@@ -73,9 +73,6 @@ class PackageDbapiProvidesIndex(DbapiProvidesIndex):
 	def __bool__(self):
 		return bool(self._db)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
 	def __iter__(self):
 		return iter(self._db)
 
diff --git a/lib/_emerge/resolver/output_helpers.py b/lib/_emerge/resolver/output_helpers.py
index 4279590dc..0616bb6ac 100644
--- a/lib/_emerge/resolver/output_helpers.py
+++ b/lib/_emerge/resolver/output_helpers.py
@@ -76,14 +76,6 @@ class _RepoDisplay(object):
 				" indicates that the source repository could not be determined\n")
 		return "".join(output)
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'])
-
 
 class _PackageCounters(object):
 
@@ -677,11 +669,3 @@ class PkgAttrDisplay(SlotObject):
 			output.append(self.mask)
 
 		return "".join(output)
-
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'])
diff --git a/lib/_emerge/resolver/slot_collision.py b/lib/_emerge/resolver/slot_collision.py
index 0bed08785..e77433fb8 100644
--- a/lib/_emerge/resolver/slot_collision.py
+++ b/lib/_emerge/resolver/slot_collision.py
@@ -1130,14 +1130,6 @@ class _solution_candidate_generator(object):
 		def __str__(self):
 			return "%s" % (self.value,)
 
-		if sys.hexversion < 0x3000000:
-
-			__unicode__ = __str__
-
-			def __str__(self):
-				return _unicode_encode(self.__unicode__(),
-					encoding=_encodings['content'], errors='backslashreplace')
-
 	def __init__(self, all_involved_flags):
 		#A copy of all_involved_flags with all "cond" values
 		#replaced by a _value_helper object.
diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
index 8ac899f7b..2c44376cb 100644
--- a/lib/portage/__init__.py
+++ b/lib/portage/__init__.py
@@ -163,43 +163,30 @@ _encodings = {
 	'stdio'                  : 'utf_8',
 }
 
-if sys.hexversion >= 0x3000000:
-
-	def _decode_argv(argv):
-		# With Python 3, the surrogateescape encoding error handler makes it
-		# possible to access the original argv bytes, which can be useful
-		# if their actual encoding does no match the filesystem encoding.
-		fs_encoding = sys.getfilesystemencoding()
-		return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape'))
-			for x in argv]
-
-	def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
-		if isinstance(s, str):
-			s = s.encode(encoding, errors)
-		return s
 
-	def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
-		if isinstance(s, bytes):
-			s = str(s, encoding=encoding, errors=errors)
-		return s
+def _decode_argv(argv):
+	# With Python 3, the surrogateescape encoding error handler makes it
+	# possible to access the original argv bytes, which can be useful
+	# if their actual encoding does no match the filesystem encoding.
+	fs_encoding = sys.getfilesystemencoding()
+	return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape'))
+		for x in argv]
 
-	_native_string = _unicode_decode
-else:
 
-	def _decode_argv(argv):
-		return [_unicode_decode(x) for x in argv]
+def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
+	if isinstance(s, str):
+		s = s.encode(encoding, errors)
+	return s
 
-	def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
-		if isinstance(s, unicode):
-			s = s.encode(encoding, errors)
-		return s
 
-	def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
-		if isinstance(s, bytes):
-			s = unicode(s, encoding=encoding, errors=errors)
-		return s
+def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
+	if isinstance(s, bytes):
+		s = str(s, encoding=encoding, errors=errors)
+	return s
+
+
+_native_string = _unicode_decode
 
-	_native_string = _unicode_encode
 
 class _unicode_func_wrapper(object):
 	"""
diff --git a/lib/portage/_emirrordist/Config.py b/lib/portage/_emirrordist/Config.py
index c1f59f725..d5dea7ab4 100644
--- a/lib/portage/_emirrordist/Config.py
+++ b/lib/portage/_emirrordist/Config.py
@@ -12,7 +12,6 @@ import portage
 from portage import os
 from portage.package.ebuild.fetch import MirrorLayoutConfig
 from portage.util import grabdict, grablines
-from portage.util._ShelveUnicodeWrapper import ShelveUnicodeWrapper
 
 class Config(object):
 	def __init__(self, options, portdb, event_loop):
@@ -126,9 +125,6 @@ class Config(object):
 					from bsddb3 import dbshelve
 					db = dbshelve.open(db_file, flags=open_flag)
 
-			if sys.hexversion < 0x3000000:
-				db = ShelveUnicodeWrapper(db)
-
 		if self.options.dry_run:
 			logging.warning("dry-run: %s db opened in readonly mode" % db_desc)
 			if not isinstance(db, dict):
diff --git a/lib/portage/_selinux.py b/lib/portage/_selinux.py
index 49e2e8e58..a64215f27 100644
--- a/lib/portage/_selinux.py
+++ b/lib/portage/_selinux.py
@@ -23,8 +23,6 @@ def copyfile(src, dest):
 	dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
 	(rc, ctx) = selinux.lgetfilecon(src)
 	if rc < 0:
-		if sys.hexversion < 0x3000000:
-			src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
 		raise OSError(_("copyfile: Failed getting context of \"%s\".") % src)
 
 	setfscreate(ctx)
@@ -48,8 +46,6 @@ def mkdir(target, refdir):
 	refdir = _native_string(refdir, encoding=_encodings['fs'], errors='strict')
 	(rc, ctx) = selinux.getfilecon(refdir)
 	if rc < 0:
-		if sys.hexversion < 0x3000000:
-			refdir = _unicode_decode(refdir, encoding=_encodings['fs'], errors='replace')
 		raise OSError(
 			_("mkdir: Failed getting context of reference directory \"%s\".") \
 			% refdir)
@@ -65,8 +61,6 @@ def rename(src, dest):
 	dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
 	(rc, ctx) = selinux.lgetfilecon(src)
 	if rc < 0:
-		if sys.hexversion < 0x3000000:
-			src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
 		raise OSError(_("rename: Failed getting context of \"%s\".") % src)
 
 	setfscreate(ctx)
@@ -98,8 +92,6 @@ def setexec(ctx="\n"):
 			portage.writemsg("!!! %s\n" % msg, noiselevel=-1)
 
 	if rc < 0:
-		if sys.hexversion < 0x3000000:
-			ctx = _unicode_decode(ctx, encoding=_encodings['content'], errors='replace')
 		if selinux.security_getenforce() == 1:
 			raise OSError(_("Failed setting exec() context \"%s\".") % ctx)
 		else:
@@ -110,8 +102,6 @@ def setexec(ctx="\n"):
 def setfscreate(ctx="\n"):
 	ctx = _native_string(ctx, encoding=_encodings['content'], errors='strict')
 	if selinux.setfscreatecon(ctx) < 0:
-		if sys.hexversion < 0x3000000:
-			ctx = _unicode_decode(ctx, encoding=_encodings['content'], errors='replace')
 		raise OSError(
 			_("setfscreate: Failed setting fs create context \"%s\".") % ctx)
 
@@ -148,8 +138,6 @@ def symlink(target, link, reflnk):
 	reflnk = _native_string(reflnk, encoding=_encodings['fs'], errors='strict')
 	(rc, ctx) = selinux.lgetfilecon(reflnk)
 	if rc < 0:
-		if sys.hexversion < 0x3000000:
-			reflnk = _unicode_decode(reflnk, encoding=_encodings['fs'], errors='replace')
 		raise OSError(
 			_("symlink: Failed getting context of reference symlink \"%s\".") \
 			% reflnk)
diff --git a/lib/portage/_sets/base.py b/lib/portage/_sets/base.py
index 4d0a42179..a9c898da7 100644
--- a/lib/portage/_sets/base.py
+++ b/lib/portage/_sets/base.py
@@ -43,9 +43,6 @@ class PackageSet(object):
 		self._load()
 		return bool(self._atoms or self._nonatoms)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
 	def supportsOperation(self, op):
 		if not op in OPERATIONS:
 			raise ValueError(op)
diff --git a/lib/portage/dbapi/porttree.py b/lib/portage/dbapi/porttree.py
index da337ad0e..4916114cd 100644
--- a/lib/portage/dbapi/porttree.py
+++ b/lib/portage/dbapi/porttree.py
@@ -1455,12 +1455,7 @@ class FetchlistDict(Mapping):
 		infinite recursion in some cases."""
 		return len(self.portdb.cp_list(self.cp, mytree=self.mytree))
 
-	def keys(self):
-		"""Returns keys for all packages within pkgdir"""
-		return self.portdb.cp_list(self.cp, mytree=self.mytree)
-
-	if sys.hexversion >= 0x3000000:
-		keys = __iter__
+	keys = __iter__
 
 
 def _async_manifest_fetchlist(portdb, repo_config, cp, cpv_list=None,
diff --git a/lib/portage/dep/__init__.py b/lib/portage/dep/__init__.py
index baeea4bf7..bfb957d89 100644
--- a/lib/portage/dep/__init__.py
+++ b/lib/portage/dep/__init__.py
@@ -960,22 +960,11 @@ class _use_dep(object):
 	def __bool__(self):
 		return bool(self.tokens)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
 	def __str__(self):
 		if not self.tokens:
 			return ""
 		return "[%s]" % (",".join(self.tokens),)
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'], errors='backslashreplace')
-
 	def __repr__(self):
 		return "portage.dep._use_dep(%s)" % repr(self.tokens)
 
@@ -1715,9 +1704,8 @@ class ExtendedAtomDict(portage.cache.mappings.MutableMapping):
 		else:
 			return self._normal.__delitem__(cp)
 
-	if sys.hexversion >= 0x3000000:
-		keys = __iter__
-		items = iteritems
+	keys = __iter__
+	items = iteritems
 
 	def __len__(self):
 		return len(self._normal) + len(self._extended)
@@ -2575,8 +2563,6 @@ class _RequiredUseBranch(object):
 
 		return " ".join(tokens)
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
 
 def check_required_use(required_use, use, iuse_match, eapi=None):
 	"""
diff --git a/lib/portage/dep/soname/SonameAtom.py b/lib/portage/dep/soname/SonameAtom.py
index 12d79386b..2dae03c36 100644
--- a/lib/portage/dep/soname/SonameAtom.py
+++ b/lib/portage/dep/soname/SonameAtom.py
@@ -56,14 +56,6 @@ class SonameAtom(object):
 	def __str__(self):
 		return "%s: %s" % (self.multilib_category, self.soname)
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'])
-
 	def match(self, pkg):
 		"""
 		Check if the given package instance matches this atom. Unbuilt
diff --git a/lib/portage/elog/mod_save_summary.py b/lib/portage/elog/mod_save_summary.py
index 48c006037..7aa6f2bef 100644
--- a/lib/portage/elog/mod_save_summary.py
+++ b/lib/portage/elog/mod_save_summary.py
@@ -73,8 +73,6 @@ def process(mysettings, key, logentries, fulltext):
 		mode=elogdir_grp_mode, mask=0)
 
 	time_fmt = "%Y-%m-%d %H:%M:%S %Z"
-	if sys.hexversion < 0x3000000:
-		time_fmt = _unicode_encode(time_fmt)
 	time_str = time.strftime(time_fmt, time.localtime(time.time()))
 	# Avoid potential UnicodeDecodeError in Python 2, since strftime
 	# returns bytes in Python 2, and %Z may contain non-ascii chars.
diff --git a/lib/portage/elog/mod_syslog.py b/lib/portage/elog/mod_syslog.py
index d2ad89d65..e5d1bbca8 100644
--- a/lib/portage/elog/mod_syslog.py
+++ b/lib/portage/elog/mod_syslog.py
@@ -26,9 +26,5 @@ def process(mysettings, key, logentries, fulltext):
 				msgcontent = [msgcontent]
 			for line in msgcontent:
 				line = "%s: %s: %s" % (key, phase, line)
-				if sys.hexversion < 0x3000000 and not isinstance(line, bytes):
-					# Avoid TypeError from syslog.syslog()
-					line = line.encode(_encodings['content'],
-						'backslashreplace')
 				syslog.syslog(_pri[msgtype], line.rstrip("\n"))
 	syslog.closelog()
diff --git a/lib/portage/exception.py b/lib/portage/exception.py
index fa59f1f14..e2be95c1e 100644
--- a/lib/portage/exception.py
+++ b/lib/portage/exception.py
@@ -9,35 +9,15 @@ from portage.localization import _
 
 class PortageException(Exception):
 	"""General superclass for portage exceptions"""
-	if sys.hexversion >= 0x3000000:
-		def __init__(self, value):
-			self.value = value[:]
-
-		def __str__(self):
-			if isinstance(self.value, str):
-				return self.value
-			else:
-				return repr(self.value)
-	else:
-		def __init__(self, value):
-			self.value = value[:]
-			if isinstance(self.value, str):
-				self.value = _unicode_decode(self.value,
-					encoding=_encodings['content'], errors='replace')
-
-		def __unicode__(self):
-			if isinstance(self.value, unicode):
-				return self.value
-			else:
-				return _unicode_decode(repr(self.value),
-					encoding=_encodings['content'], errors='replace')
-
-		def __str__(self):
-			if isinstance(self.value, unicode):
-				return _unicode_encode(self.value,
-					encoding=_encodings['content'], errors='backslashreplace')
-			else:
-				return repr(self.value)
+	def __init__(self, value):
+		self.value = value[:]
+
+	def __str__(self):
+		if isinstance(self.value, str):
+			return self.value
+		else:
+			return repr(self.value)
+
 
 class PortageKeyError(KeyError, PortageException):
 	__doc__ = KeyError.__doc__
@@ -187,13 +167,6 @@ class UnsupportedAPIException(PortagePackageException):
 		return _unicode_decode(msg,
 			encoding=_encodings['content'], errors='replace')
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['content'], errors='backslashreplace')
 
 class SignatureException(PortageException):
 	"""Signature was not present in the checked file"""
diff --git a/lib/portage/mail.py b/lib/portage/mail.py
index 6a351aa24..730c9352e 100644
--- a/lib/portage/mail.py
+++ b/lib/portage/mail.py
@@ -19,20 +19,15 @@ from portage import _unicode_decode, _unicode_encode
 from portage.localization import _
 import portage
 
-if sys.hexversion >= 0x3000000:
-	def _force_ascii_if_necessary(s):
-		# Force ascii encoding in order to avoid UnicodeEncodeError
-		# from smtplib.sendmail with python3 (bug #291331).
-		s = _unicode_encode(s,
-			encoding='ascii', errors='backslashreplace')
-		s = _unicode_decode(s,
-			encoding='ascii', errors='replace')
-		return s
+def _force_ascii_if_necessary(s):
+	# Force ascii encoding in order to avoid UnicodeEncodeError
+	# from smtplib.sendmail with python3 (bug #291331).
+	s = _unicode_encode(s,
+		encoding='ascii', errors='backslashreplace')
+	s = _unicode_decode(s,
+		encoding='ascii', errors='replace')
+	return s
 
-else:
-
-	def _force_ascii_if_necessary(s):
-		return s
 
 def TextMessage(_text):
 	from email.mime.text import MIMEText
@@ -47,16 +42,6 @@ def create_message(sender, recipient, subject, body, attachments=None):
 	from email.mime.multipart import MIMEMultipart as MultipartMessage
 	from email.utils import formatdate
 
-	if sys.hexversion < 0x3000000:
-		sender = _unicode_encode(sender,
-			encoding=_encodings['content'], errors='strict')
-		recipient = _unicode_encode(recipient,
-			encoding=_encodings['content'], errors='strict')
-		subject = _unicode_encode(subject,
-			encoding=_encodings['content'], errors='backslashreplace')
-		body = _unicode_encode(body,
-			encoding=_encodings['content'], errors='backslashreplace')
-
 	if attachments == None:
 		mymessage = TextMessage(body)
 	else:
@@ -66,10 +51,6 @@ def create_message(sender, recipient, subject, body, attachments=None):
 			if isinstance(x, BaseMessage):
 				mymessage.attach(x)
 			elif isinstance(x, str):
-				if sys.hexversion < 0x3000000:
-					x = _unicode_encode(x,
-						encoding=_encodings['content'],
-						errors='backslashreplace')
 				mymessage.attach(TextMessage(x))
 			else:
 				raise portage.exception.PortageException(_("Can't handle type of attachment: %s") % type(x))
@@ -129,20 +110,6 @@ def send_mail(mysettings, message):
 
 	myfrom = message.get("From")
 
-	if sys.hexversion < 0x3000000:
-		myrecipient = _unicode_encode(myrecipient,
-			encoding=_encodings['content'], errors='strict')
-		mymailhost = _unicode_encode(mymailhost,
-			encoding=_encodings['content'], errors='strict')
-		mymailport = _unicode_encode(mymailport,
-			encoding=_encodings['content'], errors='strict')
-		myfrom = _unicode_encode(myfrom,
-			encoding=_encodings['content'], errors='strict')
-		mymailuser = _unicode_encode(mymailuser,
-			encoding=_encodings['content'], errors='strict')
-		mymailpasswd = _unicode_encode(mymailpasswd,
-			encoding=_encodings['content'], errors='strict')
-
 	# user wants to use a sendmail binary instead of smtp
 	if mymailhost[0] == os.sep and os.path.exists(mymailhost):
 		fd = os.popen(mymailhost+" -f "+myfrom+" "+myrecipient, "w")
diff --git a/lib/portage/manifest.py b/lib/portage/manifest.py
index b2c3923a1..7671bae34 100644
--- a/lib/portage/manifest.py
+++ b/lib/portage/manifest.py
@@ -107,13 +107,6 @@ class Manifest2Entry(ManifestEntry):
 	def __ne__(self, other):
 		return not self.__eq__(other)
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__(),
-				encoding=_encodings['repo.content'], errors='strict')
 
 class Manifest(object):
 	parsers = (parseManifest2,)
diff --git a/lib/portage/output.py b/lib/portage/output.py
index 6fbb24f4c..8bfcd91c2 100644
--- a/lib/portage/output.py
+++ b/lib/portage/output.py
@@ -256,9 +256,7 @@ def xtermTitle(mystr, raw=False):
 		# avoid potential UnicodeEncodeError
 		mystr = _unicode_encode(mystr,
 			encoding=_encodings['stdio'], errors='backslashreplace')
-		f = sys.stderr
-		if sys.hexversion >= 0x3000000:
-			f = f.buffer
+		f = sys.stderr.buffer
 		f.write(mystr)
 		f.flush()
 
diff --git a/lib/portage/process.py b/lib/portage/process.py
index bbe8d02f0..f550bcb30 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -198,10 +198,7 @@ def run_exitfuncs():
 			exc_info = sys.exc_info()
 
 	if exc_info is not None:
-		if sys.hexversion >= 0x3000000:
-			raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
-		else:
-			exec("raise exc_info[0], exc_info[1], exc_info[2]")
+		raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
 
 atexit.register(run_exitfuncs)
 
@@ -289,15 +286,6 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
 
 	env = os.environ if env is None else env
 
-	if sys.hexversion < 0x3000000:
-		# Avoid a potential UnicodeEncodeError from os.execve().
-		env_bytes = {}
-		for k, v in env.items():
-			env_bytes[_unicode_encode(k, encoding=_encodings['content'])] = \
-				_unicode_encode(v, encoding=_encodings['content'])
-		env = env_bytes
-		del env_bytes
-
 	# If an absolute path to an executable file isn't given
 	# search for it unless we've been told not to.
 	binary = mycommand[0]
@@ -964,7 +952,7 @@ def find_binary(binary):
 	@return: full path to binary or None if the binary could not be located.
 	"""
 	paths = os.environ.get("PATH", "")
-	if sys.hexversion >= 0x3000000 and isinstance(binary, bytes):
+	if isinstance(binary, bytes):
 		# return bytes when input is bytes
 		paths = paths.encode(sys.getfilesystemencoding(), 'surrogateescape')
 		paths = paths.split(b':')
diff --git a/lib/portage/proxy/objectproxy.py b/lib/portage/proxy/objectproxy.py
index a755774ae..e3bf4f75a 100644
--- a/lib/portage/proxy/objectproxy.py
+++ b/lib/portage/proxy/objectproxy.py
@@ -88,11 +88,5 @@ class ObjectProxy(object):
 	def __bool__(self):
 		return bool(object.__getattribute__(self, '_get_target')())
 
-	if sys.hexversion < 0x3000000:
-		__nonzero__ = __bool__
-
-		def __unicode__(self):
-			return unicode(object.__getattribute__(self, '_get_target')())
-
 	def __int__(self):
 		return int(object.__getattribute__(self, '_get_target')())
diff --git a/lib/portage/repository/config.py b/lib/portage/repository/config.py
index e75b6b543..210ae3aa0 100644
--- a/lib/portage/repository/config.py
+++ b/lib/portage/repository/config.py
@@ -530,12 +530,6 @@ class RepoConfig(object):
 			d[k] = getattr(self, k, None)
 		return "%s" % (d,)
 
-	if sys.hexversion < 0x3000000:
-
-		__unicode__ = __str__
-
-		def __str__(self):
-			return _unicode_encode(self.__unicode__())
 
 class RepoConfigLoader(object):
 	"""Loads and store config of several repositories, loaded from PORTDIR_OVERLAY or repos.conf"""
diff --git a/lib/portage/tests/unicode/test_string_format.py b/lib/portage/tests/unicode/test_string_format.py
index 713aca8ae..561feeea1 100644
--- a/lib/portage/tests/unicode/test_string_format.py
+++ b/lib/portage/tests/unicode/test_string_format.py
@@ -10,8 +10,6 @@ from _emerge.DependencyArg import DependencyArg
 from _emerge.UseFlagDisplay import UseFlagDisplay
 
 
-STR_IS_UNICODE = sys.hexversion >= 0x3000000
-
 class StringFormatTestCase(TestCase):
 	"""
 	Test that string formatting works correctly in the current interpretter,
@@ -39,17 +37,9 @@ class StringFormatTestCase(TestCase):
 			formatted_str = "%s" % (dependency_arg,)
 			self.assertEqual(formatted_str, arg_unicode)
 
-			if STR_IS_UNICODE:
-
-				# Test the __str__ method which returns unicode in python3
-				formatted_str = "%s" % (dependency_arg,)
-				self.assertEqual(formatted_str, arg_unicode)
-
-			else:
-
-				# Test the __str__ method which returns encoded bytes in python2
-				formatted_bytes = b"%s" % (dependency_arg,)
-				self.assertEqual(formatted_bytes, arg_bytes)
+			# Test the __str__ method which returns unicode in python3
+			formatted_str = "%s" % (dependency_arg,)
+			self.assertEqual(formatted_str, arg_unicode)
 
 	def testPortageException(self):
 
@@ -64,17 +54,9 @@ class StringFormatTestCase(TestCase):
 			formatted_str = "%s" % (e,)
 			self.assertEqual(formatted_str, arg_unicode)
 
-			if STR_IS_UNICODE:
-
-				# Test the __str__ method which returns unicode in python3
-				formatted_str = "%s" % (e,)
-				self.assertEqual(formatted_str, arg_unicode)
-
-			else:
-
-				# Test the __str__ method which returns encoded bytes in python2
-				formatted_bytes = b"%s" % (e,)
-				self.assertEqual(formatted_bytes, arg_bytes)
+			# Test the __str__ method which returns unicode in python3
+			formatted_str = "%s" % (e,)
+			self.assertEqual(formatted_str, arg_unicode)
 
 	def testUseFlagDisplay(self):
 
@@ -90,14 +72,6 @@ class StringFormatTestCase(TestCase):
 					formatted_str = "%s" % (e,)
 					self.assertEqual(isinstance(formatted_str, str), True)
 
-					if STR_IS_UNICODE:
-
-						# Test the __str__ method which returns unicode in python3
-						formatted_str = "%s" % (e,)
-						self.assertEqual(isinstance(formatted_str, str), True)
-
-					else:
-
-						# Test the __str__ method which returns encoded bytes in python2
-						formatted_bytes = b"%s" % (e,)
-						self.assertEqual(isinstance(formatted_bytes, bytes), True)
+					# Test the __str__ method which returns unicode in python3
+					formatted_str = "%s" % (e,)
+					self.assertEqual(isinstance(formatted_str, str), True)
diff --git a/lib/portage/util/_ShelveUnicodeWrapper.py b/lib/portage/util/_ShelveUnicodeWrapper.py
deleted file mode 100644
index adbd5199f..000000000
--- a/lib/portage/util/_ShelveUnicodeWrapper.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-class ShelveUnicodeWrapper(object):
-	"""
-	Convert unicode to str and back again, since python-2.x shelve
-	module doesn't support unicode.
-	"""
-	def __init__(self, shelve_instance):
-		self._shelve = shelve_instance
-
-	def _encode(self, s):
-		if isinstance(s, unicode):
-			s = s.encode('utf_8')
-		return s
-
-	def __len__(self):
-		return len(self._shelve)
-
-	def __contains__(self, k):
-		return self._encode(k) in self._shelve
-
-	def __iter__(self):
-		return self._shelve.__iter__()
-
-	def items(self):
-		return self._shelve.iteritems()
-
-	def __setitem__(self, k, v):
-		self._shelve[self._encode(k)] = self._encode(v)
-
-	def __getitem__(self, k):
-		return self._shelve[self._encode(k)]
-
-	def __delitem__(self, k):
-		del self._shelve[self._encode(k)]
-
-	def get(self, k, *args):
-		return self._shelve.get(self._encode(k), *args)
-
-	def close(self):
-		self._shelve.close()
-
-	def clear(self):
-		self._shelve.clear()
-- 
2.27.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.