Skip to content

Commit 2c54bdc

Browse files
author
Matthias Koeppe
committed
pkgs/sage-conf_pypi/setup.py: Restructure like ..._conda, prepare for editable mode
1 parent 18aebf4 commit 2c54bdc

File tree

2 files changed

+86
-28
lines changed

2 files changed

+86
-28
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ build/bin/sage-build-env-config
175175
/pkgs/*/*.egg-info
176176
/pkgs/*/.tox
177177

178+
/pkgs/sage-conf_pypi/sage_root/config.log
179+
/pkgs/sage-conf_pypi/sage_root/config.status
180+
/pkgs/sage-conf_pypi/sage_root/local/
181+
/pkgs/sage-conf_pypi/sage_root/logs/
182+
/pkgs/sage-conf_pypi/sage_root/prefix
183+
/pkgs/sage-conf_pypi/sage_root/src/bin/sage-env-config
184+
/pkgs/sage-conf_pypi/sage_root/src/bin/sage-src-env-config
185+
/pkgs/sage-conf_pypi/sage_root/upstream/
186+
/pkgs/sage-conf_pypi/sage_root/venv
187+
178188
/pkgs/sagemath-objects/setup.cfg
179189
/pkgs/sagemath-bliss/setup.cfg
180190
/pkgs/sagemath-coxeter3/setup.cfg

pkgs/sage-conf_pypi/setup.py

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,35 @@
33
import shutil
44
import sysconfig
55
import platform
6+
import fnmatch
67

78
from setuptools import setup
89
from distutils.command.build_scripts import build_scripts as distutils_build_scripts
910
from setuptools.command.build_py import build_py as setuptools_build_py
10-
from setuptools.command.egg_info import egg_info as setuptools_egg_info
11-
from distutils.errors import (DistutilsSetupError, DistutilsModuleError,
12-
DistutilsOptionError)
11+
from setuptools.command.editable_wheel import editable_wheel as setuptools_editable_wheel
12+
from setuptools.errors import SetupError
13+
1314

1415
class build_py(setuptools_build_py):
1516

1617
def run(self):
17-
DOT_SAGE = os.environ.get('DOT_SAGE', os.path.join(os.environ.get('HOME'), '.sage'))
1818
HERE = os.path.dirname(__file__)
19-
with open(os.path.join(HERE, 'VERSION.txt')) as f:
20-
sage_version = f.read().strip()
19+
if self.editable_mode:
20+
SAGE_ROOT = os.path.join(HERE, 'sage_root')
21+
else:
22+
SAGE_ROOT = self._create_writable_sage_root()
23+
2124
# For convenience, set up the homebrew env automatically. This is a no-op if homebrew is not present.
22-
SETENV = '(. ./.homebrew-build-env 2> /dev/null || :)'
23-
# After #30534, SAGE_LOCAL no longer contains any Python. So we key the SAGE_ROOT only to Sage version
24-
# and architecture.
25-
system = platform.system()
26-
machine = platform.machine()
27-
arch_tag = f'{system}-{machine}'
28-
# TODO: These two should be user-configurable with options passed to "setup.py install"
29-
SAGE_ROOT = os.path.join(DOT_SAGE, f'sage-{sage_version}-{arch_tag}')
25+
if os.environ.get('CONDA_PREFIX', ''):
26+
SETENV = ':'
27+
else:
28+
SETENV = '(. ./.homebrew-build-env 2> /dev/null || :)'
29+
3030
SAGE_LOCAL = os.path.join(SAGE_ROOT, 'local')
31+
3132
if os.path.exists(os.path.join(SAGE_ROOT, 'config.status')):
32-
print(f'Reusing SAGE_ROOT={SAGE_ROOT}')
33+
print(f'Reusing configured SAGE_ROOT={SAGE_ROOT}')
3334
else:
34-
# config.status and other configure output has to be writable.
35-
# So (until the Sage distribution supports VPATH builds - #21469), we have to make a copy of sage_root.
36-
try:
37-
shutil.copytree('sage_root', SAGE_ROOT) # will fail if already exists
38-
except Exception:
39-
raise DistutilsSetupError(f"the directory SAGE_ROOT={SAGE_ROOT} already exists but it is not configured. Please remove it and try again.")
4035
cmd = f"cd {SAGE_ROOT} && {SETENV} && ./configure --prefix={SAGE_LOCAL} --with-python={sys.executable} --enable-build-as-root --enable-download-from-upstream-url --with-system-python3=force --with-sage-venv --disable-notebook --disable-sagelib --disable-sage_conf --disable-doc"
4136
print(f"Running {cmd}")
4237
sys.stdout.flush()
@@ -45,7 +40,18 @@ def run(self):
4540
sys.stdout.flush()
4641
PREREQ_SPKG = "_prereq bzip2 xz libffi" # includes python3 SPKG_DEPCHECK packages
4742
os.system(f'cd {SAGE_ROOT} && export SYSTEM=$(build/bin/sage-guess-package-system 2>/dev/null) && export PACKAGES="$(build/bin/sage-get-system-packages $SYSTEM {PREREQ_SPKG})" && [ -n "$PACKAGES" ] && echo "You can install the required build prerequisites using the following shell command" && echo "" && build/bin/sage-print-system-package-command $SYSTEM --verbose --sudo install $PACKAGES && echo ""')
48-
raise DistutilsSetupError("configure failed")
43+
raise SetupError("configure failed")
44+
45+
# Copy over files generated by the configure script
46+
# (see configure.ac AC_CONFIG_FILES)
47+
if self.editable_mode:
48+
pass # same file
49+
else:
50+
shutil.copyfile(os.path.join(SAGE_ROOT, 'pkgs', 'sage-conf', '_sage_conf', '_conf.py'),
51+
os.path.join(HERE, '_sage_conf', '_conf.py'))
52+
shutil.copyfile(os.path.join(SAGE_ROOT, 'src', 'bin', 'sage-env-config'),
53+
os.path.join(HERE, 'bin', 'sage-env-config'))
54+
4955
# Here we run "make build" -- which builds everything except for sagelib because we
5056
# used configure --disable-sagelib
5157
# Alternative:
@@ -61,13 +67,44 @@ def run(self):
6167
if os.system(cmd) != 0:
6268
raise DistutilsSetupError(f"make {TARGETS} failed")
6369

