public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-04 21:53 Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-04 21:53 UTC (permalink / raw
  To: gentoo-commits

commit:     e244f5dc8742446047c0292fe224c422577a8afa
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Feb  4 21:52:51 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Thu Feb  4 21:52:51 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=e244f5dc

big cleanup

 python.eselect.in | 96 +++++++++++++++++++++++++++----------------------------
 1 file changed, 48 insertions(+), 48 deletions(-)

diff --git a/python.eselect.in b/python.eselect.in
index d1e2836..2680d69 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -9,7 +9,7 @@ VERSION=20160202
 CONFIG_PATH="${EROOT%/}/etc/python-exec/python-exec.conf"
 ENV_D_PATH="${EROOT%/}/etc/env.d"
 INTERPRETER_DIR="${EROOT%/}/usr/bin"
-MAN_PATH="${EROOT%/}/usr/share/man/man1/"
+MAN_PATH="${EROOT%/}/usr/share/man/man1"
 
 # Get list of all installed Python interpreters, in lexical order.
 # $1 can be --pyN to filter results to pythonN.?.
@@ -74,6 +74,7 @@ get_all_pythons() {
 	local targets=( $(get_installed_pythons "${@}") )
 	local preferred=( $(get_preferred_pythons "${@}") )
 	local disabled=( $(get_disabled_pythons "${@}") )
+	local i
 
 	# preferred first
 	for i in "${preferred[@]}"; do
@@ -104,25 +105,23 @@ write_preferences() {
 
 # Set a man page symlink
 set_man_symlink() {
-	local target="${1}" x extension
+	local target=${1} x suffix
 
-	rm -f "${MAN_PATH}"python.1{,.gz,.bz2,.lzma,.xz,.lz}
+	rm -f "${MAN_PATH}"/python.1{,.gz,.bz2,.lzma,.xz,.lz} || die
 
-	for x in ".1" ".1.bz2" ".1.gz" ".1.lzma" ".1.xz" ".1.lz"; do
-		if [[ -e "${MAN_PATH}${target}${x}" ]]; then
-			extension="${x}"
+	for x in .1{,.gz,.bz2,.lzma,.xz,.lz}; do
+		if [[ -e "${MAN_PATH}/${target}${x}" ]]; then
+			suffix=${x}
 			break
 		fi
 	done
 
-	if [[ -z "${extension}" ]]; then
+	if [[ ! ${suffix} ]]; then
 		echo "Couldn't find a man page for ${target}; skipping." 1>&2
 		return 1
 	fi
 
-	pushd "${MAN_PATH}" 1> /dev/null
-	ln -nfs "${target}${extension}" "python${extension}"
-	popd 1> /dev/null
+	ln -nfs "${target}${extension}" "${MAN_PATH}/python${extension}" || die
 }
 
 # Set OSX framework symlinks
@@ -130,22 +129,22 @@ set_osx_framework() {
 	local target=${1}
 
 	# Files of Mac OS X framework
-	local framework_dir="${INTERPRETER_PATH%/bin/}/lib/Python.framework"
-	if [[ -d "${framework_dir}" ]]; then
-		local version="${target#python}"
-		pushd "${framework_dir}" 1> /dev/null
-		rm -f Headers Python Resources
-		ln -nfs "Versions/${version}/Headers"
-		ln -nfs "Versions/${version}/Python"
-		ln -nfs "Versions/${version}/Resources"
-		popd 1> /dev/null
+	local framework_dir="${INTERPRETER_DIR%/bin}"/lib/Python.framework
+	if [[ -d ${framework_dir} ]]; then
+		local version=${target#python}
+		pushd "${framework_dir}" >/dev/null || die
+		rm -f Headers Python Resources || die
+		ln -nfs "Versions/${version}/Headers" || die
+		ln -nfs "Versions/${version}/Python" || die
+		ln -nfs "Versions/${version}/Resources" || die
+		popd >/dev/null || die
 	fi
 }
 
 # Set the content of /etc/env.d/65python-docs
 set_python_docs() {
-	local path target="${1#python}" variable
-	rm -f "${ENV_D_PATH}/65python-docs"
+	local path target=${1#python} variable
+	rm -f "${ENV_D_PATH}/65python-docs" || die
 	if [[ -f ${ENV_D_PATH}/60python-docs-${target} ]]; then
 		variable="PYTHONDOCS_${target//./_}"
 		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo "${!variable}")"
@@ -169,21 +168,21 @@ post_update() {
 ### show action ###
 
 describe_show() {
-	echo "Show main active Python interpreter"
+	echo "Show the most preferred Python interpreter"
 }
 
 describe_show_options() {
-	echo "--ABI         : Show Python ABI in format of PYTHON_ABI variable"
-	echo "--python2     : Show active Python 2 interpreter"
-	echo "--python3     : Show active Python 3 interpreter"
+	echo "--ABI         : use PYTHON_ABI variable format (deprecated)"
+	echo "--python2     : show the preferred version of Python 2"
+	echo "--python3     : show the preferred version of Python 3"
 }
 
 do_show() {
-	local ABI filter interpreter
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local abi filter interpreter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--ABI)
-				ABI=1
+				abi=1
 				;;
 			--python2|--py2)
 				filter=--py2
@@ -198,7 +197,8 @@ do_show() {
 		shift
 	done
 
-	local all_interpreters=( $(get_preferred_pythons ${filter}) ) i
+	local all_interpreters=( $(get_preferred_pythons ${filter}) )
+	local i
 	for i in "${all_interpreters[@]}"; do
 		# skip if not installed
 		[[ -x ${INTERPRETER_DIR}/${i}@EXEEXT@ ]] || continue
@@ -206,7 +206,7 @@ do_show() {
 		break
 	done
 
-	if [[ "${ABI}" == "1" ]]; then
+	if [[ ${abi} ]]; then
 		echo "${interpreter#python}"
 	else
 		echo "${interpreter}"
@@ -220,14 +220,14 @@ describe_list() {
 }
 
 describe_list_options() {
-	echo "--python2     : List installed Python 2 interpreters"
-	echo "--python3     : List installed Python 3 interpreters"
+	echo "--python2     : list only Python 2 interpreters"
+	echo "--python3     : list only Python 3 interpreters"
 }
 
 do_list() {
 	local filter
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--python2|--py2)
 				filter=--py2
 				;;
@@ -260,12 +260,12 @@ do_list() {
 ### set action ###
 
 describe_set() {
-	echo "Set main active Python interpreter"
+	echo "Set the preferred Python interpreter"
 }
 
 describe_set_options() {
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--python2     : update preference for Python 2 versions only"
+	echo "--python3     : update preference for Python 3 versions only"
 }
 
 describe_set_parameters() {
@@ -274,8 +274,8 @@ describe_set_parameters() {
 
 do_set() {
 	local filter
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--python2|--py2)
 				filter=--py2
 				;;
@@ -289,14 +289,14 @@ do_set() {
 		shift
 	done
 
-	[[ $# -eq 1 ]] || die "Usage: eselect python set <interpreter>"
+	[[ ${#} -eq 1 ]] || die "Usage: eselect python set <interpreter>"
 
 	local target=${1}
 	local targets=( $(get_all_pythons ${filter}) )
 	if is_number "${target}" \
 		&& [[ ${target} -ge 1 && ${target} -le ${#targets[@]} ]]
 	then
-		target=${targets[$((${target} - 1))]}
+		target=${targets[target-1]}
 	fi
 
 	has "${target}" "${targets[@]}" || die "Invalid target: ${target}"
@@ -333,16 +333,16 @@ describe_update() {
 }
 
 describe_update_options() {
-	echo "--if-unset    : Do not override existing implementation"
-	echo "--ignore SLOT : Ignore SLOT when setting symlinks"
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--if-unset    : do not alter preferences unless there is no valid preference set"
+	echo "--ignore SLOT : ignore specified Python slots"
+	echo "--python2     : update only Python 2 preferences"
+	echo "--python3     : update only Python 3 preferences"
 }
 
 do_update() {
 	local if_unset ignored_slots=() filter
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--if-unset)
 				if_unset=1
 				;;


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-04 22:02 Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-04 22:02 UTC (permalink / raw
  To: gentoo-commits

commit:     59630bedc0360d027b9b7d45a097bd7326e90871
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Feb  4 22:02:39 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Thu Feb  4 22:02:39 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=59630bed

Set open enough umask before writing updates

 python.eselect.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python.eselect.in b/python.eselect.in
index 2680d69..2e857bd 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -322,6 +322,7 @@ do_set() {
 	# need to do this outta loop in case no pref matches
 	prefs=( "${prefs[@]:0:target_idx}" "${target}" "${prefs[@]:target_idx}" )
 
+	umask 022
 	write_preferences "${prefs[@]}"
 	post_update
 }


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-05 19:56 Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-05 19:56 UTC (permalink / raw
  To: gentoo-commits

commit:     ac197657161e95587b22893612e0cf1118376808
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Feb  2 22:02:31 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 19:54:11 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=ac197657

Rewrite to use python-exec.conf, and cleanup

Use the new preference list configuration format added in
python-exec-2.3. While at it, clean up error handling and make the code
a bit simpler. Replace the notion of 'main interpreter' with the most
preferred installed interpreter.

 python.eselect.in | 458 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 235 insertions(+), 223 deletions(-)

diff --git a/python.eselect.in b/python.eselect.in
index 3d9b4bc..ee79262 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -1,163 +1,196 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2016 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 # $Id: $
 
-DESCRIPTION="Manage active Python interpreter"
+DESCRIPTION="Manage Python interpreter preferences"
 MAINTAINER="python@gentoo.org"
-SVN_DATE='$Date$'
-VERSION=$(svn_date_to_version "${SVN_DATE}" )
+VERSION=@VERSION@
 
+CONFIG_PATH="${EROOT%/}/etc/python-exec/python-exec.conf"
 ENV_D_PATH="${EROOT%/}/etc/env.d"
-INTERPRETER_PATH="${EROOT%/}/usr/bin/"
-MAN_PATH="${EROOT%/}/usr/share/man/man1/"
-
-PYTHON_INTERPRETERS_GROUP=""
-
-# Find a list of Python versions
-find_targets() {
-	local interpreter interpreters="python?.?@EXEEXT@"
+INTERPRETER_DIR="${EROOT%/}/usr/bin"
+MAN_PATH="${EROOT%/}/usr/share/man/man1"
+
+# Get list of all installed Python interpreters, in lexical order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_installed_pythons() {
+	local exes=( "${INTERPRETER_DIR}"/python?.?@EXEEXT@ )
+	local i
+	for (( i = ${#exes[@]}-1; i >= 0; --i )); do
+		local exe=${exes[i]}
+		[[ -x ${exe} ]] || continue
+		exe=${exe##*/}
+		exe=${exe%@EXEEXT@}
+		# apply filters
+		[[ ${1} == --py? && ${exe} != python${1:4}* ]] && continue
+
+		echo "${exe}"
+	done
+}
 
-	if [[ "${PYTHON_INTERPRETERS_GROUP}" == "2" ]]; then
-		interpreters="python2.?@EXEEXT@"
-	elif [[ "${PYTHON_INTERPRETERS_GROUP}" == "3" ]]; then
-		interpreters="python3.?@EXEEXT@"
-	fi
+# Get list of all preference values from python-exec.conf. This
+# includes both preferred implementations (in preference order)
+# and disabled interpreters.
+get_all_preferences() {
+	local l
+	while read l; do
+		# skip comments
+		[[ ${l} == '#'* ]] && continue
+
+		# note: empty lines are stripped through word splitting
+		echo "${l}"
+	done <"${CONFIG_PATH}"
+}
 
-	# Think twice before adding jython to this list. /usr/bin/jython
-	# is a bash wrapper that calls java-config, which is a Python
-	# script, so you need a valid /usr/bin/python to start jython.
-	for interpreter in "${INTERPRETER_PATH}"${interpreters}; do
-		if [[ -f "${interpreter}" ]]; then
-			echo ${interpreter#${INTERPRETER_PATH}}
-		fi
+# Get list of preferred Python interpreters, from python-exec.conf,
+# in preference order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_preferred_pythons() {
+	local i
+	for i in $(get_all_preferences); do
+		# skip negative entries
+		[[ ${i} == -* ]] && continue
+		# apply filters
+		[[ ${1} == --py? && ${i} != python${1:4}* ]] && continue
+
+		echo "${i}"
 	done
 }
 
-set_python_subver() {
-	local target=${1}
-	local subver=${target%.*}
-	mkdir -p "${ENV_D_PATH}/python"
-	echo "${target}" > "${ENV_D_PATH}/python/${subver}"
+# Get list of explicitly disabled Python interpreters, from
+# python-exec.conf, in file order.
+get_disabled_pythons() {
+	local i
+	for i in $(get_all_preferences); do
+		# process only negative entries
+		[[ ${i} == -* ]] || continue
+
+		echo "${i#-}"
+	done
 }
 
-set_python() {
-	local target="${1}"
-	mkdir -p "${ENV_D_PATH}/python"
-	echo "${target}" > "${ENV_D_PATH}/python/config"
+# Get combined list of preferred, installed and disabled Python
+# interpreters, in preference order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_all_pythons() {
+	local targets=( $(get_installed_pythons "${@}") )
+	local preferred=( $(get_preferred_pythons "${@}") )
+	local disabled=( $(get_disabled_pythons "${@}") )
+	local i
+
+	# preferred first
+	for i in "${preferred[@]}"; do
+		echo "${i}"
+	done
+	# active then
+	for i in "${targets[@]}"; do
+		has "${i}" "${preferred[@]}" && continue
+		has "${i}" "${disabled[@]}" && continue
+		echo "${i}"
+	done
+	# disabled last
+	for i in "${targets[@]}"; do
+		has "${i}" "${disabled[@]}" || continue
+		echo "${i}"
+	done
 }
 
-# Try to remove python and python.1 symlinks
-remove_symlinks() {
-	local symlink symlink_target symlink_target_found
-	if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-		rm -f "${MAN_PATH}"python.1{,.gz,.bz2,.lzma,.xz,.lz} &> /dev/null || return 1
-	fi
+# Write new preference list. Preferences need to be passed
+# as parameters (${@}).
+write_preferences() {
+	sed -n -e '/^#/p' "${CONFIG_PATH}" > "${CONFIG_PATH}".new || die
+	local IFS=$'\n'
+	echo "${*}" >> "${CONFIG_PATH}".new || die
 
-	# Files of Mac OS X framework
-	rm -f "${INTERPRETER_PATH%/bin/}/lib/Python.framework}"/{Headers,Python,Resources}
+	mv "${CONFIG_PATH}".new "${CONFIG_PATH}" || die
 }
 
 # Set a man page symlink
 set_man_symlink() {
-	local target="${1}" x extension
+	local target=${1} x suffix
 
-	for x in ".1" ".1.bz2" ".1.gz" ".1.lzma" ".1.xz" ".1.lz"; do
-		if [[ -e "${MAN_PATH}${target}${x}" ]]; then
-			extension="${x}"
+	rm -f "${MAN_PATH}"/python.1{,.gz,.bz2,.lzma,.xz,.lz} || die
+
+	for x in .1{,.gz,.bz2,.lzma,.xz,.lz}; do
+		if [[ -e "${MAN_PATH}/${target}${x}" ]]; then
+			suffix=${x}
 			break
 		fi
 	done
 
-	if [[ -z "${extension}" ]]; then
+	if [[ ! ${suffix} ]]; then
 		echo "Couldn't find a man page for ${target}; skipping." 1>&2
 		return 1
 	fi
 
-	pushd "${MAN_PATH}" 1> /dev/null
-	ln -nfs "${target}${extension}" "python${extension}"
-	popd 1> /dev/null
+	ln -nfs "${target}${extension}" "${MAN_PATH}/python${extension}" || die
 }
 
-# Set python-config script and appropriate symlinks
-set_scripts_and_symlinks() {
-	local target="${1}" targets=($(find_targets))
-	if is_number "${target}" && [[ ${target} -ge 1 ]]; then
-		target=${targets[$((${target} - 1))]}
-	fi
-
-	if ! has ${target} "${targets[@]}"; then
-		die -q "Invalid target ${target}"
-	fi
-	if [[ -f "${INTERPRETER_PATH}${target}" ]]; then
-		if ! remove_symlinks; then
-			die -q "Cannot remove symlinks"
-		fi
-
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_man_symlink "${target}"
-		fi
-
-		pushd "${INTERPRETER_PATH}" 1> /dev/null
-
-		set_python_subver "${target}"
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_python "${target}"
-
-			# Files of Mac OS X framework
-			local framework_dir="${INTERPRETER_PATH%/bin/}/lib/Python.framework"
-			if [[ -d "${framework_dir}" ]]; then
-				local version="${target#python}"
-				pushd "${framework_dir}" 1> /dev/null
-				ln -nfs "Versions/${version}/Headers"
-				ln -nfs "Versions/${version}/Python"
-				ln -nfs "Versions/${version}/Resources"
-				popd 1> /dev/null
-			fi
-		fi
+# Set OSX framework symlinks
+set_osx_framework() {
+	local target=${1}
 
-		popd 1> /dev/null
-	else
-		die -q "Target \"${1}\" doesn't appear to be valid!"
+	# Files of Mac OS X framework
+	local framework_dir="${INTERPRETER_DIR%/bin}"/lib/Python.framework
+	if [[ -d ${framework_dir} ]]; then
+		local version=${target#python}
+		pushd "${framework_dir}" >/dev/null || die
+		rm -f Headers Python Resources || die
+		ln -nfs "Versions/${version}/Headers" || die
+		ln -nfs "Versions/${version}/Python" || die
+		ln -nfs "Versions/${version}/Resources" || die
+		popd >/dev/null || die
 	fi
 }
 
 # Set the content of /etc/env.d/65python-docs
 set_python_docs() {
-	local path target="${1#python}" variable
-	rm -f "${ENV_D_PATH}/65python-docs"
-	if [[ -f "${ENV_D_PATH}/60python-docs-${target}" ]]; then
+	local path target=${1#python} variable
+	rm -f "${ENV_D_PATH}/65python-docs" || die
+	if [[ -f ${ENV_D_PATH}/60python-docs-${target} ]]; then
 		variable="PYTHONDOCS_${target//./_}"
-		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo -n "${!variable}")"
-		if [[ -d "${path}" ]]; then
+		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo "${!variable}")"
+		if [[ -d ${path} ]]; then
 			echo "PYTHONDOCS=\"${path}\"" > "${ENV_D_PATH}/65python-docs"
 		fi
 	fi
 }
 
+# Perform all necessary updates following preference list change.
+post_update() {
+	local main_interp=$(do_show)
+
+	# TODO: update only when necessary
+
+	set_man_symlink "${main_interp}"
+	set_osx_framework "${main_interp}"
+	set_python_docs "${main_interp}"
+}
+
 ### show action ###
 
 describe_show() {
-	echo "Show main active Python interpreter"
+	echo "Show the most preferred Python interpreter"
 }
 
 describe_show_options() {
-	echo "--ABI         : Show Python ABI in format of PYTHON_ABI variable"
-	echo "--python2     : Show active Python 2 interpreter"
-	echo "--python3     : Show active Python 3 interpreter"
+	echo "--ABI         : use PYTHON_ABI variable format (deprecated)"
+	echo "--python2     : show the preferred version of Python 2"
+	echo "--python3     : show the preferred version of Python 3"
 }
 
 do_show() {
-	local ABI="0" interpreter python2="0" python3="0"
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local abi filter interpreter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--ABI)
-				ABI="1"
+				abi=1
 				;;
-			--python2)
-				python2="1"
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -166,30 +199,22 @@ do_show() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
+	local preferred=( $(get_preferred_pythons ${filter}) )
+	local installed=( $(get_installed_pythons ${filter}) )
 
-	if [[ "${python2}" == "1" ]]; then
-		if [[ -f ${ENV_D_PATH}/python/python2 ]]; then
-			interpreter="$(<"${ENV_D_PATH}/python/python2")"
-		fi
-	elif [[ "${python3}" == "1" ]]; then
-		if [[ -f ${ENV_D_PATH}/python/python3 ]]; then
-			interpreter="$(<"${ENV_D_PATH}/python/python3")"
-		fi
-	elif [[ -f "${ENV_D_PATH}/python/config" ]]; then
-		interpreter="$(<"${ENV_D_PATH}/python/config")"
-	fi
+	# preferred are preferred, but fall back to anything
+	local i
+	for i in "${preferred[@]}" "${installed[@]}"; do
+		# skip if not installed
+		has "${i}" "${installed[@]}" || continue
+		interpreter=${i}
+		break
+	done
 
-	if [[ "${ABI}" == "1" ]]; then
-		echo -n "${interpreter#python}"
+	if [[ ${abi} ]]; then
+		echo "${interpreter#python}"
 	else
-		echo -n "${interpreter}"
-	fi
-
-	if [[ -n "${interpreter}" ]]; then
-		echo
+		echo "${interpreter}"
 	fi
 }
 
@@ -200,25 +225,19 @@ describe_list() {
 }
 
 describe_list_options() {
-	echo "--python2     : List installed Python 2 interpreters"
-	echo "--python3     : List installed Python 3 interpreters"
+	echo "--python2     : list only Python 2 interpreters"
+	echo "--python3     : list only Python 3 interpreters"
 }
 
 do_list() {
-	local active i python_descriptive_name="Python" python_version_option= python2="0" python3="0" targets=()
-	while [[ $# > 0 ]]; do
-		case "$1" in
-			--python2)
-				python2="1"
-				python_descriptive_name="Python 2"
-				python_version_option="--python2"
-				PYTHON_INTERPRETERS_GROUP="2"
+	local filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
-				python_descriptive_name="Python 3"
-				python_version_option="--python3"
-				PYTHON_INTERPRETERS_GROUP="3"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -227,32 +246,31 @@ do_list() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
+	local all=( $(get_all_pythons ${filter}) )
+	local preferred=( $(get_preferred_pythons ${filter}) )
+	local disabled=( $(get_disabled_pythons) )
 
-	targets=($(find_targets))
+	write_list_start "Available Python${filter+ ${filter#--py}} interpreters, in order of preference:"
 
-	write_list_start "Available ${python_descriptive_name} interpreters:"
-
-	active="$(do_show ${python_version_option})"
-	for ((i = 0; i < ${#targets[@]}; i++)); do
-		if [[ ${targets[${i}]} == ${active} ]]; then
-			targets[${i}]="$(highlight_marker "${targets[${i}]}")"
+	for (( i = 0; i < ${#all[@]}; ++i )); do
+		if has "${all[i]}" "${preferred[@]}"; then
+			all[i]=$(highlight_marker "${all[i]}")
+		elif has "${all[i]}" "${disabled[@]}"; then
+			all[i]=$(highlight_marker "${all[i]}" "$(highlight_warning -)")
 		fi
 	done
-	write_numbered_list -m "(none found)" "${targets[@]}"
+	write_numbered_list -m "(none found)" "${all[@]}"
 }
 
 ### set action ###
 
 describe_set() {
-	echo "Set main active Python interpreter"
+	echo "Set the preferred Python interpreter"
 }
 
 describe_set_options() {
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--python2     : update preference for Python 2 versions only"
+	echo "--python3     : update preference for Python 3 versions only"
 }
 
 describe_set_parameters() {
@@ -260,17 +278,14 @@ describe_set_parameters() {
 }
 
 do_set() {
-	local main_active_python_interpreter python2="0" python3="0"
-	SET_MAIN_ACTIVE_PYTHON_INTERPRETER="1"
-	while [[ $# > 0 ]]; do
-		case "$1" in
-			--python2)
-				python2="1"
-				PYTHON_INTERPRETERS_GROUP="2"
+	local filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
-				PYTHON_INTERPRETERS_GROUP="3"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				break
@@ -279,62 +294,72 @@ do_set() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
+	[[ ${#} -eq 1 ]] || die "Usage: eselect python set <interpreter>"
+
+	local target=${1}
+	local targets=( $(get_all_pythons ${filter}) )
+	if is_number "${target}" \
+		&& [[ ${target} -ge 1 && ${target} -le ${#targets[@]} ]]
+	then
+		target=${targets[target-1]}
 	fi
 
-	if [[ $# -lt 1 ]]; then
-		die -q "'eselect python set' requires Python interpreter filename"
-	elif [[ $# -gt 1 ]]; then
-		die -q "'eselect python set' requires 1 argument"
-	else
-		main_active_python_interpreter="$(do_show)"
-		if [[ "${python2}" == "1" && "${main_active_python_interpreter}" != "python2."* ]]; then
-			SET_MAIN_ACTIVE_PYTHON_INTERPRETER="0"
-		elif [[ "${python3}" == "1" && "${main_active_python_interpreter}" != "python3."* ]]; then
-			SET_MAIN_ACTIVE_PYTHON_INTERPRETER="0"
-		fi
+	has "${target}" "${targets[@]}" || die "Invalid target: ${target}"
 
-		if ! set_scripts_and_symlinks "${1}"; then
-			die -q "Can't set new provider"
-		fi
+	local prefs=( $(get_all_preferences) )
 
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_python_docs "${1}"
+	local i target_idx
+	for (( i = 0; i < ${#prefs[@]}; ++i )); do
+		# find first positive preference matching the filter
+		if [[ ! ${target_idx} ]]; then
+			if [[ ( ${filter} == --py? && ${prefs[i]} == python${filter:4}* ) \
+				|| ( ! ${filter} && ${prefs[i]} != -* ) ]]
+			then
+				target_idx=${i}
+			fi
 		fi
-	fi
+
+		# remove all duplicate positive and negative entries for target
+		[[ ${prefs[i]#-} == ${target} ]] && unset 'prefs[i]'
+	done
+
+	# add between remaining preferences, before the one matching
+	# need to do this outta loop in case no pref matches
+	prefs=( "${prefs[@]:0:target_idx}" "${target}" "${prefs[@]:target_idx}" )
+
+	write_preferences "${prefs[@]}"
+	post_update
 }
 
 ### update action ###
 
 describe_update() {
-	echo "Switch to the most recent CPython interpreter"
+	echo "Switch to the most recent Python interpreter"
 }
 
 describe_update_options() {
-	echo "--if-unset    : Do not override existing implementation"
-	echo "--ignore SLOT : Ignore SLOT when setting symlinks"
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--if-unset    : do not alter preferences unless there is no valid preference set"
+	echo "--ignore SLOT : ignore specified Python slots"
+	echo "--python2     : update only Python 2 preferences"
+	echo "--python3     : update only Python 3 preferences"
 }
 
 do_update() {
-	local if_unset="0" ignored_slots=() interpreters="python?.?@EXEEXT@" python2="0" python3="0" python_version_option= slot= target targets=()
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local if_unset ignored_slots=() filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--if-unset)
-				if_unset="1"
+				if_unset=1
 				;;
 			--ignore)
-				ignored_slots+=("${2}")
-				shift;;
-			--python2)
-				python2="1"
-				python_version_option="--python2"
+				ignored_slots+=( "${2}" )
+				shift
 				;;
-			--python3)
-				python3="1"
-				python_version_option="--python3"
+			--python2|--py2)
+				filter=--py2
+				;;
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -343,37 +368,24 @@ do_update() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
-
-	if [[ "${if_unset}" == "1" && -f "${ENV_D_PATH}/python/config" ]]; then
-		if [[ "${python2}" == "1" && -f "${ENV_D_PATH}/python/python2" ]]; then
-			return
-		elif [[ "${python3}" == "1" && -f "${ENV_D_PATH}/python/python3" ]]; then
-			return
-		elif [[ "${python2}" == "0" && "${python3}" == "0" ]]; then
-			return
-		fi
-	fi
+	if [[ ${if_unset} ]]; then
+		local current=$(do_show ${filter})
 
-	if [[ "${python2}" == "1" ]]; then
-		interpreters="python2.?@EXEEXT@"
-	elif [[ "${python3}" == "1" ]]; then
-		interpreters="python3.?@EXEEXT@"
+		[[ ${current} ]] && return
 	fi
 
-	targets=($(cd "${INTERPRETER_PATH}"; ls ${interpreters} 2> /dev/null | sort -r))
+	local targets=( $(get_installed_pythons ${filter}) )
 
 	# Ignore slots
+	local slot
 	for slot in ${ignored_slots[@]}; do
-		targets=(${targets[@]/python${slot}/})
+		targets=( ${targets[@]/python${slot}/} )
 	done
 
-	if [[ ${#targets[@]} -gt 0 ]]; then
-		target=${targets[0]}
+	if [[ ${targets[@]} ]]; then
+		local target=${targets[0]}
 		echo "Switching to ${target}"
-		do_set ${python_version_option} ${target}
+		do_set ${filter} "${target}"
 	else
 		die -q "No Python interpreter available"
 	fi


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-05 19:56 Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-05 19:56 UTC (permalink / raw
  To: gentoo-commits

commit:     488a692b45d1279f0c8955965d809621bf4388b5
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Feb  4 22:02:39 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 19:54:11 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=488a692b

Set open enough umask before writing updates

 python.eselect.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python.eselect.in b/python.eselect.in
index ee79262..c222460 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -327,6 +327,7 @@ do_set() {
 	# need to do this outta loop in case no pref matches
 	prefs=( "${prefs[@]:0:target_idx}" "${target}" "${prefs[@]:target_idx}" )
 
+	umask 022
 	write_preferences "${prefs[@]}"
 	post_update
 }


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-05 20:03 Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-05 20:03 UTC (permalink / raw
  To: gentoo-commits

commit:     027a224cab2883b8f240b59ec060c39929623100
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Fri Feb  5 20:02:06 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 20:02:06 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=027a224c

Add edit action

 python.eselect.in | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/python.eselect.in b/python.eselect.in
index c222460..94d751c 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -167,6 +167,18 @@ post_update() {
 	set_python_docs "${main_interp}"
 }
 
+### edit action ###
+
+describe_edit() {
+	echo "Edit the interpreter preference list"
+}
+
+do_edit() {
+	[[ ${EDITOR} ]] || die "EDITOR is not set"
+
+	${EDITOR} "${CONFIG_PATH}"
+}
+
 ### show action ###
 
 describe_show() {


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-05 20:36 Michał Górny
  2016-02-06  9:00 ` [gentoo-commits] proj/eselect-python:master " Michał Górny
  0 siblings, 1 reply; 9+ messages in thread
From: Michał Górny @ 2016-02-05 20:36 UTC (permalink / raw
  To: gentoo-commits

commit:     ce0d0242419fd7369d7febf2544d65f0e701c7ad
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Feb  2 22:02:31 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 20:36:30 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=ce0d0242

Rewrite to use python-exec.conf, and cleanup

Use the new preference list configuration format added in
python-exec-2.3. While at it, clean up error handling and make the code
a bit simpler. Replace the notion of 'main interpreter' with the most
preferred installed interpreter.

 python.eselect.in | 465 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 243 insertions(+), 222 deletions(-)

diff --git a/python.eselect.in b/python.eselect.in
index 3d9b4bc..aa4eaa7 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -1,163 +1,200 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2016 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 # $Id: $
 
-DESCRIPTION="Manage active Python interpreter"
+DESCRIPTION="Manage Python interpreter preferences"
 MAINTAINER="python@gentoo.org"
-SVN_DATE='$Date$'
-VERSION=$(svn_date_to_version "${SVN_DATE}" )
+VERSION=@VERSION@
 
+CONFIG_PATH="${EROOT%/}/etc/python-exec/python-exec.conf"
 ENV_D_PATH="${EROOT%/}/etc/env.d"
-INTERPRETER_PATH="${EROOT%/}/usr/bin/"
-MAN_PATH="${EROOT%/}/usr/share/man/man1/"
-
-PYTHON_INTERPRETERS_GROUP=""
-
-# Find a list of Python versions
-find_targets() {
-	local interpreter interpreters="python?.?@EXEEXT@"
+INTERPRETER_DIR="${EROOT%/}/usr/bin"
+MAN_PATH="${EROOT%/}/usr/share/man/man1"
+
+# Get list of all installed Python interpreters, in lexical order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_installed_pythons() {
+	local exes=( "${INTERPRETER_DIR}"/python?.?@EXEEXT@ )
+	local i
+	for (( i = ${#exes[@]}-1; i >= 0; --i )); do
+		local exe=${exes[i]}
+		[[ -x ${exe} ]] || continue
+		exe=${exe##*/}
+		exe=${exe%@EXEEXT@}
+		# apply filters
+		[[ ${1} == --py? && ${exe} != python${1:4}* ]] && continue
+
+		echo "${exe}"
+	done
+}
 
-	if [[ "${PYTHON_INTERPRETERS_GROUP}" == "2" ]]; then
-		interpreters="python2.?@EXEEXT@"
-	elif [[ "${PYTHON_INTERPRETERS_GROUP}" == "3" ]]; then
-		interpreters="python3.?@EXEEXT@"
-	fi
+# Get list of all preference values from python-exec.conf. This
+# includes both preferred implementations (in preference order)
+# and disabled interpreters.
+get_all_preferences() {
+	local l
+	while read l; do
+		# skip comments
+		[[ ${l} == '#'* ]] && continue
+
+		# note: empty lines are stripped through word splitting
+		echo "${l}"
+	done <"${CONFIG_PATH}"
+}
 
-	# Think twice before adding jython to this list. /usr/bin/jython
-	# is a bash wrapper that calls java-config, which is a Python
-	# script, so you need a valid /usr/bin/python to start jython.
-	for interpreter in "${INTERPRETER_PATH}"${interpreters}; do
-		if [[ -f "${interpreter}" ]]; then
-			echo ${interpreter#${INTERPRETER_PATH}}
-		fi
+# Get list of preferred Python interpreters, from python-exec.conf,
+# in preference order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_preferred_pythons() {
+	local i
+	for i in $(get_all_preferences); do
+		# skip negative entries
+		[[ ${i} == -* ]] && continue
+		# apply filters
+		[[ ${1} == --py? && ${i} != python${1:4}* ]] && continue
+
+		echo "${i}"
 	done
 }
 
-set_python_subver() {
-	local target=${1}
-	local subver=${target%.*}
-	mkdir -p "${ENV_D_PATH}/python"
-	echo "${target}" > "${ENV_D_PATH}/python/${subver}"
+# Get list of explicitly disabled Python interpreters, from
+# python-exec.conf, in file order.
+get_disabled_pythons() {
+	local i
+	for i in $(get_all_preferences); do
+		# process only negative entries
+		[[ ${i} == -* ]] || continue
+
+		echo "${i#-}"
+	done
 }
 
-set_python() {
-	local target="${1}"
-	mkdir -p "${ENV_D_PATH}/python"
-	echo "${target}" > "${ENV_D_PATH}/python/config"
+# Get combined list of preferred, installed and disabled Python
+# interpreters, in preference order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_all_pythons() {
+	local targets=( $(get_installed_pythons "${@}") )
+	local preferred=( $(get_preferred_pythons "${@}") )
+	local disabled=( $(get_disabled_pythons "${@}") )
+	local i
+
+	# preferred first
+	for i in "${preferred[@]}"; do
+		echo "${i}"
+	done
+	# active then
+	for i in "${targets[@]}"; do
+		has "${i}" "${preferred[@]}" && continue
+		has "${i}" "${disabled[@]}" && continue
+		echo "${i}"
+	done
+	# disabled last
+	for i in "${targets[@]}"; do
+		has "${i}" "${disabled[@]}" || continue
+		echo "${i}"
+	done
 }
 
-# Try to remove python and python.1 symlinks
-remove_symlinks() {
-	local symlink symlink_target symlink_target_found
-	if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-		rm -f "${MAN_PATH}"python.1{,.gz,.bz2,.lzma,.xz,.lz} &> /dev/null || return 1
-	fi
+# Write new preference list. Preferences need to be passed
+# as parameters (${@}).
+write_preferences() {
+	sed -n -e '/^#/p' "${CONFIG_PATH}" > "${CONFIG_PATH}".new || die
+	local IFS=$'\n'
+	echo "${*}" >> "${CONFIG_PATH}".new || die
 
-	# Files of Mac OS X framework
-	rm -f "${INTERPRETER_PATH%/bin/}/lib/Python.framework}"/{Headers,Python,Resources}
+	mv "${CONFIG_PATH}".new "${CONFIG_PATH}" || die
 }
 
 # Set a man page symlink
 set_man_symlink() {
-	local target="${1}" x extension
+	local target=${1} x suffix
 
-	for x in ".1" ".1.bz2" ".1.gz" ".1.lzma" ".1.xz" ".1.lz"; do
-		if [[ -e "${MAN_PATH}${target}${x}" ]]; then
-			extension="${x}"
+	rm -f "${MAN_PATH}"/python.1{,.gz,.bz2,.lzma,.xz,.lz} || die
+
+	for x in .1{,.gz,.bz2,.lzma,.xz,.lz}; do
+		if [[ -e "${MAN_PATH}/${target}${x}" ]]; then
+			suffix=${x}
 			break
 		fi
 	done
 
-	if [[ -z "${extension}" ]]; then
+	if [[ ! ${suffix} ]]; then
 		echo "Couldn't find a man page for ${target}; skipping." 1>&2
 		return 1
 	fi
 
-	pushd "${MAN_PATH}" 1> /dev/null
-	ln -nfs "${target}${extension}" "python${extension}"
-	popd 1> /dev/null
+	ln -nfs "${target}${extension}" "${MAN_PATH}/python${extension}" || die
 }
 
-# Set python-config script and appropriate symlinks
-set_scripts_and_symlinks() {
-	local target="${1}" targets=($(find_targets))
-	if is_number "${target}" && [[ ${target} -ge 1 ]]; then
-		target=${targets[$((${target} - 1))]}
-	fi
-
-	if ! has ${target} "${targets[@]}"; then
-		die -q "Invalid target ${target}"
-	fi
-	if [[ -f "${INTERPRETER_PATH}${target}" ]]; then
-		if ! remove_symlinks; then
-			die -q "Cannot remove symlinks"
-		fi
-
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_man_symlink "${target}"
-		fi
-
-		pushd "${INTERPRETER_PATH}" 1> /dev/null
-
-		set_python_subver "${target}"
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_python "${target}"
-
-			# Files of Mac OS X framework
-			local framework_dir="${INTERPRETER_PATH%/bin/}/lib/Python.framework"
-			if [[ -d "${framework_dir}" ]]; then
-				local version="${target#python}"
-				pushd "${framework_dir}" 1> /dev/null
-				ln -nfs "Versions/${version}/Headers"
-				ln -nfs "Versions/${version}/Python"
-				ln -nfs "Versions/${version}/Resources"
-				popd 1> /dev/null
-			fi
-		fi
+# Set OSX framework symlinks
+set_osx_framework() {
+	local target=${1}
 
-		popd 1> /dev/null
-	else
-		die -q "Target \"${1}\" doesn't appear to be valid!"
+	# Files of Mac OS X framework
+	local framework_dir="${INTERPRETER_DIR%/bin}"/lib/Python.framework
+	if [[ -d ${framework_dir} ]]; then
+		local version=${target#python}
+		pushd "${framework_dir}" >/dev/null || die
+		rm -f Headers Python Resources || die
+		ln -nfs "Versions/${version}/Headers" || die
+		ln -nfs "Versions/${version}/Python" || die
+		ln -nfs "Versions/${version}/Resources" || die
+		popd >/dev/null || die
 	fi
 }
 
 # Set the content of /etc/env.d/65python-docs
 set_python_docs() {
-	local path target="${1#python}" variable
-	rm -f "${ENV_D_PATH}/65python-docs"
-	if [[ -f "${ENV_D_PATH}/60python-docs-${target}" ]]; then
+	local path target=${1#python} variable
+	rm -f "${ENV_D_PATH}/65python-docs" || die
+	if [[ -f ${ENV_D_PATH}/60python-docs-${target} ]]; then
 		variable="PYTHONDOCS_${target//./_}"
-		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo -n "${!variable}")"
-		if [[ -d "${path}" ]]; then
+		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo "${!variable}")"
+		if [[ -d ${path} ]]; then
 			echo "PYTHONDOCS=\"${path}\"" > "${ENV_D_PATH}/65python-docs"
 		fi
 	fi
 }
 
+# Perform all necessary updates following preference list change.
+post_update() {
+	local main_interp=$(do_show)
+
+	# TODO: update only when necessary
+
+	set_man_symlink "${main_interp}"
+	set_osx_framework "${main_interp}"
+	set_python_docs "${main_interp}"
+}
+
 ### show action ###
 
 describe_show() {
-	echo "Show main active Python interpreter"
+	echo "Show the most preferred Python interpreter"
 }
 
 describe_show_options() {
-	echo "--ABI         : Show Python ABI in format of PYTHON_ABI variable"
-	echo "--python2     : Show active Python 2 interpreter"
-	echo "--python3     : Show active Python 3 interpreter"
+	echo "--ABI         : use PYTHON_ABI variable format (deprecated)"
+	echo "--pref-only   : consider only explicitly preferred impls"
+	echo "--python2     : show the preferred version of Python 2"
+	echo "--python3     : show the preferred version of Python 3"
 }
 
 do_show() {
-	local ABI="0" interpreter python2="0" python3="0"
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local abi filter interpreter pref_only
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--ABI)
-				ABI="1"
+				abi=1
+				;;
+			--pref-only)
+				pref_only=1
 				;;
-			--python2)
-				python2="1"
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -166,30 +203,25 @@ do_show() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
+	local preferred=( $(get_preferred_pythons ${filter}) )
+	local installed=()
+	if [[ ! ${pref_only} ]]; then
+		installed=( $(get_installed_pythons ${filter}) )
 	fi
 
-	if [[ "${python2}" == "1" ]]; then
-		if [[ -f ${ENV_D_PATH}/python/python2 ]]; then
-			interpreter="$(<"${ENV_D_PATH}/python/python2")"
-		fi
-	elif [[ "${python3}" == "1" ]]; then
-		if [[ -f ${ENV_D_PATH}/python/python3 ]]; then
-			interpreter="$(<"${ENV_D_PATH}/python/python3")"
-		fi
-	elif [[ -f "${ENV_D_PATH}/python/config" ]]; then
-		interpreter="$(<"${ENV_D_PATH}/python/config")"
-	fi
+	# preferred are preferred, but fall back to anything
+	local i
+	for i in "${preferred[@]}" "${installed[@]}"; do
+		# skip if not installed
+		has "${i}" "${installed[@]}" || continue
+		interpreter=${i}
+		break
+	done
 
-	if [[ "${ABI}" == "1" ]]; then
-		echo -n "${interpreter#python}"
+	if [[ ${abi} ]]; then
+		echo "${interpreter#python}"
 	else
-		echo -n "${interpreter}"
-	fi
-
-	if [[ -n "${interpreter}" ]]; then
-		echo
+		echo "${interpreter}"
 	fi
 }
 
@@ -200,25 +232,19 @@ describe_list() {
 }
 
 describe_list_options() {
-	echo "--python2     : List installed Python 2 interpreters"
-	echo "--python3     : List installed Python 3 interpreters"
+	echo "--python2     : list only Python 2 interpreters"
+	echo "--python3     : list only Python 3 interpreters"
 }
 
 do_list() {
-	local active i python_descriptive_name="Python" python_version_option= python2="0" python3="0" targets=()
-	while [[ $# > 0 ]]; do
-		case "$1" in
-			--python2)
-				python2="1"
-				python_descriptive_name="Python 2"
-				python_version_option="--python2"
-				PYTHON_INTERPRETERS_GROUP="2"
+	local filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
-				python_descriptive_name="Python 3"
-				python_version_option="--python3"
-				PYTHON_INTERPRETERS_GROUP="3"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -227,32 +253,31 @@ do_list() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
+	local all=( $(get_all_pythons ${filter}) )
+	local preferred=( $(get_preferred_pythons ${filter}) )
+	local disabled=( $(get_disabled_pythons) )
 
-	targets=($(find_targets))
+	write_list_start "Available Python${filter+ ${filter#--py}} interpreters, in order of preference:"
 
-	write_list_start "Available ${python_descriptive_name} interpreters:"
-
-	active="$(do_show ${python_version_option})"
-	for ((i = 0; i < ${#targets[@]}; i++)); do
-		if [[ ${targets[${i}]} == ${active} ]]; then
-			targets[${i}]="$(highlight_marker "${targets[${i}]}")"
+	for (( i = 0; i < ${#all[@]}; ++i )); do
+		if has "${all[i]}" "${preferred[@]}"; then
+			all[i]=$(highlight_marker "${all[i]}")
+		elif has "${all[i]}" "${disabled[@]}"; then
+			all[i]=$(highlight_marker "${all[i]}" "$(highlight_warning -)")
 		fi
 	done
-	write_numbered_list -m "(none found)" "${targets[@]}"
+	write_numbered_list -m "(none found)" "${all[@]}"
 }
 
 ### set action ###
 
 describe_set() {
-	echo "Set main active Python interpreter"
+	echo "Set the preferred Python interpreter"
 }
 
 describe_set_options() {
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--python2     : update preference for Python 2 versions only"
+	echo "--python3     : update preference for Python 3 versions only"
 }
 
 describe_set_parameters() {
@@ -260,17 +285,14 @@ describe_set_parameters() {
 }
 
 do_set() {
-	local main_active_python_interpreter python2="0" python3="0"
-	SET_MAIN_ACTIVE_PYTHON_INTERPRETER="1"
-	while [[ $# > 0 ]]; do
-		case "$1" in
-			--python2)
-				python2="1"
-				PYTHON_INTERPRETERS_GROUP="2"
+	local filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
-				PYTHON_INTERPRETERS_GROUP="3"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				break
@@ -279,62 +301,74 @@ do_set() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
+	[[ ${#} -eq 1 ]] || die "Usage: eselect python set <interpreter>"
+
+	local target=${1}
+	local targets=( $(get_all_pythons ${filter}) )
+	if is_number "${target}" \
+		&& [[ ${target} -ge 1 && ${target} -le ${#targets[@]} ]]
+	then
+		target=${targets[target-1]}
 	fi
 
-	if [[ $# -lt 1 ]]; then
-		die -q "'eselect python set' requires Python interpreter filename"
-	elif [[ $# -gt 1 ]]; then
-		die -q "'eselect python set' requires 1 argument"
-	else
-		main_active_python_interpreter="$(do_show)"
-		if [[ "${python2}" == "1" && "${main_active_python_interpreter}" != "python2."* ]]; then
-			SET_MAIN_ACTIVE_PYTHON_INTERPRETER="0"
-		elif [[ "${python3}" == "1" && "${main_active_python_interpreter}" != "python3."* ]]; then
-			SET_MAIN_ACTIVE_PYTHON_INTERPRETER="0"
-		fi
+	has "${target}" "${targets[@]}" || die "Invalid target: ${target}"
 
-		if ! set_scripts_and_symlinks "${1}"; then
-			die -q "Can't set new provider"
-		fi
+	local prefs=( $(get_all_preferences) )
 
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_python_docs "${1}"
+	local i target_idx
+	for (( i = 0; i < ${#prefs[@]}; ++i )); do
+		# find first positive preference matching the filter
+		if [[ ! ${target_idx} ]]; then
+			if [[ ( ${filter} == --py? && ${prefs[i]} == python${filter:4}* ) \
+				|| ( ! ${filter} && ${prefs[i]} != -* ) ]]
+			then
+				target_idx=${i}
+			fi
 		fi
-	fi
+
+		# remove all duplicate positive and negative entries for target
+		[[ ${prefs[i]#-} == ${target} ]] && unset 'prefs[i]'
+	done
+	# if none matched, add to the bottom
+	: "${target_idx=${#prefs[@]}}"
+
+	# add between remaining preferences, before the one matching
+	# need to do this outta loop in case no pref matches
+	prefs=( "${prefs[@]:0:target_idx}" "${target}" "${prefs[@]:target_idx}" )
+
+	write_preferences "${prefs[@]}"
+	post_update
 }
 
 ### update action ###
 
 describe_update() {
-	echo "Switch to the most recent CPython interpreter"
+	echo "Switch to the most recent Python interpreter"
 }
 
 describe_update_options() {
-	echo "--if-unset    : Do not override existing implementation"
-	echo "--ignore SLOT : Ignore SLOT when setting symlinks"
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--if-unset    : do not alter preferences unless there is no valid preference set"
+	echo "--ignore SLOT : ignore specified Python slots"
+	echo "--python2     : update only Python 2 preferences"
+	echo "--python3     : update only Python 3 preferences"
 }
 
 do_update() {
-	local if_unset="0" ignored_slots=() interpreters="python?.?@EXEEXT@" python2="0" python3="0" python_version_option= slot= target targets=()
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local if_unset ignored_slots=() filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--if-unset)
-				if_unset="1"
+				if_unset=1
 				;;
 			--ignore)
-				ignored_slots+=("${2}")
-				shift;;
-			--python2)
-				python2="1"
-				python_version_option="--python2"
+				ignored_slots+=( "${2}" )
+				shift
 				;;
-			--python3)
-				python3="1"
-				python_version_option="--python3"
+			--python2|--py2)
+				filter=--py2
+				;;
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -343,37 +377,24 @@ do_update() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
-
-	if [[ "${if_unset}" == "1" && -f "${ENV_D_PATH}/python/config" ]]; then
-		if [[ "${python2}" == "1" && -f "${ENV_D_PATH}/python/python2" ]]; then
-			return
-		elif [[ "${python3}" == "1" && -f "${ENV_D_PATH}/python/python3" ]]; then
-			return
-		elif [[ "${python2}" == "0" && "${python3}" == "0" ]]; then
-			return
-		fi
-	fi
+	if [[ ${if_unset} ]]; then
+		local current=$(do_show ${filter} --pref-only)
 
-	if [[ "${python2}" == "1" ]]; then
-		interpreters="python2.?@EXEEXT@"
-	elif [[ "${python3}" == "1" ]]; then
-		interpreters="python3.?@EXEEXT@"
+		[[ ${current} ]] && return
 	fi
 
-	targets=($(cd "${INTERPRETER_PATH}"; ls ${interpreters} 2> /dev/null | sort -r))
+	local targets=( $(get_installed_pythons ${filter}) )
 
 	# Ignore slots
+	local slot
 	for slot in ${ignored_slots[@]}; do
-		targets=(${targets[@]/python${slot}/})
+		targets=( ${targets[@]/python${slot}/} )
 	done
 
-	if [[ ${#targets[@]} -gt 0 ]]; then
-		target=${targets[0]}
+	if [[ ${targets[@]} ]]; then
+		local target=${targets[0]}
 		echo "Switching to ${target}"
-		do_set ${python_version_option} ${target}
+		do_set ${filter} "${target}"
 	else
 		die -q "No Python interpreter available"
 	fi


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
@ 2016-02-05 20:36 Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-05 20:36 UTC (permalink / raw
  To: gentoo-commits

commit:     808be74d51901c942fce1ddd0bb69d910b2a5d9c
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Feb  4 22:02:39 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 20:36:30 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=808be74d

Set open enough umask before writing updates

 python.eselect.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python.eselect.in b/python.eselect.in
index aa4eaa7..d84f1ef 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -336,6 +336,7 @@ do_set() {
 	# need to do this outta loop in case no pref matches
 	prefs=( "${prefs[@]:0:target_idx}" "${target}" "${prefs[@]:target_idx}" )
 
+	umask 022
 	write_preferences "${prefs[@]}"
 	post_update
 }


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: /
  2016-02-06  9:00 Michał Górny
@ 2016-02-05 20:36 ` Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-05 20:36 UTC (permalink / raw
  To: gentoo-commits

commit:     bfce7d731ce9c41c6bc3e5b8acf26f4d2ec53e32
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Fri Feb  5 20:02:06 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 20:36:30 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=bfce7d73

Add edit action

 python.eselect.in | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/python.eselect.in b/python.eselect.in
index d84f1ef..bbe024f 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -167,6 +167,18 @@ post_update() {
 	set_python_docs "${main_interp}"
 }
 
+### edit action ###
+
+describe_edit() {
+	echo "Edit the interpreter preference list"
+}
+
+do_edit() {
+	[[ ${EDITOR} ]] || die "EDITOR is not set"
+
+	${EDITOR} "${CONFIG_PATH}"
+}
+
 ### show action ###
 
 describe_show() {


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/eselect-python:master commit in: /
  2016-02-05 20:36 [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: / Michał Górny
@ 2016-02-06  9:00 ` Michał Górny
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Górny @ 2016-02-06  9:00 UTC (permalink / raw
  To: gentoo-commits

commit:     ce0d0242419fd7369d7febf2544d65f0e701c7ad
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Feb  2 22:02:31 2016 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Fri Feb  5 20:36:30 2016 +0000
URL:        https://gitweb.gentoo.org/proj/eselect-python.git/commit/?id=ce0d0242

Rewrite to use python-exec.conf, and cleanup

Use the new preference list configuration format added in
python-exec-2.3. While at it, clean up error handling and make the code
a bit simpler. Replace the notion of 'main interpreter' with the most
preferred installed interpreter.

 python.eselect.in | 465 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 243 insertions(+), 222 deletions(-)

diff --git a/python.eselect.in b/python.eselect.in
index 3d9b4bc..aa4eaa7 100644
--- a/python.eselect.in
+++ b/python.eselect.in
@@ -1,163 +1,200 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2016 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 # $Id: $
 
-DESCRIPTION="Manage active Python interpreter"
+DESCRIPTION="Manage Python interpreter preferences"
 MAINTAINER="python@gentoo.org"
-SVN_DATE='$Date$'
-VERSION=$(svn_date_to_version "${SVN_DATE}" )
+VERSION=@VERSION@
 
+CONFIG_PATH="${EROOT%/}/etc/python-exec/python-exec.conf"
 ENV_D_PATH="${EROOT%/}/etc/env.d"
-INTERPRETER_PATH="${EROOT%/}/usr/bin/"
-MAN_PATH="${EROOT%/}/usr/share/man/man1/"
-
-PYTHON_INTERPRETERS_GROUP=""
-
-# Find a list of Python versions
-find_targets() {
-	local interpreter interpreters="python?.?@EXEEXT@"
+INTERPRETER_DIR="${EROOT%/}/usr/bin"
+MAN_PATH="${EROOT%/}/usr/share/man/man1"
+
+# Get list of all installed Python interpreters, in lexical order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_installed_pythons() {
+	local exes=( "${INTERPRETER_DIR}"/python?.?@EXEEXT@ )
+	local i
+	for (( i = ${#exes[@]}-1; i >= 0; --i )); do
+		local exe=${exes[i]}
+		[[ -x ${exe} ]] || continue
+		exe=${exe##*/}
+		exe=${exe%@EXEEXT@}
+		# apply filters
+		[[ ${1} == --py? && ${exe} != python${1:4}* ]] && continue
+
+		echo "${exe}"
+	done
+}
 
-	if [[ "${PYTHON_INTERPRETERS_GROUP}" == "2" ]]; then
-		interpreters="python2.?@EXEEXT@"
-	elif [[ "${PYTHON_INTERPRETERS_GROUP}" == "3" ]]; then
-		interpreters="python3.?@EXEEXT@"
-	fi
+# Get list of all preference values from python-exec.conf. This
+# includes both preferred implementations (in preference order)
+# and disabled interpreters.
+get_all_preferences() {
+	local l
+	while read l; do
+		# skip comments
+		[[ ${l} == '#'* ]] && continue
+
+		# note: empty lines are stripped through word splitting
+		echo "${l}"
+	done <"${CONFIG_PATH}"
+}
 
-	# Think twice before adding jython to this list. /usr/bin/jython
-	# is a bash wrapper that calls java-config, which is a Python
-	# script, so you need a valid /usr/bin/python to start jython.
-	for interpreter in "${INTERPRETER_PATH}"${interpreters}; do
-		if [[ -f "${interpreter}" ]]; then
-			echo ${interpreter#${INTERPRETER_PATH}}
-		fi
+# Get list of preferred Python interpreters, from python-exec.conf,
+# in preference order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_preferred_pythons() {
+	local i
+	for i in $(get_all_preferences); do
+		# skip negative entries
+		[[ ${i} == -* ]] && continue
+		# apply filters
+		[[ ${1} == --py? && ${i} != python${1:4}* ]] && continue
+
+		echo "${i}"
 	done
 }
 
-set_python_subver() {
-	local target=${1}
-	local subver=${target%.*}
-	mkdir -p "${ENV_D_PATH}/python"
-	echo "${target}" > "${ENV_D_PATH}/python/${subver}"
+# Get list of explicitly disabled Python interpreters, from
+# python-exec.conf, in file order.
+get_disabled_pythons() {
+	local i
+	for i in $(get_all_preferences); do
+		# process only negative entries
+		[[ ${i} == -* ]] || continue
+
+		echo "${i#-}"
+	done
 }
 
-set_python() {
-	local target="${1}"
-	mkdir -p "${ENV_D_PATH}/python"
-	echo "${target}" > "${ENV_D_PATH}/python/config"
+# Get combined list of preferred, installed and disabled Python
+# interpreters, in preference order.
+# $1 can be --pyN to filter results to pythonN.?.
+get_all_pythons() {
+	local targets=( $(get_installed_pythons "${@}") )
+	local preferred=( $(get_preferred_pythons "${@}") )
+	local disabled=( $(get_disabled_pythons "${@}") )
+	local i
+
+	# preferred first
+	for i in "${preferred[@]}"; do
+		echo "${i}"
+	done
+	# active then
+	for i in "${targets[@]}"; do
+		has "${i}" "${preferred[@]}" && continue
+		has "${i}" "${disabled[@]}" && continue
+		echo "${i}"
+	done
+	# disabled last
+	for i in "${targets[@]}"; do
+		has "${i}" "${disabled[@]}" || continue
+		echo "${i}"
+	done
 }
 
-# Try to remove python and python.1 symlinks
-remove_symlinks() {
-	local symlink symlink_target symlink_target_found
-	if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-		rm -f "${MAN_PATH}"python.1{,.gz,.bz2,.lzma,.xz,.lz} &> /dev/null || return 1
-	fi
+# Write new preference list. Preferences need to be passed
+# as parameters (${@}).
+write_preferences() {
+	sed -n -e '/^#/p' "${CONFIG_PATH}" > "${CONFIG_PATH}".new || die
+	local IFS=$'\n'
+	echo "${*}" >> "${CONFIG_PATH}".new || die
 
-	# Files of Mac OS X framework
-	rm -f "${INTERPRETER_PATH%/bin/}/lib/Python.framework}"/{Headers,Python,Resources}
+	mv "${CONFIG_PATH}".new "${CONFIG_PATH}" || die
 }
 
 # Set a man page symlink
 set_man_symlink() {
-	local target="${1}" x extension
+	local target=${1} x suffix
 
-	for x in ".1" ".1.bz2" ".1.gz" ".1.lzma" ".1.xz" ".1.lz"; do
-		if [[ -e "${MAN_PATH}${target}${x}" ]]; then
-			extension="${x}"
+	rm -f "${MAN_PATH}"/python.1{,.gz,.bz2,.lzma,.xz,.lz} || die
+
+	for x in .1{,.gz,.bz2,.lzma,.xz,.lz}; do
+		if [[ -e "${MAN_PATH}/${target}${x}" ]]; then
+			suffix=${x}
 			break
 		fi
 	done
 
-	if [[ -z "${extension}" ]]; then
+	if [[ ! ${suffix} ]]; then
 		echo "Couldn't find a man page for ${target}; skipping." 1>&2
 		return 1
 	fi
 
-	pushd "${MAN_PATH}" 1> /dev/null
-	ln -nfs "${target}${extension}" "python${extension}"
-	popd 1> /dev/null
+	ln -nfs "${target}${extension}" "${MAN_PATH}/python${extension}" || die
 }
 
-# Set python-config script and appropriate symlinks
-set_scripts_and_symlinks() {
-	local target="${1}" targets=($(find_targets))
-	if is_number "${target}" && [[ ${target} -ge 1 ]]; then
-		target=${targets[$((${target} - 1))]}
-	fi
-
-	if ! has ${target} "${targets[@]}"; then
-		die -q "Invalid target ${target}"
-	fi
-	if [[ -f "${INTERPRETER_PATH}${target}" ]]; then
-		if ! remove_symlinks; then
-			die -q "Cannot remove symlinks"
-		fi
-
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_man_symlink "${target}"
-		fi
-
-		pushd "${INTERPRETER_PATH}" 1> /dev/null
-
-		set_python_subver "${target}"
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_python "${target}"
-
-			# Files of Mac OS X framework
-			local framework_dir="${INTERPRETER_PATH%/bin/}/lib/Python.framework"
-			if [[ -d "${framework_dir}" ]]; then
-				local version="${target#python}"
-				pushd "${framework_dir}" 1> /dev/null
-				ln -nfs "Versions/${version}/Headers"
-				ln -nfs "Versions/${version}/Python"
-				ln -nfs "Versions/${version}/Resources"
-				popd 1> /dev/null
-			fi
-		fi
+# Set OSX framework symlinks
+set_osx_framework() {
+	local target=${1}
 
-		popd 1> /dev/null
-	else
-		die -q "Target \"${1}\" doesn't appear to be valid!"
+	# Files of Mac OS X framework
+	local framework_dir="${INTERPRETER_DIR%/bin}"/lib/Python.framework
+	if [[ -d ${framework_dir} ]]; then
+		local version=${target#python}
+		pushd "${framework_dir}" >/dev/null || die
+		rm -f Headers Python Resources || die
+		ln -nfs "Versions/${version}/Headers" || die
+		ln -nfs "Versions/${version}/Python" || die
+		ln -nfs "Versions/${version}/Resources" || die
+		popd >/dev/null || die
 	fi
 }
 
 # Set the content of /etc/env.d/65python-docs
 set_python_docs() {
-	local path target="${1#python}" variable
-	rm -f "${ENV_D_PATH}/65python-docs"
-	if [[ -f "${ENV_D_PATH}/60python-docs-${target}" ]]; then
+	local path target=${1#python} variable
+	rm -f "${ENV_D_PATH}/65python-docs" || die
+	if [[ -f ${ENV_D_PATH}/60python-docs-${target} ]]; then
 		variable="PYTHONDOCS_${target//./_}"
-		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo -n "${!variable}")"
-		if [[ -d "${path}" ]]; then
+		path="$(. "${ENV_D_PATH}/60python-docs-${target}"; echo "${!variable}")"
+		if [[ -d ${path} ]]; then
 			echo "PYTHONDOCS=\"${path}\"" > "${ENV_D_PATH}/65python-docs"
 		fi
 	fi
 }
 
+# Perform all necessary updates following preference list change.
+post_update() {
+	local main_interp=$(do_show)
+
+	# TODO: update only when necessary
+
+	set_man_symlink "${main_interp}"
+	set_osx_framework "${main_interp}"
+	set_python_docs "${main_interp}"
+}
+
 ### show action ###
 
 describe_show() {
-	echo "Show main active Python interpreter"
+	echo "Show the most preferred Python interpreter"
 }
 
 describe_show_options() {
-	echo "--ABI         : Show Python ABI in format of PYTHON_ABI variable"
-	echo "--python2     : Show active Python 2 interpreter"
-	echo "--python3     : Show active Python 3 interpreter"
+	echo "--ABI         : use PYTHON_ABI variable format (deprecated)"
+	echo "--pref-only   : consider only explicitly preferred impls"
+	echo "--python2     : show the preferred version of Python 2"
+	echo "--python3     : show the preferred version of Python 3"
 }
 
 do_show() {
-	local ABI="0" interpreter python2="0" python3="0"
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local abi filter interpreter pref_only
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--ABI)
-				ABI="1"
+				abi=1
+				;;
+			--pref-only)
+				pref_only=1
 				;;
-			--python2)
-				python2="1"
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -166,30 +203,25 @@ do_show() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
+	local preferred=( $(get_preferred_pythons ${filter}) )
+	local installed=()
+	if [[ ! ${pref_only} ]]; then
+		installed=( $(get_installed_pythons ${filter}) )
 	fi
 
-	if [[ "${python2}" == "1" ]]; then
-		if [[ -f ${ENV_D_PATH}/python/python2 ]]; then
-			interpreter="$(<"${ENV_D_PATH}/python/python2")"
-		fi
-	elif [[ "${python3}" == "1" ]]; then
-		if [[ -f ${ENV_D_PATH}/python/python3 ]]; then
-			interpreter="$(<"${ENV_D_PATH}/python/python3")"
-		fi
-	elif [[ -f "${ENV_D_PATH}/python/config" ]]; then
-		interpreter="$(<"${ENV_D_PATH}/python/config")"
-	fi
+	# preferred are preferred, but fall back to anything
+	local i
+	for i in "${preferred[@]}" "${installed[@]}"; do
+		# skip if not installed
+		has "${i}" "${installed[@]}" || continue
+		interpreter=${i}
+		break
+	done
 
-	if [[ "${ABI}" == "1" ]]; then
-		echo -n "${interpreter#python}"
+	if [[ ${abi} ]]; then
+		echo "${interpreter#python}"
 	else
-		echo -n "${interpreter}"
-	fi
-
-	if [[ -n "${interpreter}" ]]; then
-		echo
+		echo "${interpreter}"
 	fi
 }
 
@@ -200,25 +232,19 @@ describe_list() {
 }
 
 describe_list_options() {
-	echo "--python2     : List installed Python 2 interpreters"
-	echo "--python3     : List installed Python 3 interpreters"
+	echo "--python2     : list only Python 2 interpreters"
+	echo "--python3     : list only Python 3 interpreters"
 }
 
 do_list() {
-	local active i python_descriptive_name="Python" python_version_option= python2="0" python3="0" targets=()
-	while [[ $# > 0 ]]; do
-		case "$1" in
-			--python2)
-				python2="1"
-				python_descriptive_name="Python 2"
-				python_version_option="--python2"
-				PYTHON_INTERPRETERS_GROUP="2"
+	local filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
-				python_descriptive_name="Python 3"
-				python_version_option="--python3"
-				PYTHON_INTERPRETERS_GROUP="3"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -227,32 +253,31 @@ do_list() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
+	local all=( $(get_all_pythons ${filter}) )
+	local preferred=( $(get_preferred_pythons ${filter}) )
+	local disabled=( $(get_disabled_pythons) )
 
-	targets=($(find_targets))
+	write_list_start "Available Python${filter+ ${filter#--py}} interpreters, in order of preference:"
 
-	write_list_start "Available ${python_descriptive_name} interpreters:"
-
-	active="$(do_show ${python_version_option})"
-	for ((i = 0; i < ${#targets[@]}; i++)); do
-		if [[ ${targets[${i}]} == ${active} ]]; then
-			targets[${i}]="$(highlight_marker "${targets[${i}]}")"
+	for (( i = 0; i < ${#all[@]}; ++i )); do
+		if has "${all[i]}" "${preferred[@]}"; then
+			all[i]=$(highlight_marker "${all[i]}")
+		elif has "${all[i]}" "${disabled[@]}"; then
+			all[i]=$(highlight_marker "${all[i]}" "$(highlight_warning -)")
 		fi
 	done
-	write_numbered_list -m "(none found)" "${targets[@]}"
+	write_numbered_list -m "(none found)" "${all[@]}"
 }
 
 ### set action ###
 
 describe_set() {
-	echo "Set main active Python interpreter"
+	echo "Set the preferred Python interpreter"
 }
 
 describe_set_options() {
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--python2     : update preference for Python 2 versions only"
+	echo "--python3     : update preference for Python 3 versions only"
 }
 
 describe_set_parameters() {
@@ -260,17 +285,14 @@ describe_set_parameters() {
 }
 
 do_set() {
-	local main_active_python_interpreter python2="0" python3="0"
-	SET_MAIN_ACTIVE_PYTHON_INTERPRETER="1"
-	while [[ $# > 0 ]]; do
-		case "$1" in
-			--python2)
-				python2="1"
-				PYTHON_INTERPRETERS_GROUP="2"
+	local filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
+			--python2|--py2)
+				filter=--py2
 				;;
-			--python3)
-				python3="1"
-				PYTHON_INTERPRETERS_GROUP="3"
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				break
@@ -279,62 +301,74 @@ do_set() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
+	[[ ${#} -eq 1 ]] || die "Usage: eselect python set <interpreter>"
+
+	local target=${1}
+	local targets=( $(get_all_pythons ${filter}) )
+	if is_number "${target}" \
+		&& [[ ${target} -ge 1 && ${target} -le ${#targets[@]} ]]
+	then
+		target=${targets[target-1]}
 	fi
 
-	if [[ $# -lt 1 ]]; then
-		die -q "'eselect python set' requires Python interpreter filename"
-	elif [[ $# -gt 1 ]]; then
-		die -q "'eselect python set' requires 1 argument"
-	else
-		main_active_python_interpreter="$(do_show)"
-		if [[ "${python2}" == "1" && "${main_active_python_interpreter}" != "python2."* ]]; then
-			SET_MAIN_ACTIVE_PYTHON_INTERPRETER="0"
-		elif [[ "${python3}" == "1" && "${main_active_python_interpreter}" != "python3."* ]]; then
-			SET_MAIN_ACTIVE_PYTHON_INTERPRETER="0"
-		fi
+	has "${target}" "${targets[@]}" || die "Invalid target: ${target}"
 
-		if ! set_scripts_and_symlinks "${1}"; then
-			die -q "Can't set new provider"
-		fi
+	local prefs=( $(get_all_preferences) )
 
-		if [[ "${SET_MAIN_ACTIVE_PYTHON_INTERPRETER}" == "1" ]]; then
-			set_python_docs "${1}"
+	local i target_idx
+	for (( i = 0; i < ${#prefs[@]}; ++i )); do
+		# find first positive preference matching the filter
+		if [[ ! ${target_idx} ]]; then
+			if [[ ( ${filter} == --py? && ${prefs[i]} == python${filter:4}* ) \
+				|| ( ! ${filter} && ${prefs[i]} != -* ) ]]
+			then
+				target_idx=${i}
+			fi
 		fi
-	fi
+
+		# remove all duplicate positive and negative entries for target
+		[[ ${prefs[i]#-} == ${target} ]] && unset 'prefs[i]'
+	done
+	# if none matched, add to the bottom
+	: "${target_idx=${#prefs[@]}}"
+
+	# add between remaining preferences, before the one matching
+	# need to do this outta loop in case no pref matches
+	prefs=( "${prefs[@]:0:target_idx}" "${target}" "${prefs[@]:target_idx}" )
+
+	write_preferences "${prefs[@]}"
+	post_update
 }
 
 ### update action ###
 
 describe_update() {
-	echo "Switch to the most recent CPython interpreter"
+	echo "Switch to the most recent Python interpreter"
 }
 
 describe_update_options() {
-	echo "--if-unset    : Do not override existing implementation"
-	echo "--ignore SLOT : Ignore SLOT when setting symlinks"
-	echo "--python2     : Set active Python 2 interpreter without setting of main active Python interpreter if it is not set to Python 2"
-	echo "--python3     : Set active Python 3 interpreter without setting of main active Python interpreter if it is not set to Python 3"
+	echo "--if-unset    : do not alter preferences unless there is no valid preference set"
+	echo "--ignore SLOT : ignore specified Python slots"
+	echo "--python2     : update only Python 2 preferences"
+	echo "--python3     : update only Python 3 preferences"
 }
 
 do_update() {
-	local if_unset="0" ignored_slots=() interpreters="python?.?@EXEEXT@" python2="0" python3="0" python_version_option= slot= target targets=()
-	while [[ $# > 0 ]]; do
-		case "$1" in
+	local if_unset ignored_slots=() filter
+	while [[ ${#} -gt 0 ]]; do
+		case ${1} in
 			--if-unset)
-				if_unset="1"
+				if_unset=1
 				;;
 			--ignore)
-				ignored_slots+=("${2}")
-				shift;;
-			--python2)
-				python2="1"
-				python_version_option="--python2"
+				ignored_slots+=( "${2}" )
+				shift
 				;;
-			--python3)
-				python3="1"
-				python_version_option="--python3"
+			--python2|--py2)
+				filter=--py2
+				;;
+			--python3|--py3)
+				filter=--py3
 				;;
 			*)
 				die -q "Unrecognized argument '$1'"
@@ -343,37 +377,24 @@ do_update() {
 		shift
 	done
 
-	if [[ "${python2}" == "1" && "${python3}" == "1" ]]; then
-		die -q "'--python2' and '--python3' options cannot be specified simultaneously"
-	fi
-
-	if [[ "${if_unset}" == "1" && -f "${ENV_D_PATH}/python/config" ]]; then
-		if [[ "${python2}" == "1" && -f "${ENV_D_PATH}/python/python2" ]]; then
-			return
-		elif [[ "${python3}" == "1" && -f "${ENV_D_PATH}/python/python3" ]]; then
-			return
-		elif [[ "${python2}" == "0" && "${python3}" == "0" ]]; then
-			return
-		fi
-	fi
+	if [[ ${if_unset} ]]; then
+		local current=$(do_show ${filter} --pref-only)
 
-	if [[ "${python2}" == "1" ]]; then
-		interpreters="python2.?@EXEEXT@"
-	elif [[ "${python3}" == "1" ]]; then
-		interpreters="python3.?@EXEEXT@"
+		[[ ${current} ]] && return
 	fi
 
-	targets=($(cd "${INTERPRETER_PATH}"; ls ${interpreters} 2> /dev/null | sort -r))
+	local targets=( $(get_installed_pythons ${filter}) )
 
 	# Ignore slots
+	local slot
 	for slot in ${ignored_slots[@]}; do
-		targets=(${targets[@]/python${slot}/})
+		targets=( ${targets[@]/python${slot}/} )
 	done
 
-	if [[ ${#targets[@]} -gt 0 ]]; then
-		target=${targets[0]}
+	if [[ ${targets[@]} ]]; then
+		local target=${targets[0]}
 		echo "Switching to ${target}"
-		do_set ${python_version_option} ${target}
+		do_set ${filter} "${target}"
 	else
 		die -q "No Python interpreter available"
 	fi


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-02-06  9:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-05 20:36 [gentoo-commits] proj/eselect-python:pyexec-2.3 commit in: / Michał Górny
2016-02-06  9:00 ` [gentoo-commits] proj/eselect-python:master " Michał Górny
  -- strict thread matches above, loose matches on Subject: below --
2016-02-06  9:00 Michał Górny
2016-02-05 20:36 ` [gentoo-commits] proj/eselect-python:pyexec-2.3 " Michał Górny
2016-02-05 20:36 Michał Górny
2016-02-05 20:03 Michał Górny
2016-02-05 19:56 Michał Górny
2016-02-05 19:56 Michał Górny
2016-02-04 22:02 Michał Górny
2016-02-04 21:53 Michał Górny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox