forked from iterorganization/imas-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup.py
145 lines (116 loc) · 5.04 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# pylint: disable=wrong-import-position
# This file is part of IMASPy.
# You should have received the IMASPy LICENSE file with this project.
"""
Packaging settings. Inspired by a minimal setup.py file, the Pandas cython build
and the access-layer setup template.
The installable IMASPy package tries to follow in the following order:
- The style guide for Python code [PEP8](https://www.python.org/dev/peps/pep-0008/)
- The [PyPA guide on packaging projects](
https://packaging.python.org/guides/distributing-packages-using-setuptools/#distributing-packages)
- The [PyPA tool recommendations](
https://packaging.python.org/guides/tool-recommendations/), specifically:
* Installing: [pip](https://pip.pypa.io/en/stable/)
* Environment management: [venv](https://docs.python.org/3/library/venv.html)
* Dependency management: [pip-tools](https://github.com/jazzband/pip-tools)
* Packaging source distributions: [setuptools](https://setuptools.readthedocs.io/)
* Packaging built distributions: [wheels](https://pythonwheels.com/)
On the ITER cluster we handle the environment by using the `IMAS` module load.
So instead, we install packages to the `USER_SITE` there, and do not use
`pip`s `build-isolation`. See [IMAS-584](https://jira.iter.org/browse/IMAS-584)
"""
import importlib
import importlib.util
import site
import traceback
# Allow importing local files, see https://snarky.ca/what-the-heck-is-pyproject-toml/
import sys
import warnings
# Import other stdlib packages
from pathlib import Path
# Use setuptools to build packages. Advised to import setuptools before distutils
import setuptools
from packaging.version import Version as V
from setuptools import __version__ as setuptools_version
from setuptools import setup
from setuptools.command.build_ext import build_ext
from setuptools.command.build_py import build_py
from setuptools.command.sdist import sdist
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
# Ensure the current folder is on the import path:
sys.path.append(str(Path(__file__).parent.resolve()))
import versioneer # noqa
cannonical_python_command = "module load Python/3.8.6-GCCcore-10.2.0"
if sys.version_info < (3, 7):
sys.exit(
"Sorry, Python < 3.7 is not supported. Use a different"
f" python e.g. '{cannonical_python_command}'"
)
if sys.version_info < (3, 8):
warnings.warn("Python < 3.8 support on best-effort basis", FutureWarning)
# Check setuptools version before continuing for legacy builds
# Version 61 is required for pyproject.toml support
if V(setuptools_version) < V("61"):
raise RuntimeError(
"Setuptools version outdated. Found"
f" {V(setuptools_version)} need at least {V('61')}"
)
# Workaround for https://github.com/pypa/pip/issues/7953
# Cannot install into user site directory with editable source
site.ENABLE_USER_SITE = "--user" in sys.argv[1:]
# We need to know where we are for many things
this_file = Path(__file__)
this_dir = this_file.parent.resolve()
# Start: Load dd_helpers
dd_helpers_file = this_dir / "imaspy/dd_helpers.py"
assert dd_helpers_file.is_file()
spec = importlib.util.spec_from_file_location("dd_helpers", dd_helpers_file)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
sys.modules["imaspy.dd_helpers"] = module
from imaspy.dd_helpers import prepare_data_dictionaries # noqa
# End: Load dd_helpers
# Define building of the Data Dictionary as custom build step
class BuildDDCommand(setuptools.Command):
"""A custom command to build the data dictionaries."""
description = "build IDSDef.zip"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
"""Prepare DDs if they can be git pulled"""
prepare_data_dictionaries()
# Inject prepare_data_dictionaries() into the setuptool's build steps. So far it covers
# all installation cases:
# - `pip install -e .`` (from git clone)
# - `python -m build``
# - Source tarball from git-archive. Note: version only picked up when doing git-archive
# from a tagged release, otherwise version will be "0+unknown" (expected versioneer
# behaviour).
# `git archive HEAD -v -o imaspy.tar.gz && pip install imaspy.tar.gz`
cmd_class = {}
build_overrides = {"build_ext": build_ext, "build_py": build_py, "sdist": sdist}
if bdist_wheel:
build_overrides["bdist_wheel"] = bdist_wheel
for name, cls in build_overrides.items():
class build_DD_before(cls):
"""Build DD before executing original distutils command"""
def run(self):
try:
prepare_data_dictionaries()
except Exception:
traceback.print_exc()
print("Failed to build DD during setup, continuing without.")
super().run()
cmd_class[name] = build_DD_before
if __name__ == "__main__":
setup(
version=versioneer.get_version(),
zip_safe=False, # https://mypy.readthedocs.io/en/latest/installed_packages.html
cmdclass=versioneer.get_cmdclass({"build_DD": BuildDDCommand, **cmd_class}),
)