-
-
Notifications
You must be signed in to change notification settings - Fork 684
check ipython for sphinxext, extend python_package_check macro #36848
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
Can this not just be taken care of by setting a lower version bound? |
|
No, I don't think so. E.g. if a distro doesn't package sphinx in the usual way, or doesn't package it at all, it's not clear why they'd put sphinxext in ipython. |
That would be highly unusual, so I think more investigation is needed. Note that ALL of Python distribution compatibility is done on the basis of version constraints. |
Fedora splits ipython into a number of parts, see https://packages.fedoraproject.org/pkgs/ipython/ As we have no control on how much of these is installed, we need a check, and the check in this PR is a generic one (maybe other distros do this, or will do this...) |
e81623a to
b755e58
Compare
|
I'd say this is a distribution bug. Do you happen to know if this has been discussed with upstream? |
I have no idea, but I don't think you'd have much luck convincing them to merge these packages. |
|
Documentation preview for this PR (built with commit b755e58; changes) is ready! 🎉 |
|
This has come up three or four times now, where we need the ability to run some python code in the interpreter that sage will use, and perform different actions based on the result. For example:
I think now is a good time to refactor the python package check into a free-form if/else check. I whipped up a quick proof-of-concept of a new macro, m4/sage_python_run_ifelse.m4#
# SYNOPSIS
#
# SAGE_PYTHON_RUN_IFELSE(code, [action-if-true], [action-if-false])
#
# DESCRIPTION
#
# Attempt to run the given input using the python that will be used
# for Sage. The PYTHONUSERBASE variable poisoned in the same manner
# as sage-env poisons it, to ensure that the configure- and run-time
# views of the system are as similar as possible.
#
# The SAGE_SPKG_CONFIGURE_PYTHON3() macro is AC_REQUIRE'd to ensure
# that $PYTHON_FOR_VENV is available (if we can use the system
# python). If it is, the check is run inside a new venv; if not, we
# execute the code directly under "python3".
#
# INPUT
#
# * code - the python code to run
#
# * action-if-true - list of commands to execute if the python
# interpreter exits successfully (with exit code zero)
#
# * action-if-false - list of commands to execute if the python
# interpreter exits unsuccessfully (with a non-zero exit code)
#
AC_DEFUN([SAGE_PYTHON_RUN_IFELSE], [
# Create conftest.py containing the user's code
cat >conftest.py <<SAGE__EOF
$1
SAGE__EOF
# We need to know if we're using the system python or not.
AC_REQUIRE([SAGE_SPKG_CONFIGURE_PYTHON3])
# To prevent user-site (pip install --user) packages from affecting
# the result, we poison PYTHONUSERBASE. The sage-env script also
# does this at runtime; we mimic that implementation to ensure that
# the behaviors at configure- and run-time are identical. Beware
# that (as in sage-env) the poisoning is skipped if PYTHONUSERBASE
# is non-empty. In particular, if the user points PYTHONUSERBASE to
# any path (even the default), then his local pip packages will be
# detected.
PYTHONUSERBASE_SAVED="${PYTHONUSERBASE}"
AS_IF([test -z "${PYTHONUSERBASE}"], [
PYTHONUSERBASE="${HOME}/.sage/local"
])
# Are we using the system python or not? The PYTHON_FOR_VENV
# variable is only set if we're using the system python.
AS_IF([test "x$sage_spkg_install_python3" = "xno"],[
# We run this check inside a python venv, because that's
# ultimately how the system $PYTHON_FOR_VENV will be used. We use
# --clear because ./configure typically clobbers its output files.
# And we pass --system-site-packages to the venv if it was enabled
# via ./configure --enable-system-site-packages.
AS_IF([test "${enable_system_site_packages}" = "yes"], [
_SSP="--system-site-packages"
])
AS_IF(["${PYTHON_FOR_VENV}" build/bin/sage-venv dnl
${_SSP} dnl
--clear dnl
config.venv dnl
2>&AS_MESSAGE_LOG_FD], [
AS_IF([PYTHONUSERBASE="${PYTHONUSERBASE}" dnl
config.venv/bin/python3 dnl
conftest.py dnl
1>&AS_MESSAGE_LOG_FD dnl
2>&AS_MESSAGE_LOG_FD],[$2],[$3])
], [
# Failed to create a venv for some reason?
$3
])
# Clean up config.venv, but only if we could have created it.
# (The --clear flag to pyvenv will not clobber a plain file.)
AS_IF([test -d config.venv], [rm -rf config.venv])
],[
# Not the system python, just run the thing.
AS_IF([PYTHONUSERBASE="${PYTHONUSERBASE}" dnl
python3 dnl
conftest.py dnl
1>&AS_MESSAGE_LOG_FD dnl
2>&AS_MESSAGE_LOG_FD],[$2],[$3])
])
# Un-clobber PYTHONUSERBASE and clean up conftest.py before leaving.
PYTHONUSERBASE="${PYTHONUSERBASE_SAVED}"
rm -f conftest.py
])m4/sage_python_package_check.m4#
# SYNOPSIS
#
# SAGE_PYTHON_PACKAGE_CHECK(package)
#
# DESCRIPTION
#
# Determine if the system copy of a python package can be used by sage.
#
# This macro uses setuptools.version's pkg_resources to check that the
# "install-requires.txt" file for the named package is satisfied, and
# it can typically fail in five ways:
#
# 1. If --enable-system-site-packages was not passed to ./configure,
#
# 2. If we are not using the system python,
#
# 3. If we are unable to create a venv with the system python,
#
# 4. If setuptools is not available to the system python,
#
# 5. If the contents of install-requires.txt are not met (wrong
# version, no version, etc.) by the system python.
#
# (The third item takes place in the SAGE_PYTHON_RUN_IFELSE macro.)
#
# In any of those cases, we set sage_spkg_install_$package to "yes"
# so that the corresponding SPKG is installed. Otherwise, we do
# nothing, since the default value of sage_spkg_install_$package
# is "no" (to use the system copy).
#
# To avoid suggesting these system packages to users who have not
# set --enable-system-site-packages, this macro also changes the
# default for --with-system-foo from "yes" to "no" in that case.
#
AC_DEFUN([SAGE_PYTHON_PACKAGE_CHECK], [
AC_MSG_CHECKING([if --enable-system-site-packages was used])
AS_IF([test "${enable_system_site_packages}" = "yes"], [
AC_MSG_RESULT(yes)
AC_REQUIRE([SAGE_SPKG_CONFIGURE_PYTHON3])
AC_MSG_CHECKING([if we're using the system python])
AS_IF([test "x$sage_spkg_install_python3" = "xno"],[
AC_MSG_RESULT([yes])
SAGE_PKG_VERSPEC=$(sed '/^#/d' "./build/pkgs/$1/install-requires.txt")
AC_MSG_CHECKING([for python package $1 ("${SAGE_PKG_VERSPEC}")])
SAGE_PYTHON_RUN_IFELSE([
import pkg_resources
pkg_resources.require('${SAGE_PKG_VERSPEC}'.splitlines())
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
sage_spkg_install_$1=yes
])
], [
dnl Not using the system python
AC_MSG_RESULT([no])
sage_spkg_install_$1=yes
])
], [
dnl System site packages are disabled.
AC_MSG_RESULT(no; skipping check)
sage_spkg_install_$1=yes
dnl We have to retroactively hack the --with-system-foo={no,yes,force}
dnl mechanism here because it wasn't designed with the ability to
dnl disable arbitrary chunks of system packages in mind. The easy cases
dnl are "no" and "force" which require no action; "no" means we won't
dnl suggest the package anyway, and "force" will raise an error when
dnl the system-package check fails.
dnl
dnl The default of "yes" is more troubling because it is the default. To
dnl avoid prompting users to install packages that won't be used, we want
dnl to ignore "yes" when reporting the "hint: install these packages..."
dnl at the end of ./configure. To accomplish that, we change "yes" to
dnl "no" here, essentially changing the default for packages using this
dnl macro when --enable-system-site-packages is disabled. Packages with
dnl "no" are not suggested to the user.
AS_IF([test "${sage_use_system_$1}" = "yes"],[sage_use_system_$1=no])
])
]) |
|
can we please have optional args in SAGE_PYTHON_PACKAGE_CHECK ? instead of |
|
The default is # default is no
SAGE_PYTHON_PACKAGE_CHECK(foo)
# maybe it's yes
SAGE_PYTHON_RUN_IFELSE(..., [do nothing], [set it to yes])
# it's "no" only if both tests succeededThe second test is wasteful but it's only slow because of the venv creation. Matthias brought that up once before. I chose to create/destroy the venv each time because the autoconf macros are typically wasteful (i.e. self-contained) like that, but I don't really care about it. (I doubt we need a venv at all when we're allowed to use system packages.) |
I forgot to say: I'm not opposed to this, just wondering if it's necessary. |
the 2nd test is not needed at all if the 1st one gives yes. How do you check that the 2nd one does not flip the state back to no? I don't understand the preference for these hidden states being passed around. It's a recipe for bugs. |
You can never be sure, but I was hoping that the implementation of "do nothing" does not alter variables.
I agree in principle, but the hidden state is already there. The current behavior of The reason I set the variable in the macro in the first place is because it worked for 100+ packages and made the spkg-configure scripts a bit shorter. Now we're probably closer to 200 python packages, and we have one outlier. I'd say it's OK to write the |
with system-wide
ipython, it sometimes happens (e.g. with Fedora's 38ipython8.9) thatit does not have
sphinxext.We provide a check here, by extending the
sage_python_package_checkmacro to allow for extra check,and doing the corresponding check