Skip to content

Commit 592fd64

Browse files
datapythonistajreback
authored andcommitted
BUILD: Simplifying contributor dependencies (#23522)
1 parent 2c982df commit 592fd64

9 files changed

+181
-110
lines changed

ci/code_checks.sh

+15-5
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@
99
# In the future we may want to add the validation of docstrings and other checks here.
1010
#
1111
# Usage:
12-
# $ ./ci/code_checks.sh # run all checks
13-
# $ ./ci/code_checks.sh lint # run linting only
14-
# $ ./ci/code_checks.sh patterns # check for patterns that should not exist
15-
# $ ./ci/code_checks.sh doctests # run doctests
12+
# $ ./ci/code_checks.sh # run all checks
13+
# $ ./ci/code_checks.sh lint # run linting only
14+
# $ ./ci/code_checks.sh patterns # check for patterns that should not exist
15+
# $ ./ci/code_checks.sh doctests # run doctests
16+
# $ ./ci/code_checks.sh dependencies # check that dependencies are consistent
1617

1718
echo "inside $0"
1819
[[ $LINT ]] || { echo "NOT Linting. To lint use: LINT=true $0 $1"; exit 0; }
19-
[[ -z "$1" || "$1" == "lint" || "$1" == "patterns" || "$1" == "doctests" ]] || { echo "Unknown command $1. Usage: $0 [lint|patterns|doctests]"; exit 9999; }
20+
[[ -z "$1" || "$1" == "lint" || "$1" == "patterns" || "$1" == "doctests" || "$1" == "dependencies" ]] \
21+
|| { echo "Unknown command $1. Usage: $0 [lint|patterns|doctests|dependencies]"; exit 9999; }
2022

2123
source activate pandas
24+
BASE_DIR="$(dirname $0)/.."
2225
RET=0
2326
CHECK=$1
2427

@@ -172,4 +175,11 @@ if [[ -z "$CHECK" || "$CHECK" == "doctests" ]]; then
172175

173176
fi
174177

178+
### DEPENDENCIES ###
179+
if [[ -z "$CHECK" || "$CHECK" == "dependencies" ]]; then
180+
MSG='Check that requirements-dev.txt has been generated from environment.yml' ; echo $MSG
181+
$BASE_DIR/scripts/generate_pip_deps_from_conda.py --compare
182+
RET=$(($RET + $?)) ; echo $MSG "DONE"
183+
fi
184+
175185
exit $RET

ci/environment-dev.yaml

-20
This file was deleted.

ci/requirements-optional-conda.txt

-28
This file was deleted.

ci/requirements_dev.txt

-16
This file was deleted.

doc/source/contributing.rst

+3-8
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ We'll now kick off a three-step process:
170170
.. code-block:: none
171171
172172
# Create and activate the build environment
173-
conda env create -f ci/environment-dev.yaml
173+
conda env create -f environment.yml
174174
conda activate pandas-dev
175175
176176
# or with older versions of Anaconda:
@@ -180,9 +180,6 @@ We'll now kick off a three-step process:
180180
python setup.py build_ext --inplace -j 4
181181
python -m pip install -e .
182182
183-
# Install the rest of the optional dependencies
184-
conda install -c defaults -c conda-forge --file=ci/requirements-optional-conda.txt
185-
186183
At this point you should be able to import pandas from your locally built version::
187184

188185
$ python # start an interpreter
@@ -221,14 +218,12 @@ You'll need to have at least python3.5 installed on your system.
221218
. ~/virtualenvs/pandas-dev/bin/activate
222219
223220
# Install the build dependencies
224-
python -m pip install -r ci/requirements_dev.txt
221+
python -m pip install -r requirements-dev.txt
222+
225223
# Build and install pandas
226224
python setup.py build_ext --inplace -j 4
227225
python -m pip install -e .
228226
229-
# Install additional dependencies
230-
python -m pip install -r ci/requirements-optional-pip.txt
231-
232227
Creating a branch
233228
-----------------
234229

environment.yml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: pandas-dev
2+
channels:
3+
- defaults
4+
- conda-forge
5+
dependencies:
6+
# required
7+
- NumPy
8+
- python=3
9+
- python-dateutil>=2.5.0
10+
- pytz
11+
12+
# development
13+
- Cython>=0.28.2
14+
- flake8
15+
- flake8-comprehensions
16+
- flake8-rst
17+
- hypothesis>=3.58.0
18+
- isort
19+
- moto
20+
- pytest>=3.6
21+
- setuptools>=24.2.0
22+
- sphinx
23+
- sphinxcontrib-spelling
24+
25+
# optional
26+
- beautifulsoup4>=4.2.1
27+
- blosc
28+
- bottleneck>=1.2.0
29+
- fastparquet>=0.1.2
30+
- gcsfs
31+
- html5lib
32+
- ipython>=5.6.0
33+
- ipykernel
34+
- jinja2
35+
- lxml
36+
- matplotlib>=2.0.0
37+
- nbsphinx
38+
- numexpr>=2.6.1
39+
- openpyxl
40+
- pyarrow>=0.7.0
41+
- pymysql
42+
- pytables>=3.4.2
43+
- pytest-cov
44+
- pytest-xdist
45+
- s3fs
46+
- scipy>=0.18.1
47+
- seaborn
48+
- sqlalchemy
49+
- statsmodels
50+
- xarray
51+
- xlrd
52+
- xlsxwriter
53+
- xlwt

ci/requirements-optional-pip.txt renamed to requirements-dev.txt

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
1-
# This file was autogenerated by scripts/convert_deps.py
2-
# Do not modify directly
1+
NumPy
2+
python-dateutil>=2.5.0
3+
pytz
4+
Cython>=0.28.2
5+
flake8
6+
flake8-comprehensions
7+
flake8-rst
8+
hypothesis>=3.58.0
9+
isort
10+
moto
11+
pytest>=3.6
12+
setuptools>=24.2.0
13+
sphinx
14+
sphinxcontrib-spelling
315
beautifulsoup4>=4.2.1
416
blosc
517
bottleneck>=1.2.0

scripts/convert_deps.py

-31
This file was deleted.
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env python
2+
"""
3+
Convert the conda environment.yml to the pip requirements-dev.txt,
4+
or check that they have the same packages (for the CI)
5+
6+
Usage:
7+
8+
Generate `requirements-dev.txt`
9+
$ ./conda_to_pip
10+
11+
Compare and fail (exit status != 0) if `requirements-dev.txt` has not been
12+
generated with this script:
13+
$ ./conda_to_pip --compare
14+
"""
15+
import argparse
16+
import os
17+
import re
18+
import sys
19+
import yaml
20+
21+
22+
EXCLUDE = {'python=3'}
23+
RENAME = {'pytables': 'tables'}
24+
25+
26+
def conda_package_to_pip(package):
27+
"""
28+
Convert a conda package to its pip equivalent.
29+
30+
In most cases they are the same, those are the exceptions:
31+
- Packages that should be excluded (in `EXCLUDE`)
32+
- Packages that should be renamed (in `RENAME`)
33+
- A package requiring a specific version, in conda is defined with a single
34+
equal (e.g. ``pandas=1.0``) and in pip with two (e.g. ``pandas==1.0``)
35+
"""
36+
if package in EXCLUDE:
37+
return
38+
39+
if package in RENAME:
40+
return RENAME[package]
41+
42+
return re.sub('(?<=[^<>])=', '==', package).strip()
43+
44+
45+
def main(conda_fname, pip_fname, compare=False):
46+
"""
47+
Generate the pip dependencies file from the conda file, or compare that
48+
they are synchronized (``compare=True``).
49+
50+
Parameters
51+
----------
52+
conda_fname : str
53+
Path to the conda file with dependencies (e.g. `environment.yml`).
54+
pip_fname : str
55+
Path to the pip file with dependencies (e.g. `requirements-dev.txt`).
56+
compare : bool, default False
57+
Whether to generate the pip file (``False``) or to compare if the
58+
pip file has been generated with this script and the last version
59+
of the conda file (``True``).
60+
61+
Returns
62+
-------
63+
bool
64+
True if the comparison fails, False otherwise
65+
"""
66+
with open(conda_fname) as conda_fd:
67+
deps = yaml.safe_load(conda_fd)['dependencies']
68+
69+
pip_content = '\n'.join(filter(None, map(conda_package_to_pip, deps)))
70+
71+
if compare:
72+
with open(pip_fname) as pip_fd:
73+
return pip_content != pip_fd.read()
74+
else:
75+
with open(pip_fname, 'w') as pip_fd:
76+
pip_fd.write(pip_content)
77+
return False
78+
79+
80+
if __name__ == '__main__':
81+
argparser = argparse.ArgumentParser(
82+
description='convert (or compare) conda file to pip')
83+
argparser.add_argument('--compare',
84+
action='store_true',
85+
help='compare whether the two files are equivalent')
86+
args = argparser.parse_args()
87+
88+
repo_path = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
89+
res = main(os.path.join(repo_path, 'environment.yml'),
90+
os.path.join(repo_path, 'requirements-dev.txt'),
91+
compare=args.compare)
92+
if res:
93+
sys.stderr.write('`requirements-dev.txt` has to be generated with '
94+
'`{}` after `environment.yml` is modified.\n'.format(
95+
sys.argv[0]))
96+
sys.exit(res)

0 commit comments

Comments
 (0)