Skip to content

Commit 7304396

Browse files
authored
BLD: Setup meson builds (#49115)
1 parent 574f241 commit 7304396

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+603
-115
lines changed

.circleci/setup_env.sh

+1-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ if pip list | grep -q ^pandas; then
5454
pip uninstall -y pandas || true
5555
fi
5656

57-
echo "Build extensions"
58-
python setup.py build_ext -q -j4
59-
6057
echo "Install pandas"
61-
python -m pip install --no-build-isolation --no-use-pep517 -e .
58+
python -m pip install --no-build-isolation -ve .
6259

6360
echo "done"

.github/actions/build_pandas/action.yml

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: Build pandas
22
description: Rebuilds the C extensions and installs pandas
3+
inputs:
4+
editable:
5+
description: Whether to build pandas in editable mode (default true)
6+
default: true
37
runs:
48
using: composite
59
steps:
@@ -12,9 +16,9 @@ runs:
1216

1317
- name: Build Pandas
1418
run: |
15-
python setup.py build_ext -j $N_JOBS
16-
python -m pip install -e . --no-build-isolation --no-use-pep517 --no-index
19+
if [[ ${{ inputs.editable }} == "true" ]]; then
20+
pip install -e . --no-build-isolation -v
21+
else
22+
pip install . --no-build-isolation -v
23+
fi
1724
shell: bash -el {0}
18-
env:
19-
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
20-
N_JOBS: ${{ runner.os == 'macOS' && 3 || 2 }}

.github/workflows/code-checks.yml

+16-4
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,24 @@ jobs:
6363
- name: Build Pandas
6464
id: build
6565
uses: ./.github/actions/build_pandas
66+
with:
67+
editable: false
6668

6769
# The following checks are independent of each other and should still be run if one fails
70+
71+
# TODO: The doctests have to be run first right now, since the Cython doctests only work
72+
# with pandas installed in non-editable mode
73+
# This can be removed once pytest-cython doesn't require C extensions to be installed inplace
74+
- name: Run doctests
75+
run: cd ci && ./code_checks.sh doctests
76+
if: ${{ steps.build.outcome == 'success' && always() }}
77+
78+
- name: Install pandas in editable mode
79+
id: build-editable
80+
uses: ./.github/actions/build_pandas
81+
with:
82+
editable: true
83+
6884
- name: Check for no warnings when building single-page docs
6985
run: ci/code_checks.sh single-docs
7086
if: ${{ steps.build.outcome == 'success' && always() }}
@@ -73,10 +89,6 @@ jobs:
7389
run: ci/code_checks.sh code
7490
if: ${{ steps.build.outcome == 'success' && always() }}
7591

76-
- name: Run doctests
77-
run: ci/code_checks.sh doctests
78-
if: ${{ steps.build.outcome == 'success' && always() }}
79-
8092
- name: Run docstring validation
8193
run: ci/code_checks.sh docstrings
8294
if: ${{ steps.build.outcome == 'success' && always() }}

.github/workflows/package-checks.yml

+3-6
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,10 @@ jobs:
4444
with:
4545
python-version: '3.10'
4646

47-
- name: Install required dependencies
48-
run: |
49-
python -m pip install --upgrade pip setuptools wheel python-dateutil pytz numpy cython
50-
python -m pip install versioneer[toml]
51-
5247
- name: Pip install with extra
53-
run: python -m pip install -e .[${{ matrix.extra }}] --no-build-isolation
48+
run: |
49+
python -m pip install .[${{ matrix.extra }}] -v
50+
shell: bash -el {0}
5451
conda_forge_recipe:
5552
if: ${{ github.event.label.name == 'Build' || contains(github.event.pull_request.labels.*.name, 'Build') || github.event_name == 'push'}}
5653
runs-on: ubuntu-22.04

.github/workflows/unit-tests.yml

+5-8
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,9 @@ jobs:
229229
run: |
230230
/opt/python/cp39-cp39/bin/python -m venv ~/virtualenvs/pandas-dev
231231
. ~/virtualenvs/pandas-dev/bin/activate
232-
python -m pip install --no-cache-dir --no-deps -U pip wheel setuptools
232+
python -m pip install -U pip wheel setuptools meson[ninja]==1.0.1 meson-python==0.13.1
233233
python -m pip install --no-cache-dir versioneer[toml] cython numpy python-dateutil pytz pytest>=7.0.0 pytest-xdist>=2.2.0 pytest-asyncio>=0.17 hypothesis>=6.46.1
234-
python setup.py build_ext -q -j$(nproc)
235-
python -m pip install --no-cache-dir --no-build-isolation --no-use-pep517 -e .
234+
python -m pip install --no-cache-dir --no-build-isolation -e .
236235
python -m pip list
237236
export PANDAS_CI=1
238237
python -m pytest -m 'not slow and not network and not clipboard and not single_cpu' pandas --junitxml=test-data.xml
@@ -268,10 +267,9 @@ jobs:
268267
run: |
269268
/opt/python/cp39-cp39/bin/python -m venv ~/virtualenvs/pandas-dev
270269
. ~/virtualenvs/pandas-dev/bin/activate
271-
python -m pip install --no-cache-dir --no-deps -U pip wheel setuptools
270+
python -m pip install -U pip wheel setuptools meson-python==0.13.1 meson[ninja]==1.0.1
272271
python -m pip install --no-cache-dir versioneer[toml] cython numpy python-dateutil pytz pytest>=7.0.0 pytest-xdist>=2.2.0 pytest-asyncio>=0.17 hypothesis>=6.46.1
273-
python setup.py build_ext -q -j$(nproc)
274-
python -m pip install --no-cache-dir --no-build-isolation --no-use-pep517 -e .
272+
python -m pip install --no-cache-dir --no-build-isolation -e .
275273
python -m pip list --no-cache-dir
276274
277275
- name: Run Tests
@@ -347,8 +345,7 @@ jobs:
347345
348346
- name: Build Pandas
349347
run: |
350-
python setup.py build_ext -q -j4
351-
python -m pip install -e . --no-build-isolation --no-use-pep517 --no-index
348+
python -m pip install -e . --no-build-isolation --no-index
352349
353350
- name: Build Version
354351
run: |

.github/workflows/wheels.yml

-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ jobs:
5656
- [ubuntu-20.04, manylinux_x86_64]
5757
- [macos-11, macosx_*]
5858
- [windows-2019, win_amd64]
59-
- [windows-2019, win32]
6059
# TODO: support PyPy?
6160
python: [["cp39", "3.9"], ["cp310", "3.10"], ["cp311", "3.11"]]# "pp39"]
6261
env:

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
*.py[ocd]
3737
*.so
3838
.build_cache_dir
39+
.mesonpy-native-file.ini
3940
MANIFEST
4041

4142
# Python files #
@@ -76,6 +77,8 @@ coverage_html_report
7677
__pycache__
7778
# pytest-monkeytype
7879
monkeytype.sqlite3
80+
# meson editable install folder
81+
.mesonpy
7982

8083

8184
# OS generated files #

asv_bench/asv.conf.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
// pip (with all the conda available packages installed first,
4242
// followed by the pip installed packages).
4343
"matrix": {
44-
"numpy": [],
4544
"Cython": ["0.29.33"],
4645
"matplotlib": [],
4746
"sqlalchemy": [],
@@ -56,6 +55,9 @@
5655
"xlrd": [],
5756
"odfpy": [],
5857
"jinja2": [],
58+
"meson": [],
59+
"meson-python": [],
60+
"python-build": [],
5961
},
6062
"conda_channels": ["conda-forge"],
6163
// Combinations of libraries/python versions can be excluded/included
@@ -125,7 +127,5 @@
125127
"regression_thresholds": {
126128
},
127129
"build_command":
128-
["python -m pip install versioneer[toml]",
129-
"python setup.py build -j4",
130-
"PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}"],
130+
["python -m build -Cbuilddir=builddir --wheel --outdir {build_cache_dir} {build_dir}"]
131131
}

