diff --git a/.circleci/config.yml b/.circleci/config.yml index c0557b6a..27b3d70e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -91,12 +91,23 @@ jobs: - run: name: Build the distribution tarball. - command: python setup.py sdist + command: | + python setup.py sdist + python setup.py check + python -m twine check dist/*.tar.gz --strict + rm dist/* + python -m build - run: name: Install from the distribution tarball command: | - python -m venv venv - source venv/bin/activate - pip install --upgrade setuptools pip - pip install dist/*.tar.gz + python -m venv venv + source venv/bin/activate + pip install dist/*.tar.gz + python -c 'import tsinfer; print(tsinfer.__version__)' + + #Also check the wheel + pip uninstall --yes tsinfer + pip install dist/*.whl + python -c 'import tsinfer; print(tsinfer.__version__)' + diff --git a/.github/workflows/docker/buildwheel.sh b/.github/workflows/docker/buildwheel.sh index da98ada8..9898a802 100644 --- a/.github/workflows/docker/buildwheel.sh +++ b/.github/workflows/docker/buildwheel.sh @@ -6,7 +6,6 @@ set -e -x ARCH=`uname -p` echo "arch=$ARCH" -#yum -y install gsl-devel #For msprime # We're running as root in the docker container so git commands issued by # setuptools_scm will fail without this: @@ -14,13 +13,16 @@ git config --global --add safe.directory /project # Fetch the full history as we'll be missing tags otherwise. git fetch --unshallow for V in "${PYTHON_VERSIONS[@]}"; do + git reset --hard + git clean -fd PYBIN=/opt/python/$V/bin rm -rf build/ # Avoid lib build by narrow Python is used by wide python # Instead of letting setup.py install a newer numpy we install it here # using the oldest supported version for ABI compatibility - $PYBIN/pip install oldest-supported-numpy - SETUPTOOLS_SCM_DEBUG=1 $PYBIN/python setup.py build_ext --inplace - SETUPTOOLS_SCM_DEBUG=1 $PYBIN/python setup.py bdist_wheel + $PYBIN/python -m venv env + source env/bin/activate + $PYBIN/python -m pip install --upgrade build + SETUPTOOLS_SCM_DEBUG=1 $PYBIN/python -m build done cd dist diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 11e5fb36..994bae9d 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -27,22 +27,12 @@ jobs: python-version: ${{ matrix.python }} - name: Install deps run: | - # Upgrade pip to get bdist_wheel - pip install --upgrade pip - pip install setuptools wheel - # Instead of letting setup.py install a newer numpy we install it here - # using the oldest supported version for ABI compatibility - pip install oldest-supported-numpy - - name: Build C extension - run: | - python -VV - python setup.py build_ext --inplace + pip install --upgrade pip build delocate - name: Build Wheel run: | - python setup.py bdist_wheel + python -m build --wheel - name: Delocate to bundle dynamic libs run: | - pip install delocate delocate-wheel -v dist/*.whl - name: Upload Wheels uses: actions/upload-artifact@v3 @@ -67,27 +57,14 @@ jobs: shell: bash run: | set -ex - ${PYTHON} -m pip install --upgrade pip - ${PYTHON} -m pip install setuptools wheel - # Instead of letting setup.py install a newer numpy we install it here - # using the oldest supported version for ABI compatibility - ${PYTHON} -m pip install oldest-supported-numpy - - name: Build C Extension - env: - PYTHON: "py -${{ matrix.python }}-${{ matrix.wordsize }}" - shell: bash - run: | - set -ex - git reset --hard - ${PYTHON} -VV - ${PYTHON} setup.py build_ext --inplace + ${PYTHON} -m pip install --upgrade pip build - name: Build Wheel env: PYTHON: "py -${{ matrix.python }}-${{ matrix.wordsize }}" shell: bash run: | set -ex - ${PYTHON} setup.py bdist_wheel + ${PYTHON} -m build --wheel - name: Upload Wheels uses: actions/upload-artifact@v3 with: @@ -110,7 +87,8 @@ jobs: - name: Build sdist shell: bash run: | - python setup.py sdist + pip install --upgrade pip build + python -m build --sdist - name: Upload sdist uses: actions/upload-artifact@v3 @@ -137,7 +115,7 @@ jobs: python: [3.7, 3.8, 3.9, "3.10"] steps: - name: Download wheels - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: osx-wheel-${{ matrix.python }} - name: Set up Python ${{ matrix.python }} @@ -160,7 +138,7 @@ jobs: wordsize: [64] steps: - name: Download wheels - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: win-wheel-${{ matrix.python }}-${{ matrix.wordsize }} - name: Set up Python ${{ matrix.python }} @@ -184,7 +162,7 @@ jobs: python: [3.7, 3.8, 3.9, "3.10"] steps: - name: Download wheels - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: linux-wheels - name: Set up Python @@ -204,7 +182,7 @@ jobs: needs: ['windows-test', 'OSX-test', 'manylinux-test'] steps: - name: Download all - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 - name: Move to dist run: | mkdir dist diff --git a/README.md b/README.md index f67aa6f1..f1efb5c5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The [documentation](https://tskit.dev/tsinfer/docs/stable) contains details of h The algorithm, its rationale, and results from testing on simulated and real data are described in the following [Nature Genetics paper](https://doi.org/10.1038/s41588-019-0483-y): -> Jerome Kelleher, Yan Wong, Anthony W Wohns, Chaimaa Fadil, Patrick K Albers and Gil McVean (2019) _Inferring whole-genome histories in large population datasets_. Nature Genetics **51**: 1330-1338 +> Jerome Kelleher, Yan Wong, Anthony W Wohns, Chaimaa Fadil, Patrick K Albers and Gil McVean (2019) *Inferring whole-genome histories in large population datasets*. Nature Genetics **51**: 1330-1338 Please cite this if you use ``tsinfer`` in your work. Code to reproduce the results in the paper is present in a [separate GitHub repository](https://github.com/mcveanlab/treeseq-inference). diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..4a7ef3cf --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,12 @@ +[build-system] +requires = [ + "setuptools>=42", + "setuptools_scm", + "wheel", + "oldest-supported-numpy" +] + +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] +write_to = "tsinfer/_version.py" \ No newline at end of file diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 50b8418b..00000000 --- a/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[pytest] -addopts = -n 4 -testpaths = - tests diff --git a/requirements/CI-tests-complete/requirements.txt b/requirements/CI-tests-complete/requirements.txt index dcd896f9..5c859cf8 100644 --- a/requirements/CI-tests-complete/requirements.txt +++ b/requirements/CI-tests-complete/requirements.txt @@ -1,4 +1,5 @@ attrs==21.4.0 +build==0.8.0 codecov==2.1.12 colorama==0.4.4 daiquiri==3.0.1 @@ -14,7 +15,9 @@ pytest==7.1.2 pytest-cov==3.0.0 pytest-xdist==2.5.0 seaborn==0.11.2 +setuptools==65.4.1 sortedcontainers==2.4.0 tqdm==4.64.0 tskit==0.5.3 +twine==4.0.1 zarr==2.11.3 diff --git a/requirements/development.txt b/requirements/development.txt index 33a5a1e4..679c73bf 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -25,6 +25,7 @@ numa; sys_platform == 'linux' sphinx sphinx-argparse sphinx_rtd_theme +setuptools>=45 setuptools_scm # Needed for evaluation script. pandas diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..e9b7db71 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,77 @@ +[metadata] +name = tsinfer +author= Tskit Developers +author_email = admin@tskit.dev +license = GNU GPLv3+ +description= Infer tree sequences from genetic variation data. +long_description_content_type = text/x-markdown +long_description = file: README.md +url = https://tskit.dev/tsinfer +project_urls = + Documentation = https://tskit.dev/tsinfer/docs/stable + Changelog = https://tskit.dev/tsinfer/docs/stable/CHANGELOG.html + Bug Tracker = https://github.com/tskit-dev/tsinfer/issues + GitHub = https://github.com/tskit-dev/tsinfer/ +classifiers = + Programming Language :: C + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3 :: Only + License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) + Development Status :: 3 - Alpha + Environment :: Other Environment + Intended Audience :: Science/Research + Operating System :: POSIX + Operating System :: MacOS :: MacOS X + Operating System :: Microsoft :: Windows + Topic :: Scientific/Engineering + Topic :: Scientific/Engineering :: Bio-Informatics +keywords = + population genetics + tree sequence + ancestral recombination graph + evolutionary tree + inference + tsinfer +platforms = + POSIX + Windows + MacOS X + +[options] +packages = tsinfer +python_requires = >=3.7 +include_package_data = True +install_requires = + numpy + six + tqdm + humanize + daiquiri + tskit>=0.5.3 + numcodecs>=0.6 + # issues 965 and 967 at zarr-python prevent usage of 2.11.0 and 2.11.1 + zarr>=2.2!=2.11.0!=2.11.1!=2.11.2 + lmdb + sortedcontainers + attrs>=19.2.0 + +[options.entry_points] +console_scripts = + tsinfer = tsinfer.__main__:main + +[tool:pytest] +addopts = -n 4 +testpaths = + tests + +[bdist_wheel] +# This flag says to generate wheels that support both Python 2 and Python +# 3. If your code will not run unchanged on both Python 2 and 3, you will +# need to generate separate wheels for each Python version that you +# support. +universal=0 diff --git a/setup.py b/setup.py index 6c46a046..f0579d28 100644 --- a/setup.py +++ b/setup.py @@ -1,26 +1,15 @@ import os import platform +import numpy from setuptools import Extension from setuptools import setup -from setuptools.command.build_ext import build_ext as _build_ext -IS_WINDOWS = platform.system() == "Windows" - - -# Obscure magic required to allow numpy be used as an 'setup_requires'. -class build_ext(_build_ext): - def finalize_options(self): - super().finalize_options() - # Prevent numpy from thinking it is still in its setup process: - __builtins__.__NUMPY_SETUP__ = False - import numpy - - self.include_dirs.append(numpy.get_include()) +IS_WINDOWS = platform.system() == "Windows" libdir = "lib" -tskroot = os.path.join("lib", "subprojects", "tskit") +tskroot = os.path.join(libdir, "subprojects", "tskit") tskdir = os.path.join(tskroot, "tskit") kasdir = os.path.join(tskroot, "subprojects", "kastore") includes = [libdir, tskroot, tskdir, kasdir] @@ -53,59 +42,16 @@ def finalize_options(self): _tsinfer_module = Extension( "_tsinfer", sources=sources, - # Enable asserts by default. - undef_macros=["NDEBUG"], extra_compile_args=["-std=c99"], - include_dirs=includes, libraries=libraries, + # Enable asserts by default. + undef_macros=["NDEBUG"], + include_dirs=includes + [numpy.get_include()], ) -with open("README.md") as f: - long_description = f.read() - setup( + # The package name along with all the other metadata is specified in setup.cfg + # However, GitHub's dependency graph can't see the package unless we put this here. name="tsinfer", - description="Infer tree sequences from genetic variation data.", - long_description=long_description, - packages=["tsinfer"], - author="Jerome Kelleher", - author_email="jerome.kelleher@bdi.ox.ac.uk", - url="http://pypi.python.org/pypi/tsinfer", - python_requires=">=3.7", - entry_points={"console_scripts": ["tsinfer=tsinfer.__main__:main"]}, - setup_requires=["setuptools_scm", "numpy"], - cmdclass={"build_ext": build_ext}, - install_requires=[ - "numpy", - "six", - "tqdm", - "humanize", - "daiquiri", - "tskit>=0.5.3", - "numcodecs>=0.6", - # issues 965 and 967 at zarr-python prevent usage of 2.11.0 and 2.11.1 - "zarr>=2.2,!=2.11.0,!=2.11.1,!=2.11.2", - "lmdb", - "sortedcontainers", - "attrs>=19.2.0", - ], ext_modules=[_tsinfer_module], - keywords=[], - license="GNU GPLv3+", - classifiers=[ - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3 :: Only", - "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", - "Development Status :: 3 - Alpha", - "Environment :: Other Environment", - "Intended Audience :: Science/Research", - "Operating System :: POSIX", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Bio-Informatics", - ], - use_scm_version={"write_to": "tsinfer/_version.py"}, )