64-
# Install configuration
65-
shutil.copyfile(os.path.join(SAGE_ROOT, 'pkgs', 'sage-conf', '_sage_conf', '_conf.py'),
66-
os.path.join(HERE, '_sage_conf', '_conf.py'))
67-
shutil.copyfile(os.path.join(SAGE_ROOT, 'src', 'bin', 'sage-env-config'),
68-
os.path.join(HERE, 'bin', 'sage-env-config'))
6970
setuptools_build_py.run(self)
7071

72+
def _create_writable_sage_root(self):
73+
HERE = os.path.dirname(__file__)
74+
DOT_SAGE = os.environ.get('DOT_SAGE', os.path.join(os.environ.get('HOME'), '.sage'))
75+
with open(os.path.join(HERE, 'VERSION.txt')) as f:
76+
sage_version = f.read().strip()
77+
# After #30534, SAGE_LOCAL no longer contains any Python. So we key the SAGE_ROOT only to Sage version
78+
# and architecture.
79+
system = platform.system()
80+
machine = platform.machine()
81+
arch_tag = f'{system}-{machine}'
82+
# TODO: Should be user-configurable with config settings
83+
SAGE_ROOT = os.path.join(DOT_SAGE, f'sage-{sage_version}-{arch_tag}')
84+
85+
def ignore(path, names):
86+
# exclude all embedded src trees
87+
if fnmatch.fnmatch(path, f'*/build/pkgs/*'):
88+
return ['src']
89+
### ignore more stuff --- .tox etc.
90+
return [name for name in names
91+
if name in ('.tox', '.git', '__pycache__',
92+
'prefix', 'local', 'venv', 'upstream',
93+
'config.status', 'config.log', 'logs')]
94+
95+
if not os.path.exists(os.path.join(SAGE_ROOT, 'config.status')):
96+
# config.status and other configure output has to be writable.
97+
# So (until the Sage distribution supports VPATH builds - #21469), we have to make a copy of sage_root.
98+
try:
99+
shutil.copytree('sage_root', SAGE_ROOT,
100+
ignore=ignore) # will fail if already exists
101+
except Exception as e:
102+
raise SetupError(f"the directory SAGE_ROOT={SAGE_ROOT} already exists but it is not configured ({e}). "
103+
"Please either remove it and try again, or install in editable mode (pip install -e).")
104+
105+
return SAGE_ROOT
106+
107+
71108
class build_scripts(distutils_build_scripts):
72109

73110
def run(self):
@@ -76,6 +113,17 @@ def run(self):
76113
self.entry_points = self.distribution.entry_points = dict()
77114
distutils_build_scripts.run(self)
78115

116+
117+
class editable_wheel(setuptools_editable_wheel):
118+
r"""
119+
Customized so that exceptions raised by our build_py
120+
do not lead to the "Customization incompatible with editable install" message
121+
"""
122+
_safely_run = setuptools_editable_wheel.run_command
123+
124+
79125
setup(
80-
cmdclass=dict(build_py=build_py, build_scripts=build_scripts)
126+
cmdclass=dict(build_py=build_py,
127+
build_scripts=build_scripts,
128+
editable_wheel=editable_wheel)
81129
)

0 commit comments

Comments
 (0)