ci/code_checks.sh

+2-7
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,8 @@ fi
6565
### DOCTESTS ###
6666
if [[ -z "$CHECK" || "$CHECK" == "doctests" ]]; then
6767

68-
MSG='Doctests' ; echo $MSG
69-
# Ignore test_*.py files or else the unit tests will run
70-
python -m pytest --doctest-modules --ignore-glob="**/test_*.py" pandas
71-
RET=$(($RET + $?)) ; echo $MSG "DONE"
72-
73-
MSG='Cython Doctests' ; echo $MSG
74-
python -m pytest --doctest-cython pandas/_libs
68+
MSG='Python and Cython Doctests' ; echo $MSG
69+
python -c 'import pandas as pd; pd.test(run_doctests=True)'
7570
RET=$(($RET + $?)) ; echo $MSG "DONE"
7671

7772
fi

ci/deps/actions-310-numpydev.yaml

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ dependencies:
66

77
# build dependencies
88
- versioneer[toml]
9+
- meson[ninja]=1.0.1
10+
- meson-python=0.13.1
911

1012
# test dependencies
1113
- pytest>=7.0.0
1214
- pytest-cov
13-
- pytest-xdist>=2.2.0
15+
# Once pytest-cov > 4 comes out, unpin this
16+
# Right now, a DeprecationWarning related to rsyncdir
17+
# causes an InternalError within pytest
18+
- pytest-xdist>=2.2.0, <3
1419
- hypothesis>=6.46.1
1520
- pytest-asyncio>=0.17.0
1621

