python-dateutil: upgraded package to upstream

Upgraded dev-python/python-dateutil to version 2.7.2-r1 on amd64

Pulled the latest eclass/python-utils-r1.eclass from gentoo

https://cros-goldeneye.corp.google.com/chromeos/healthmonitoring/buildDetails?buildbucketId=8936748904661188448

BUG=chromium:870100
TEST=cros tryjob

Change-Id: Iba2865dac51408bfcf0d7570725d81e50de57b00
Reviewed-on: https://chromium-review.googlesource.com/1196690
Commit-Ready: Keith Haddow <haddowk@chromium.org>
Tested-by: Keith Haddow <haddowk@chromium.org>
Reviewed-by: Jason Clinton <jclinton@chromium.org>
diff --git a/dev-python/python-dateutil/Manifest b/dev-python/python-dateutil/Manifest
index a8e7622..0073c5c 100644
--- a/dev-python/python-dateutil/Manifest
+++ b/dev-python/python-dateutil/Manifest
@@ -1 +1 @@
-DIST python-dateutil-2.1.tar.gz 152334 SHA256 4c44ec3f9ff057b8c7b4c78beca5fdd8710600ea9a1df42f31bfcbae2f059dee
+DIST python-dateutil-2.7.2.tar.gz 298000 SHA256 9d8074be4c993fbe4947878ce593052f71dac82932a677d49194d8ce9778002e SHA512 b8fdc867aa67c4e5602bb3e9bf906dd4d32a6616fcdfd5f39d146d849a46d13c266bc9c2eae28490399fe608ba19dcb824d05ce96d556de07999449eaece7dfc WHIRLPOOL 5abfca550dbefe123a94834e88a9b2917dd89d74e5893224a8487ec588ce37ba0e42bd981a282218193876d2bd1c52186c827d6720834ded124455b5a6c6c132
diff --git a/dev-python/python-dateutil/files/0001-zoneinfo-Get-timezone-data-from-system-tzdata.patch b/dev-python/python-dateutil/files/0001-zoneinfo-Get-timezone-data-from-system-tzdata.patch
new file mode 100644
index 0000000..2e3f4ee
--- /dev/null
+++ b/dev-python/python-dateutil/files/0001-zoneinfo-Get-timezone-data-from-system-tzdata.patch
@@ -0,0 +1,104 @@
+From f48e70ae846c161dfbfe6ddb36e4bcad4427ac8c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= <mgorny@gentoo.org>
+Date: Tue, 3 Apr 2018 22:03:32 +0200
+Subject: [PATCH] zoneinfo: Get timezone data from system tzdata
+
+---
+ dateutil/test/test_imports.py |  3 +--
+ dateutil/zoneinfo/__init__.py | 25 ++++++++++++++-----------
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/dateutil/test/test_imports.py b/dateutil/test/test_imports.py
+index 2a19b62..97d07e4 100644
+--- a/dateutil/test/test_imports.py
++++ b/dateutil/test/test_imports.py
+@@ -158,9 +158,8 @@ class ImportZoneInfoTest(unittest.TestCase):
+     def testZoneinfoStar(self):
+         from dateutil.zoneinfo import gettz
+         from dateutil.zoneinfo import gettz_db_metadata
+-        from dateutil.zoneinfo import rebuild
+ 
+-        zi_all = (gettz, gettz_db_metadata, rebuild)
++        zi_all = (gettz, gettz_db_metadata)
+ 
+         for var in zi_all:
+             self.assertIsNot(var, None)
+diff --git a/dateutil/zoneinfo/__init__.py b/dateutil/zoneinfo/__init__.py
+index 34f11ad..e9870ca 100644
+--- a/dateutil/zoneinfo/__init__.py
++++ b/dateutil/zoneinfo/__init__.py
+@@ -1,6 +1,7 @@
+ # -*- coding: utf-8 -*-
+ import warnings
+ import json
++import os
+ 
+ from tarfile import TarFile
+ from pkgutil import get_data
+@@ -10,7 +11,7 @@ from dateutil.tz import tzfile as _tzfile
+ 
+ __all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata"]
+ 
+-ZONEFILENAME = "dateutil-zoneinfo.tar.gz"
++ZONEDIRECTORY = "/usr/share/zoneinfo"
+ METADATA_FN = 'METADATA'
+ 
+ 
+@@ -19,12 +20,14 @@ class tzfile(_tzfile):
+         return (gettz, (self._filename,))
+ 
+ 
+-def getzoneinfofile_stream():
+-    try:
+-        return BytesIO(get_data(__name__, ZONEFILENAME))
+-    except IOError as e:  # TODO  switch to FileNotFoundError?
+-        warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror))
+-        return None
++def iter_zones(topdir):
++    for dirpath, dirnames, filenames in os.walk(topdir):
++        for f in filenames:
++            if f.endswith('.tab'):
++                continue
++            fpath = os.path.join(dirpath, f)
++            relpath = os.path.relpath(fpath, topdir)
++            yield (relpath, tzfile(fpath, filename=relpath))
+ 
+ 
+ class ZoneInfoFile(object):
+@@ -48,7 +51,7 @@ class ZoneInfoFile(object):
+                     # no metadata in tar file
+                     self.metadata = None
+         else:
+-            self.zones = {}
++            self.zones = dict(iter_zones(ZONEDIRECTORY))
+             self.metadata = None
+ 
+     def get(self, name, default=None):
+@@ -99,7 +102,7 @@ def get_zonefile_instance(new_instance=False):
+         zif = getattr(get_zonefile_instance, '_cached_instance', None)
+ 
+     if zif is None:
+-        zif = ZoneInfoFile(getzoneinfofile_stream())
++        zif = ZoneInfoFile()
+ 
+         get_zonefile_instance._cached_instance = zif
+ 
+@@ -140,7 +143,7 @@ def gettz(name):
+                   DeprecationWarning)
+ 
+     if len(_CLASS_ZONE_INSTANCE) == 0:
+-        _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))
++        _CLASS_ZONE_INSTANCE.append(ZoneInfoFile())
+     return _CLASS_ZONE_INSTANCE[0].zones.get(name)
+ 
+ 
+@@ -163,5 +166,5 @@ def gettz_db_metadata():
+                   DeprecationWarning)
+ 
+     if len(_CLASS_ZONE_INSTANCE) == 0:
+-        _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))
++        _CLASS_ZONE_INSTANCE.append(ZoneInfoFile())
+     return _CLASS_ZONE_INSTANCE[0].metadata
+-- 
+2.17.0
+
diff --git a/dev-python/python-dateutil/files/python-dateutil-1.4.1-locale.patch b/dev-python/python-dateutil/files/python-dateutil-1.4.1-locale.patch
deleted file mode 100644
index 53d4bb8..0000000
--- a/dev-python/python-dateutil/files/python-dateutil-1.4.1-locale.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: python-dateutil/example.py
-===================================================================
---- python-dateutil.orig/example.py	2006-09-06 13:21:44.000000000 +0200
-+++ python-dateutil/example.py	2006-09-06 13:21:56.000000000 +0200
-@@ -5,7 +5,7 @@
- from datetime import *
- import commands
- import os
--now = parse(commands.getoutput("date"))
-+now = parse(commands.getoutput("LC_ALL=C date"))
- today = now.date()
- year = rrule(YEARLY,bymonth=8,bymonthday=13,byweekday=FR)[0].year
- rdelta = relativedelta(easter(year), today)
diff --git a/dev-python/python-dateutil/files/python-dateutil-2.1-open-utf-8.patch b/dev-python/python-dateutil/files/python-dateutil-2.1-open-utf-8.patch
deleted file mode 100644
index f272854..0000000
--- a/dev-python/python-dateutil/files/python-dateutil-2.1-open-utf-8.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Fix UnicodeDecodeError in setup.py.
-
-https://bugs.gentoo.org/show_bug.cgi?id=410725
---- setup.py
-+++ setup.py
-@@ -1,5 +1,6 @@
- #!/usr/bin/python
- from os.path import isfile, join
-+import codecs
- import glob
- import os
- import re
-@@ -13,7 +14,7 @@
- 
- TOPDIR = os.path.dirname(__file__) or "."
- VERSION = re.search('__version__ = "([^"]+)"',
--                    open(TOPDIR + "/dateutil/__init__.py").read()).group(1)
-+                    codecs.open(TOPDIR + "/dateutil/__init__.py", encoding='utf-8').read()).group(1)
- 
- 
- setup(name="python-dateutil",
diff --git a/dev-python/python-dateutil/metadata.xml b/dev-python/python-dateutil/metadata.xml
index a6f09b8..4bee24c 100644
--- a/dev-python/python-dateutil/metadata.xml
+++ b/dev-python/python-dateutil/metadata.xml
@@ -1,9 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
 <pkgmetadata>
-	<herd>python</herd>
-	<longdescription lang="en">
-		The dateutil module provides powerful extensions to the standard
-		datetime module, available in Python 2.3+.
-	</longdescription>
+  <maintainer type="project">
+    <email>python@gentoo.org</email>
+    <name>Python</name>
+  </maintainer>
+  <longdescription lang="en">
+  The dateutil module provides powerful extensions to the standard
+  datetime module, available in Python 2.3+.
+  </longdescription>
+  <upstream>
+    <remote-id type="pypi">python-dateutil</remote-id>
+    <remote-id type="github">dateutil/dateutil</remote-id>
+    <remote-id type="launchpad">dateutil</remote-id>
+  </upstream>
 </pkgmetadata>
diff --git a/dev-python/python-dateutil/python-dateutil-2.1-r1.ebuild b/dev-python/python-dateutil/python-dateutil-2.1-r1.ebuild
deleted file mode 100644
index c89f524..0000000
--- a/dev-python/python-dateutil/python-dateutil-2.1-r1.ebuild
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 1999-2013 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/dev-python/python-dateutil/python-dateutil-2.1-r1.ebuild,v 1.14 2013/12/23 16:23:13 ago Exp $
-
-EAPI=5
-PYTHON_COMPAT=( python{2_6,2_7,3_2,3_3} pypy2_0 )
-
-inherit distutils-r1
-
-DESCRIPTION="Extensions to the standard Python datetime module"
-HOMEPAGE="https://launchpad.net/dateutil http://pypi.python.org/pypi/python-dateutil"
-SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
-
-LICENSE="BSD"
-SLOT="0"
-KEYWORDS="*"
-IUSE="examples"
-
-RDEPEND="dev-python/six[${PYTHON_USEDEP}]
-	sys-libs/timezone-data
-	!<dev-python/python-dateutil-2.1"
-DEPEND="${RDEPEND}
-	dev-python/setuptools[${PYTHON_USEDEP}]"
-
-PATCHES=(
-	# Bug 410725.
-	"${FILESDIR}/${P}-open-utf-8.patch"
-)
-
-python_prepare_all() {
-	# Use zoneinfo in /usr/share/zoneinfo.
-	sed -i -e "s/zoneinfo.gettz/gettz/g" test.py || die
-
-	# Fix parsing of date in non-English locales.
-	sed -e 's/subprocess.getoutput("date")/subprocess.getoutput("LC_ALL=C date")/' \
-		-i example.py || die
-
-	distutils-r1_python_prepare_all
-}
-
-python_test() {
-	"${PYTHON}" test.py || die
-}
-
-python_install() {
-	distutils-r1_python_install
-
-	rm -f "${D}$(python_get_sitedir)/dateutil/zoneinfo"/*.tar.*
-}
-
-python_install_all() {
-	distutils-r1_python_install_all
-
-	if use examples; then
-		docinto examples
-		dodoc example.py sandbox/*.py
-	fi
-}
diff --git a/dev-python/python-dateutil/python-dateutil-2.7.2-r1.ebuild b/dev-python/python-dateutil/python-dateutil-2.7.2-r1.ebuild
new file mode 100644
index 0000000..43e9f4b
--- /dev/null
+++ b/dev-python/python-dateutil/python-dateutil-2.7.2-r1.ebuild
@@ -0,0 +1,49 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+
+PYTHON_COMPAT=( python2_7 python3_{4,5,6,7} pypy pypy3 )
+
+inherit distutils-r1
+
+DESCRIPTION="Extensions to the standard Python datetime module"
+HOMEPAGE="
+	https://dateutil.readthedocs.org/
+	https://pypi.org/project/python-dateutil
+	https://github.com/dateutil/dateutil/
+"
+SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
+
+LICENSE="BSD"
+SLOT="0"
+KEYWORDS="*"
+IUSE="test"
+
+RDEPEND="
+	>=dev-python/six-1.5[${PYTHON_USEDEP}]
+	sys-libs/timezone-data
+"
+DEPEND="${RDEPEND}
+	dev-python/setuptools_scm[${PYTHON_USEDEP}]
+	dev-python/setuptools[${PYTHON_USEDEP}]
+	test? (
+		dev-python/pytest[${PYTHON_USEDEP}]
+		dev-python/freezegun[${PYTHON_USEDEP}]
+	)
+"
+
+python_prepare_all() {
+	local PATCHES=(
+		"${FILESDIR}"/0001-zoneinfo-Get-timezone-data-from-system-tzdata.patch
+	)
+
+	# don't install zoneinfo tarball
+	sed -i '/package_data=/d' setup.py || die
+
+	distutils-r1_python_prepare_all
+}
+
+python_test() {
+	py.test -v || die "Tests failed under ${EPYTHON}"
+}
diff --git a/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass
index 5e5cc8f..e3cf82b 100644
--- a/eclass/python-utils-r1.eclass
+++ b/eclass/python-utils-r1.eclass
@@ -1,6 +1,5 @@
-# Copyright 1999-2017 Gentoo Foundation
+# Copyright 1999-2018 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Id$
 
 # @ECLASS: python-utils-r1.eclass
 # @MAINTAINER:
@@ -8,6 +7,7 @@
 # @AUTHOR:
 # Author: MichaƂ Górny <mgorny@gentoo.org>
 # Based on work of: Krzysztof Pawlik <nelchael@gentoo.org>
+# @SUPPORTED_EAPIS: 0 1 2 3 4 5 6 7
 # @BLURB: Utility functions for packages with Python parts.
 # @DESCRIPTION:
 # A utility eclass providing functions to query Python implementations,
@@ -20,7 +20,7 @@
 # https://wiki.gentoo.org/wiki/Project:Python/python-utils-r1
 
 case "${EAPI:-0}" in
-	0|1|2|3|4|5|6)
+	0|1|2|3|4|5|6|7)
 		;;
 	*)
 		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
@@ -44,10 +44,22 @@
 	jython2_7
 	pypy pypy3
 	python2_7
-	python3_3 python3_4 python3_5 python3_6
+	python3_4 python3_5 python3_6 python3_7
 )
 readonly _PYTHON_ALL_IMPLS
 
+# @ECLASS-VARIABLE: PYTHON_COMPAT_NO_STRICT
+# @INTERNAL
+# @DESCRIPTION:
+# Set to a non-empty value in order to make eclass tolerate (ignore)
+# unknown implementations in PYTHON_COMPAT.
+#
+# This is intended to be set by the user when using ebuilds that may
+# have unknown (newer) implementations in PYTHON_COMPAT. The assumption
+# is that the ebuilds are intended to be used within multiple contexts
+# which can involve revisions of this eclass that support a different
+# set of Python implementations.
+
 # @FUNCTION: _python_impl_supported
 # @USAGE: <impl>
 # @INTERNAL
@@ -68,10 +80,10 @@
 	# keep in sync with _PYTHON_ALL_IMPLS!
 	# (not using that list because inline patterns shall be faster)
 	case "${impl}" in
-		python2_7|python3_[3456]|jython2_7)
+		python2_7|python3_[4567]|jython2_7)
 			return 0
 			;;
-		pypy1_[89]|pypy2_0|python2_[56]|python3_[12])
+		pypy1_[89]|pypy2_0|python2_[56]|python3_[123])
 			return 1
 			;;
 		pypy|pypy3)
@@ -80,6 +92,7 @@
 			fi
 			;;
 		*)
+			[[ ${PYTHON_COMPAT_NO_STRICT} ]] && return 1
 			die "Invalid implementation in PYTHON_COMPAT: ${impl}"
 	esac
 }
@@ -115,22 +128,73 @@
 		_python_impl_supported "${i}"
 	done
 
-	_PYTHON_SUPPORTED_IMPLS=()
-	_PYTHON_UNSUPPORTED_IMPLS=()
+	local supp=() unsupp=()
 
 	for i in "${_PYTHON_ALL_IMPLS[@]}"; do
 		if has "${i}" "${PYTHON_COMPAT[@]}"; then
-			_PYTHON_SUPPORTED_IMPLS+=( "${i}" )
+			supp+=( "${i}" )
 		else
-			_PYTHON_UNSUPPORTED_IMPLS+=( "${i}" )
+			unsupp+=( "${i}" )
 		fi
 	done
 
-	if [[ ${#_PYTHON_SUPPORTED_IMPLS[@]} -eq 0 ]]; then
+	if [[ ! ${supp[@]} ]]; then
 		die "No supported implementation in PYTHON_COMPAT."
 	fi
 
-	readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
+	if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} ]]; then
+		# set once already, verify integrity
+		if [[ ${_PYTHON_SUPPORTED_IMPLS[@]} != ${supp[@]} ]]; then
+			eerror "Supported impls (PYTHON_COMPAT) changed between inherits!"
+			eerror "Before: ${_PYTHON_SUPPORTED_IMPLS[*]}"
+			eerror "Now   : ${supp[*]}"
+			die "_PYTHON_SUPPORTED_IMPLS integrity check failed"
+		fi
+		if [[ ${_PYTHON_UNSUPPORTED_IMPLS[@]} != ${unsupp[@]} ]]; then
+			eerror "Unsupported impls changed between inherits!"
+			eerror "Before: ${_PYTHON_UNSUPPORTED_IMPLS[*]}"
+			eerror "Now   : ${unsupp[*]}"
+			die "_PYTHON_UNSUPPORTED_IMPLS integrity check failed"
+		fi
+	else
+		_PYTHON_SUPPORTED_IMPLS=( "${supp[@]}" )
+		_PYTHON_UNSUPPORTED_IMPLS=( "${unsupp[@]}" )
+		readonly _PYTHON_SUPPORTED_IMPLS _PYTHON_UNSUPPORTED_IMPLS
+	fi
+}
+
+# @FUNCTION: _python_impl_matches
+# @USAGE: <impl> <pattern>...
+# @INTERNAL
+# @DESCRIPTION:
+# Check whether the specified <impl> matches at least one
+# of the patterns following it. Return 0 if it does, 1 otherwise.
+#
+# <impl> can be in PYTHON_COMPAT or EPYTHON form. The patterns can be
+# either:
+# a) fnmatch-style patterns, e.g. 'python2*', 'pypy'...
+# b) '-2' to indicate all Python 2 variants (= !python_is_python3)
+# c) '-3' to indicate all Python 3 variants (= python_is_python3)
+_python_impl_matches() {
+	[[ ${#} -ge 2 ]] || die "${FUNCNAME}: takes at least 2 parameters"
+
+	local impl=${1} pattern
+	shift
+
+	for pattern; do
+		if [[ ${pattern} == -2 ]]; then
+			! python_is_python3 "${impl}"
+			return
+		elif [[ ${pattern} == -3 ]]; then
+			python_is_python3 "${impl}"
+			return
+		# unify value style to allow lax matching
+		elif [[ ${impl/./_} == ${pattern/./_} ]]; then
+			return 0
+		fi
+	done
+
+	return 1
 }
 
 # @ECLASS-VARIABLE: PYTHON
@@ -415,9 +479,9 @@
 					python*)
 						PYTHON_PKG_DEP="dev-lang/python:${impl#python}";;
 					pypy)
-						PYTHON_PKG_DEP='virtual/pypy:0=';;
+						PYTHON_PKG_DEP='>=virtual/pypy-5:0=';;
 					pypy3)
-						PYTHON_PKG_DEP='virtual/pypy3:0=';;
+						PYTHON_PKG_DEP='>=virtual/pypy3-5:0=';;
 					jython2.7)
 						PYTHON_PKG_DEP='dev-java/jython:2.7';;
 					*)
@@ -625,8 +689,8 @@
 			# 2) skip paths which do not exist
 			#    (python2.6 complains about them verbosely)
 
-			if [[ ${f} == /* && -d ${D}${f} ]]; then
-				set -- "${D}${f}" "${@}"
+			if [[ ${f} == /* && -d ${D%/}${f} ]]; then
+				set -- "${D%/}${f}" "${@}"
 			fi
 		done < <("${PYTHON}" -c 'import sys; print("\0".join(sys.path))' || die)
 
@@ -636,14 +700,20 @@
 	local d
 	for d; do
 		# make sure to get a nice path without //
-		local instpath=${d#${D}}
+		local instpath=${d#${D%/}}
 		instpath=/${instpath##/}
 
 		case "${EPYTHON}" in
-			python*)
+			python2.7|python3.[34])
 				"${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
 				"${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
 				;;
+			python*|pypy3)
+				# both levels of optimization are separate since 3.5
+				"${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
+				"${PYTHON}" -O -m compileall -q -f -d "${instpath}" "${d}"
+				"${PYTHON}" -OO -m compileall -q -f -d "${instpath}" "${d}"
+				;;
 			*)
 				"${PYTHON}" -m compileall -q -f -d "${instpath}" "${d}"
 				;;
@@ -651,32 +721,23 @@
 	done
 }
 
-# @ECLASS-VARIABLE: python_scriptroot
-# @DEFAULT_UNSET
+# @FUNCTION: python_scriptinto
+# @USAGE: <new-path>
 # @DESCRIPTION:
-# The current script destination for python_doscript(). The path
-# is relative to the installation root (${ED}).
+# Set the directory to which files passed to python_doexe(),
+# python_doscript(), python_newexe() and python_newscript()
+# are going to be installed. The new value needs to be relative
+# to the installation root (${ED}).
 #
-# When unset, ${DESTTREE}/bin (/usr/bin by default) will be used.
-#
-# Can be set indirectly through the python_scriptinto() function.
+# If not set explicitly, the directory defaults to /usr/bin.
 #
 # Example:
 # @CODE
 # src_install() {
-#   local python_scriptroot=${GAMES_BINDIR}
+#   python_scriptinto /usr/sbin
 #   python_foreach_impl python_doscript foo
 # }
 # @CODE
-
-# @FUNCTION: python_scriptinto
-# @USAGE: <new-path>
-# @DESCRIPTION:
-# Set the current scriptroot. The new value will be stored
-# in the 'python_scriptroot' environment variable. The new value need
-# be relative to the installation root (${ED}).
-#
-# Alternatively, you can set the variable directly.
 python_scriptinto() {
 	debug-print-function ${FUNCNAME} "${@}"
 
@@ -686,7 +747,7 @@
 # @FUNCTION: python_doexe
 # @USAGE: <files>...
 # @DESCRIPTION:
-# Install the given executables into current python_scriptroot,
+# Install the given executables into the executable install directory,
 # for the current Python implementation (${EPYTHON}).
 #
 # The executable will be wrapped properly for the Python implementation,
@@ -703,7 +764,7 @@
 # @FUNCTION: python_newexe
 # @USAGE: <path> <new-name>
 # @DESCRIPTION:
-# Install the given executable into current python_scriptroot,
+# Install the given executable into the executable install directory,
 # for the current Python implementation (${EPYTHON}).
 #
 # The executable will be wrapped properly for the Python implementation,
@@ -718,7 +779,7 @@
 		die "python_do* and python_new* helpers are banned in EAPIs older than 4."
 	fi
 
-	local wrapd=${python_scriptroot:-${DESTTREE}/bin}
+	local wrapd=${python_scriptroot:-/usr/bin}
 
 	local f=${1}
 	local newfn=${2}
@@ -729,6 +790,7 @@
 
 	(
 		dodir "${wrapd}"
+		exeopts -m 0755
 		exeinto "${d}"
 		newexe "${f}" "${newfn}" || return ${?}
 	)
@@ -746,7 +808,7 @@
 # @FUNCTION: python_doscript
 # @USAGE: <files>...
 # @DESCRIPTION:
-# Install the given scripts into current python_scriptroot,
+# Install the given scripts into the executable install directory,
 # for the current Python implementation (${EPYTHON}).
 #
 # All specified files must start with a 'python' shebang. The shebang
@@ -769,7 +831,7 @@
 # @FUNCTION: python_newscript
 # @USAGE: <path> <new-name>
 # @DESCRIPTION:
-# Install the given script into current python_scriptroot
+# Install the given script into the executable install directory
 # for the current Python implementation (${EPYTHON}), and name it
 # <new-name>.
 #
@@ -790,35 +852,34 @@
 	python_newexe "${@}"
 }
 
-# @ECLASS-VARIABLE: python_moduleroot
-# @DEFAULT_UNSET
+# @FUNCTION: python_moduleinto
+# @USAGE: <new-path>
 # @DESCRIPTION:
-# The current module root for python_domodule(). The path can be either
-# an absolute system path (it must start with a slash, and ${ED} will be
-# prepended to it) or relative to the implementation's site-packages directory
-# (then it must start with a non-slash character).
+# Set the Python module install directory for python_domodule().
+# The <new-path> can either be an absolute target system path (in which
+# case it needs to start with a slash, and ${ED} will be prepended to
+# it) or relative to the implementation's site-packages directory
+# (then it must not start with a slash). The relative path can be
+# specified either using the Python package notation (separated by dots)
+# or the directory notation (using slashes).
 #
-# When unset, the modules will be installed in the site-packages root.
+# When not set explicitly, the modules are installed to the top
+# site-packages directory.
 #
-# Can be set indirectly through the python_moduleinto() function.
+# In the relative case, the exact path is determined directly
+# by each python_doscript/python_newscript function. Therefore,
+# python_moduleinto can be safely called before establishing the Python
+# interpreter and/or a single call can be used to set the path correctly
+# for multiple implementations, as can be seen in the following example.
 #
 # Example:
 # @CODE
 # src_install() {
-#   local python_moduleroot=bar
+#   python_moduleinto bar
 #   # installs ${PYTHON_SITEDIR}/bar/baz.py
 #   python_foreach_impl python_domodule baz.py
 # }
 # @CODE
-
-# @FUNCTION: python_moduleinto
-# @USAGE: <new-path>
-# @DESCRIPTION:
-# Set the current module root. The new value will be stored
-# in the 'python_moduleroot' environment variable. The new value need
-# be relative to the site-packages root.
-#
-# Alternatively, you can set the variable directly.
 python_moduleinto() {
 	debug-print-function ${FUNCNAME} "${@}"
 
@@ -828,8 +889,8 @@
 # @FUNCTION: python_domodule
 # @USAGE: <files>...
 # @DESCRIPTION:
-# Install the given modules (or packages) into the current
-# python_moduleroot. The list can mention both modules (files)
+# Install the given modules (or packages) into the current Python module
+# installation directory. The list can mention both modules (files)
 # and packages (directories). All listed files will be installed
 # for all enabled implementations, and compiled afterwards.
 #
@@ -857,15 +918,16 @@
 		local PYTHON_SITEDIR=${PYTHON_SITEDIR}
 		[[ ${PYTHON_SITEDIR} ]] || python_export PYTHON_SITEDIR
 
-		d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot}
+		d=${PYTHON_SITEDIR#${EPREFIX}}/${python_moduleroot//.//}
 	fi
 
 	(
+		insopts -m 0644
 		insinto "${d}"
 		doins -r "${@}" || return ${?}
 	)
 
-	python_optimize "${ED}/${d}"
+	python_optimize "${ED%/}/${d}"
 }
 
 # @FUNCTION: python_doheader
@@ -895,6 +957,7 @@
 	d=${PYTHON_INCLUDEDIR#${EPREFIX}}
 
 	(
+		insopts -m 0644
 		insinto "${d}"
 		doins -r "${@}" || return ${?}
 	)
@@ -929,11 +992,11 @@
 		mkdir -p "${workdir}"/{bin,pkgconfig} || die
 
 		# Clean up, in case we were supposed to do a cheap update.
-		rm -f "${workdir}"/bin/python{,2,3,-config} || die
+		rm -f "${workdir}"/bin/python{,2,3}{,-config} || die
 		rm -f "${workdir}"/bin/2to3 || die
 		rm -f "${workdir}"/pkgconfig/python{,2,3}.pc || die
 
-		local EPYTHON PYTHON PYTHON_CONFIG
+		local EPYTHON PYTHON
 		python_export "${impl}" EPYTHON PYTHON
 
 		local pyver pyother
@@ -960,11 +1023,9 @@
 
 		# CPython-specific
 		if [[ ${EPYTHON} == python* ]]; then
-			python_export "${impl}" PYTHON_CONFIG
-
 			cat > "${workdir}/bin/python-config" <<-_EOF_ || die
 				#!/bin/sh
-				exec "${PYTHON_CONFIG}" "\${@}"
+				exec "${PYTHON}-config" "\${@}"
 			_EOF_
 			cp "${workdir}/bin/python-config" \
 				"${workdir}/bin/python${pyver}-config" || die
@@ -986,23 +1047,23 @@
 		for x in "${nonsupp[@]}"; do
 			cat >"${workdir}"/bin/${x} <<-_EOF_ || die
 				#!/bin/sh
-				echo "${x} is not supported by ${EPYTHON}" >&2
+				echo "${ECLASS}: ${FUNCNAME}: ${x} is not supported by ${EPYTHON} (PYTHON_COMPAT)" >&2
 				exit 127
 			_EOF_
 			chmod +x "${workdir}"/bin/${x} || die
 		done
-
-		# Now, set the environment.
-		# But note that ${workdir} may be shared with something else,
-		# and thus already on top of PATH.
-		if [[ ${PATH##:*} != ${workdir}/bin ]]; then
-			PATH=${workdir}/bin${PATH:+:${PATH}}
-		fi
-		if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
-			PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
-		fi
-		export PATH PKG_CONFIG_PATH
 	fi
+
+	# Now, set the environment.
+	# But note that ${workdir} may be shared with something else,
+	# and thus already on top of PATH.
+	if [[ ${PATH##:*} != ${workdir}/bin ]]; then
+		PATH=${workdir}/bin${PATH:+:${PATH}}
+	fi
+	if [[ ${PKG_CONFIG_PATH##:*} != ${workdir}/pkgconfig ]]; then
+		PKG_CONFIG_PATH=${workdir}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
+	fi
+	export PATH PKG_CONFIG_PATH
 }
 
 # @FUNCTION: python_is_python3
@@ -1029,9 +1090,20 @@
 python_is_installed() {
 	local impl=${1:-${EPYTHON}}
 	[[ ${impl} ]] || die "${FUNCNAME}: no impl nor EPYTHON"
+	local hasv_args=()
 
-	# for has_version
-	local -x ROOT=/
+	case ${EAPI:-0} in
+		0|1|2|3|4)
+			local -x ROOT=/
+			;;
+		5|6)
+			hasv_args+=( --host-root )
+			;;
+		*)
+			hasv_args+=( -b )
+			;;
+	esac
+
 	case "${impl}" in
 		pypy|pypy3)
 			local append=
@@ -1040,13 +1112,13 @@
 			fi
 
 			# be happy with just the interpeter, no need for the virtual
-			has_version "dev-python/${impl}${append}" \
-				|| has_version "dev-python/${impl}-bin${append}"
+			has_version "${hasv_args[@]}" "dev-python/${impl}${append}" \
+				|| has_version "${hasv_args[@]}" "dev-python/${impl}-bin${append}"
 			;;
 		*)
 			local PYTHON_PKG_DEP
 			python_export "${impl}" PYTHON_PKG_DEP
-			has_version "${PYTHON_PKG_DEP}"
+			has_version "${hasv_args[@]}" "${PYTHON_PKG_DEP}"
 			;;
 	esac
 }
@@ -1110,7 +1182,7 @@
 				for i in "${split_shebang[@]}"; do
 					case "${i}" in
 						*"${EPYTHON}")
-							debug-print "${FUNCNAME}: in file ${f#${D}}"
+							debug-print "${FUNCNAME}: in file ${f#${D%/}}"
 							debug-print "${FUNCNAME}: shebang matches EPYTHON: ${shebang}"
 
 							# Nothing to do, move along.
@@ -1119,7 +1191,7 @@
 							break
 							;;
 						*python|*python[23])
-							debug-print "${FUNCNAME}: in file ${f#${D}}"
+							debug-print "${FUNCNAME}: in file ${f#${D%/}}"
 							debug-print "${FUNCNAME}: rewriting shebang: ${shebang}"
 
 							if [[ ${i} == *python2 ]]; then
@@ -1169,7 +1241,7 @@
 			fi
 
 			if [[ ! ${quiet} ]]; then
-				einfo "Fixing shebang in ${f#${D}}."
+				einfo "Fixing shebang in ${f#${D%/}}."
 			fi
 
 			if [[ ! ${error} ]]; then
@@ -1183,7 +1255,7 @@
 				any_fixed=1
 			else
 				eerror "The file has incompatible shebang:"
-				eerror "  file: ${f#${D}}"
+				eerror "  file: ${f#${D%/}}"
 				eerror "  current shebang: ${shebang}"
 				eerror "  requested impl: ${EPYTHON}"
 				die "${FUNCNAME}: conversion of incompatible shebang requested"
@@ -1194,7 +1266,7 @@
 			local cmd=eerror
 			[[ ${EAPI:-0} == [012345] ]] && cmd=eqawarn
 
-			"${cmd}" "QA warning: ${FUNCNAME}, ${path#${D}} did not match any fixable files."
+			"${cmd}" "QA warning: ${FUNCNAME}, ${path#${D%/}} did not match any fixable files."
 			if [[ ${any_correct} ]]; then
 				"${cmd}" "All files have ${EPYTHON} shebang already."
 			else
@@ -1213,7 +1285,7 @@
 # Check whether the specified locale sanely maps between lowercase
 # and uppercase ASCII characters.
 _python_check_locale_sanity() {
-	local -x LC_CTYPE=${1}
+	local -x LC_ALL=${1}
 	local IFS=
 
 	local lc=( {a..z} )
@@ -1238,7 +1310,7 @@
 
 	if [[ $(locale charmap) != UTF-8 ]]; then
 		# Try English first, then everything else.
-		local lang locales="en_US.UTF-8 $(locale -a)"
+		local lang locales="C.UTF-8 en_US.UTF-8 en_GB.UTF-8 $(locale -a)"
 
 		for lang in ${locales}; do
 			if [[ $(LC_ALL=${lang} locale charmap 2>/dev/null) == UTF-8 ]]; then
@@ -1260,14 +1332,14 @@
 					fi
 					return 0
 				fi
-			fi  
+			fi
 		done
 
 		ewarn "Could not find a UTF-8 locale. This may trigger build failures in"
 		ewarn "some python packages. Please ensure that a UTF-8 locale is listed in"
 		ewarn "/etc/locale.gen and run locale-gen."
 		return 1
-	fi  
+	fi
 
 	return 0
 }
diff --git a/metadata/md5-cache/dev-python/python-dateutil-2.1-r1 b/metadata/md5-cache/dev-python/python-dateutil-2.1-r1
deleted file mode 100644
index 2d4b759..0000000
--- a/metadata/md5-cache/dev-python/python-dateutil-2.1-r1
+++ /dev/null
@@ -1,14 +0,0 @@
-DEFINED_PHASES=compile configure install prepare test
-DEPEND=dev-python/six[python_targets_python2_7(-)?,python_targets_python3_3(-)?,-python_single_target_python2_7(-),-python_single_target_python3_3(-)] sys-libs/timezone-data !<dev-python/python-dateutil-2.1 dev-python/setuptools[python_targets_python2_7(-)?,python_targets_python3_3(-)?,-python_single_target_python2_7(-),-python_single_target_python3_3(-)] python_targets_python2_7? ( >=dev-lang/python-2.7.5-r2:2.7 ) python_targets_python3_3? ( >=dev-lang/python-3.3.2-r2:3.3 ) >=dev-lang/python-exec-2:=[python_targets_python2_7(-)?,python_targets_python3_3(-)?,-python_single_target_python2_7(-),-python_single_target_python3_3(-)]
-DESCRIPTION=Extensions to the standard Python datetime module
-EAPI=5
-HOMEPAGE=https://launchpad.net/dateutil http://pypi.python.org/pypi/python-dateutil
-IUSE=examples python_targets_python2_7 python_targets_python3_3
-KEYWORDS=*
-LICENSE=BSD
-RDEPEND=dev-python/six[python_targets_python2_7(-)?,python_targets_python3_3(-)?,-python_single_target_python2_7(-),-python_single_target_python3_3(-)] sys-libs/timezone-data !<dev-python/python-dateutil-2.1 python_targets_python2_7? ( >=dev-lang/python-2.7.5-r2:2.7 ) python_targets_python3_3? ( >=dev-lang/python-3.3.2-r2:3.3 ) >=dev-lang/python-exec-2:=[python_targets_python2_7(-)?,python_targets_python3_3(-)?,-python_single_target_python2_7(-),-python_single_target_python3_3(-)]
-REQUIRED_USE=|| ( python_targets_python2_7 python_targets_python3_3 )
-SLOT=0
-SRC_URI=mirror://pypi/p/python-dateutil/python-dateutil-2.1.tar.gz
-_eclasses_=distutils-r1	4e8ac1ba76ddacd8f7c0289aa586a34c	eutils	06133990e861be0fe60c2b428fd025d9	multibuild	742139c87a9fa3766f0c2b155e5522bf	multilib	97f470f374f2e94ccab04a2fb21d811e	multiprocessing	e32940a7b2a9992ad217eccddb84d548	python-r1	9f6eda21d15d6a8f665d7996a4e0f4e3	python-utils-r1	ec7e05a608c9ab8ae4d180d10bd61600	toolchain-funcs	1e35303c63cd707f6c3422b4493d5607
-_md5_=f633c0ca52fb68da16fecc3299e81d43
diff --git a/metadata/md5-cache/dev-python/python-dateutil-2.7.2-r1 b/metadata/md5-cache/dev-python/python-dateutil-2.7.2-r1
new file mode 100644
index 0000000..7addda1
--- /dev/null
+++ b/metadata/md5-cache/dev-python/python-dateutil-2.7.2-r1
@@ -0,0 +1,14 @@
+DEFINED_PHASES=compile configure install prepare test
+DEPEND=>=dev-python/six-1.5[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)] sys-libs/timezone-data dev-python/setuptools_scm[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)] dev-python/setuptools[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)] test? ( dev-python/pytest[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)] dev-python/freezegun[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)] ) python_targets_pypy? ( >=virtual/pypy-5:0= ) python_targets_pypy3? ( >=virtual/pypy3-5:0= ) python_targets_python2_7? ( >=dev-lang/python-2.7.5-r2:2.7 ) python_targets_python3_4? ( dev-lang/python:3.4 ) python_targets_python3_5? ( dev-lang/python:3.5 ) python_targets_python3_6? ( dev-lang/python:3.6 ) python_targets_python3_7? ( dev-lang/python:3.7 ) >=dev-lang/python-exec-2:=[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)]
+DESCRIPTION=Extensions to the standard Python datetime module
+EAPI=6
+HOMEPAGE=https://dateutil.readthedocs.org/ https://pypi.org/project/python-dateutil https://github.com/dateutil/dateutil/
+IUSE=test python_targets_pypy python_targets_pypy3 python_targets_python2_7 python_targets_python3_4 python_targets_python3_5 python_targets_python3_6 python_targets_python3_7
+KEYWORDS=*
+LICENSE=BSD
+RDEPEND=>=dev-python/six-1.5[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)] sys-libs/timezone-data python_targets_pypy? ( >=virtual/pypy-5:0= ) python_targets_pypy3? ( >=virtual/pypy3-5:0= ) python_targets_python2_7? ( >=dev-lang/python-2.7.5-r2:2.7 ) python_targets_python3_4? ( dev-lang/python:3.4 ) python_targets_python3_5? ( dev-lang/python:3.5 ) python_targets_python3_6? ( dev-lang/python:3.6 ) python_targets_python3_7? ( dev-lang/python:3.7 ) >=dev-lang/python-exec-2:=[python_targets_pypy(-)?,python_targets_pypy3(-)?,python_targets_python2_7(-)?,python_targets_python3_4(-)?,python_targets_python3_5(-)?,python_targets_python3_6(-)?,python_targets_python3_7(-)?,-python_single_target_pypy(-),-python_single_target_pypy3(-),-python_single_target_python2_7(-),-python_single_target_python3_4(-),-python_single_target_python3_5(-),-python_single_target_python3_6(-),-python_single_target_python3_7(-)]
+REQUIRED_USE=|| ( python_targets_pypy python_targets_pypy3 python_targets_python2_7 python_targets_python3_4 python_targets_python3_5 python_targets_python3_6 python_targets_python3_7 )
+SLOT=0
+SRC_URI=mirror://pypi/p/python-dateutil/python-dateutil-2.7.2.tar.gz
+_eclasses_=distutils-r1	4e8ac1ba76ddacd8f7c0289aa586a34c	multibuild	742139c87a9fa3766f0c2b155e5522bf	multilib	97f470f374f2e94ccab04a2fb21d811e	multiprocessing	e32940a7b2a9992ad217eccddb84d548	python-r1	9f6eda21d15d6a8f665d7996a4e0f4e3	python-utils-r1	12114a2a9aab35b93efc037a196b3234	toolchain-funcs	1e35303c63cd707f6c3422b4493d5607
+_md5_=b2bdec0a2fc6cfc17c6b249b410d2147