ci/deps/actions-310.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ dependencies:
77
# build dependencies
88
- versioneer[toml]
99
- cython>=0.29.33
10+
- meson[ninja]=1.0.1
11+
- meson-python=0.13.1
1012

1113
# test dependencies
1214
- pytest>=7.0.0

ci/deps/actions-311-pyarrownightly.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ dependencies:
66

77
# build dependencies
88
- versioneer[toml]
9+
- meson[ninja]=1.0.1
910
- cython>=0.29.33
11+
- meson-python=0.13.1
1012

1113
# test dependencies
1214
- pytest>=7.0.0

ci/deps/actions-311.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ dependencies:
77
# build dependencies
88
- versioneer[toml]
99
- cython>=0.29.33
10+
- meson[ninja]=1.0.1
11+
- meson-python=0.13.1
1012

1113
# test dependencies
1214
- pytest>=7.0.0

ci/deps/actions-39-downstream_compat.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ dependencies:
88
# build dependencies
99
- versioneer[toml]
1010
- cython>=0.29.33
11+
- meson[ninja]=1.0.1
12+
- meson-python=0.13.1
1113

1214
# test dependencies
1315
- pytest>=7.0.0
@@ -69,7 +71,6 @@ dependencies:
6971
- pandas-datareader
7072
- pyyaml
7173
- py
72-
7374
- pip:
7475
- pyqt5>=5.15.6
7576
- tzdata>=2022.1

ci/deps/actions-39-minimum_versions.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ dependencies:
99
# build dependencies
1010
- versioneer[toml]
1111
- cython>=0.29.33
12+
- meson[ninja]=1.0.1
13+
- meson-python=0.13.1
1214

1315
# test dependencies
1416
- pytest>=7.0.0

ci/deps/actions-39.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ dependencies:
77
# build dependencies
88
- versioneer[toml]
99
- cython>=0.29.33
10+
- meson[ninja]=1.0.1
11+
- meson-python=0.13.1
1012

1113
# test dependencies
1214
- pytest>=7.0.0

ci/deps/actions-pypy-39.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ dependencies:
1010
# build dependencies
1111
- versioneer[toml]
1212
- cython>=0.29.33
13+
- meson[ninja]=1.0.1
14+
- meson-python=0.13.1
1315

1416
# test dependencies
1517
- pytest>=7.0.0
@@ -22,6 +24,5 @@ dependencies:
2224
- numpy
2325
- python-dateutil
2426
- pytz
25-
2627
- pip:
2728
- tzdata>=2022.1

ci/deps/circle-39-arm64.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ dependencies:
77
# build dependencies
88
- versioneer[toml]
99
- cython>=0.29.33
10+
- meson[ninja]=1.0.1
11+
- meson-python=0.13.1
1012

1113
# test dependencies
1214
- pytest>=7.0.0

ci/run_tests.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ if [[ "not network" == *"$PATTERN"* ]]; then
1212
export http_proxy=http://1.2.3.4 https_proxy=http://1.2.3.4;
1313
fi
1414

15-
COVERAGE="-s --cov=pandas --cov-report=xml --cov-append"
15+
COVERAGE="-s --cov=pandas --cov-report=xml --cov-append --cov-config=pyproject.toml"
1616

1717
# If no X server is found, we use xvfb to emulate it
1818
if [[ $(uname) == "Linux" && -z $DISPLAY ]]; then
1919
export DISPLAY=":0"
2020
XVFB="xvfb-run "
2121
fi
2222

23-
PYTEST_CMD="${XVFB}pytest -r fEs -n $PYTEST_WORKERS --dist=loadfile $TEST_ARGS $COVERAGE $PYTEST_TARGET"
23+
PYTEST_CMD="MESONPY_EDITABLE_VERBOSE=1 ${XVFB}pytest -r fEs -n $PYTEST_WORKERS --dist=loadfile $TEST_ARGS $COVERAGE $PYTEST_TARGET"
2424

2525
if [[ "$PATTERN" ]]; then
2626
PYTEST_CMD="$PYTEST_CMD -m \"$PATTERN\""

doc/source/development/contributing_environment.rst

+58-7
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,47 @@ for :ref:`building pandas with GitPod <contributing-gitpod>`.
207207
Step 3: build and install pandas
208208
--------------------------------
209209

210-
You can now run::
210+
There are currently two supported ways of building pandas, pip/meson and setuptools(setup.py).
211+
Historically, pandas has only supported using setuptools to build pandas. However, this method
212+
requires a lot of convoluted code in setup.py and also has many issues in compiling pandas in parallel
213+
due to limitations in setuptools.
214+
215+
The newer build system, invokes the meson backend through pip (via a `PEP 517 <https://peps.python.org/pep-0517/>`_ build).
216+
It automatically uses all available cores on your CPU, and also avoids the need for manual rebuilds by
217+
rebuilding automatically whenever pandas is imported(with an editable install).
218+
219+
For these reasons, you should compile pandas with meson.
220+
Because the meson build system is newer, you may find bugs/minor issues as it matures. You can report these bugs
221+
`here <https://github.com/pandas-dev/pandas/issues/49683>`_.
222+
223+
To compile pandas with meson, run::
211224

212225
# Build and install pandas
213-
# The number after -j is the number of compiling jobs run in parallel
214-
# Change it according to your machine's hardware spec
215-
python setup.py build_ext -j 4
216-
python -m pip install -e . --no-build-isolation --no-use-pep517
226+
python -m pip install -ve . --no-build-isolation
227+
228+
** Build options **
229+
230+
It is possible to pass options from the pip frontend to the meson backend if you would like to configure your
231+
install. Occasionally, you'll want to use this to adjust the build directory, and/or toggle debug/optimization levels.
232+
233+
You can pass a build directory to pandas by appending ``--config-settings builddir="your builddir here"`` to your pip command.
234+
This option allows you to configure where meson stores your built C extensions, and allows for fast rebuilds.
235+
236+
Sometimes, it might be useful to compile pandas with debugging symbols, when debugging C extensions.
237+
Appending ``--config-settings setup-args="-Ddebug=true"`` will do the trick.
238+
239+
With pip, it is possible to chain together multiple config settings (for example specifying both a build directory
240+
and building with debug symbols would look like
241+
``--config-settings builddir="your builddir here" --config-settings=setup-args="-Dbuildtype=debug"``.
242+
243+
**Compiling pandas with setup.py**
244+
245+
.. note::
246+
This method of compiling pandas will be deprecated and removed very soon, as the meson backend matures.
247+
248+
To compile pandas with setuptools, run::
249+
250+
python setup.py develop
217251

218252
.. note::
219253
You will need to repeat this step each time the C extensions change, for example
@@ -226,5 +260,22 @@ At this point you should be able to import pandas from your locally built versio
226260
>>> print(pandas.__version__) # note: the exact output may differ
227261
2.0.0.dev0+880.g2b9e661fbb.dirty
228262

229-
This will create the new environment, and not touch any of your existing environments,
230-
nor any existing Python installation.
263+
When building pandas with meson, importing pandas will automatically trigger a rebuild, even when C/Cython files are modified.
264+
By default, no output will be produced by this rebuild (the import will just take longer). If you would like to see meson's
265+
output when importing pandas, you can set the environment variable ``MESONPY_EDTIABLE_VERBOSE``. For example, this would be::
266+
267+
# On Linux/macOS
268+
MESONPY_EDITABLE_VERBOSE=1 python
269+
270+
# Windows
271+
set MESONPY_EDITABLE_VERBOSE=1 # Only need to set this once per session
272+
python
273+
274+
If you would like to see this verbose output every time, you can set the ``editable-verbose`` config setting to ``true`` like so::
275+
276+
python -m pip install -ve . --config-settings editable-verbose=true
277+
278+
.. tip::
279+
If you ever find yourself wondering whether setuptools or meson was used to build your pandas,
280+
you can check the value of ``pandas._built_with_meson``, which will be true if meson was used
281+
to compile pandas.

0 commit comments

Comments
 (0)