diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3ef7f9b6e..9099347df 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,7 +28,7 @@ // "runServices": [], // Uncomment the next line if you want to keep your containers running after VS Code shuts down. "shutdownAction": "stopCompose", - "onCreateCommand": "python3 -m pip install -q -e .[test]", + "onCreateCommand": "python3 -m pip install -q -e .[dev]", "features": { "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/docker-in-docker:2": {}, diff --git a/.github/workflows/development.yaml b/.github/workflows/development.yaml deleted file mode 100644 index 63960b6c2..000000000 --- a/.github/workflows/development.yaml +++ /dev/null @@ -1,241 +0,0 @@ -name: Development -on: - push: - branches: - - "**" # every branch - - "!gh-pages" # exclude gh-pages branch - - "!stage*" # exclude branches beginning with stage - tags: - - '\d+\.\d+\.\d+' # only semver tags - pull_request: - branches: - - "**" # every branch - - "!gh-pages" # exclude gh-pages branch - - "!stage*" # exclude branches beginning with stage -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - include: - - py_ver: "3.9" - distro: debian - image: djbase - env: - PY_VER: ${{matrix.py_ver}} - DISTRO: ${{matrix.distro}} - IMAGE: ${{matrix.image}} - DOCKER_CLIENT_TIMEOUT: "120" - COMPOSE_HTTP_TIMEOUT: "120" - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: ${{matrix.py_ver}} - - name: Validate version and release notes - run: | - DJ_VERSION=$(grep -oP '\d+\.\d+\.\d+' datajoint/version.py) - RELEASE_BODY=$(python3 -c \ - 'print(open("./CHANGELOG.md").read().split("\n\n")[1].split("\n", 1)[1])' \ - ) - echo "DJ_VERSION=${DJ_VERSION}" >> $GITHUB_ENV - echo "RELEASE_BODY<> $GITHUB_ENV - echo "$RELEASE_BODY" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - name: Build pip artifacts - run: | - python3 -m pip install build - python3 -m build . - echo "DJ_VERSION=${DJ_VERSION}" >> $GITHUB_ENV - - if: matrix.py_ver == '3.9' && matrix.distro == 'debian' - name: Add pip artifacts - uses: actions/upload-artifact@v4 - with: - name: pip-datajoint-${{env.DJ_VERSION}} - path: dist - retention-days: 1 - test: - runs-on: ubuntu-latest - strategy: - matrix: - py_ver: ["3.9"] - mysql_ver: ["8.0", "5.7"] - include: - - py_ver: "3.13" - mysql_ver: "8.0" - - py_ver: "3.12" - mysql_ver: "8.0" - - py_ver: "3.11" - mysql_ver: "8.0" - - py_ver: "3.10" - mysql_ver: "8.0" - - py_ver: "3.8" - mysql_ver: "5.7" - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{matrix.py_ver}} - uses: actions/setup-python@v5 - with: - python-version: ${{matrix.py_ver}} - - name: Run primary tests - env: - PY_VER: ${{matrix.py_ver}} - DJ_PASS: password - MYSQL_VER: ${{matrix.mysql_ver}} - DISTRO: alpine - MINIO_VER: RELEASE.2021-09-03T03-56-13Z - DOCKER_CLIENT_TIMEOUT: "120" - COMPOSE_HTTP_TIMEOUT: "120" - run: | - export HOST_UID=$(id -u) - docker compose --profile test up --quiet-pull --build --exit-code-from djtest djtest - lint: - runs-on: ubuntu-latest - strategy: - matrix: - py_ver: ["3.11"] - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{matrix.py_ver}} - uses: actions/setup-python@v5 - with: - python-version: ${{matrix.py_ver}} - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install ".[test]" - - name: Run syntax tests - run: flake8 datajoint --count --select=E9,F63,F7,F82 --show-source --statistics - - name: Run style tests - run: | - flake8 --ignore=E203,E722,W503 datajoint \ - --count --max-complexity=62 --max-line-length=127 --statistics \ - --per-file-ignores='datajoint/diagram.py:C901' - black --required-version '24.2.0' --check -v datajoint tests --diff - codespell: - name: Check for spelling errors - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Codespell - uses: codespell-project/actions-codespell@v2 - publish-docs: - if: | - github.event_name == 'push' && - startsWith(github.ref, 'refs/tags') - needs: test - runs-on: ubuntu-latest - env: - DOCKER_CLIENT_TIMEOUT: "120" - COMPOSE_HTTP_TIMEOUT: "120" - steps: - - uses: actions/checkout@v4 - - name: Deploy docs - run: | - export MODE=BUILD - export PACKAGE=datajoint - export UPSTREAM_REPO=https://github.com/${GITHUB_REPOSITORY}.git - export HOST_UID=$(id -u) - docker compose -f docs/docker-compose.yaml up --quiet-pull --exit-code-from docs --build - git push origin gh-pages - publish-release: - if: | - github.event_name == 'push' && - startsWith(github.ref, 'refs/tags') - needs: test - runs-on: ubuntu-latest - strategy: - matrix: - include: - - py_ver: "3.9" - distro: debian - image: djbase - env: - PY_VER: ${{matrix.py_ver}} - DISTRO: ${{matrix.distro}} - IMAGE: ${{matrix.image}} - TWINE_USERNAME: ${{secrets.twine_username}} - TWINE_PASSWORD: ${{secrets.twine_password}} - DOCKER_CLIENT_TIMEOUT: "120" - COMPOSE_HTTP_TIMEOUT: "120" - outputs: - release_upload_url: ${{steps.create_gh_release.outputs.upload_url}} - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{matrix.py_ver}} - uses: actions/setup-python@v5 - with: - python-version: ${{matrix.py_ver}} - - name: Determine package version - run: | - DJ_VERSION=$(grep -oP '\d+\.\d+\.\d+' datajoint/version.py) - RELEASE_BODY=$(python -c \ - 'print(open("./CHANGELOG.md").read().split("\n\n")[1].split("\n", 1)[1])' \ - ) - echo "DJ_VERSION=${DJ_VERSION}" >> $GITHUB_ENV - echo "RELEASE_BODY<> $GITHUB_ENV - echo "$RELEASE_BODY" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - name: Create GH release - id: create_gh_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - tag_name: ${{env.DJ_VERSION}} - release_name: Release ${{env.DJ_VERSION}} - body: ${{env.RELEASE_BODY}} - prerelease: false - draft: false - - name: Fetch pip artifacts - uses: actions/download-artifact@v4 - with: - name: pip-datajoint-${{env.DJ_VERSION}} - path: dist - - name: Determine pip artifact paths - run: | - echo "DJ_WHEEL_PATH=$(ls dist/datajoint-*.whl)" >> $GITHUB_ENV - echo "DJ_SDIST_PATH=$(ls dist/datajoint-*.tar.gz)" >> $GITHUB_ENV - - name: Upload pip wheel asset to release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - upload_url: ${{steps.create_gh_release.outputs.upload_url}} - asset_path: ${{env.DJ_WHEEL_PATH}} - asset_name: pip-datajoint-${{env.DJ_VERSION}}.whl - asset_content_type: application/zip - - name: Upload pip sdist asset to release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - upload_url: ${{steps.create_gh_release.outputs.upload_url}} - asset_path: ${{env.DJ_SDIST_PATH}} - asset_name: pip-datajoint-${{env.DJ_VERSION}}.tar.gz - asset_content_type: application/gzip - - name: Publish pip release - run: | - export HOST_UID=$(id -u) - docker compose run --build --quiet-pull \ - -e TWINE_USERNAME=${TWINE_USERNAME} -e TWINE_PASSWORD=${TWINE_PASSWORD} app \ - sh -c "pip install twine && python -m twine upload dist/*" - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{secrets.docker_username}} - password: ${{secrets.docker_password}} - - name: Publish image - run: | - IMAGE=$(docker images --filter "reference=datajoint/datajoint*" --format "{{.Repository}}") - TAG=$(docker images --filter "reference=datajoint/datajoint*" --format "{{.Tag}}") - docker push "${IMAGE}:${TAG}" - docker tag "${IMAGE}:${TAG}" "${IMAGE}:${TAG}-${GITHUB_SHA:0:7}" - docker push "${IMAGE}:${TAG}-${GITHUB_SHA:0:7}" - [ "$PY_VER" == "3.9" ] && [ "$DISTRO" == "debian" ] \ - && docker tag "${IMAGE}:${TAG}" "${IMAGE}:latest" \ - && docker push "${IMAGE}:latest" \ - || echo "skipping 'latest' tag..." diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 897e39e5f..f434d63d7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,12 +1,10 @@ name: Manual docs release on: workflow_dispatch: + workflow_call: jobs: publish-docs: runs-on: ubuntu-latest - env: - DOCKER_CLIENT_TIMEOUT: "120" - COMPOSE_HTTP_TIMEOUT: "120" steps: - uses: actions/checkout@v4 - name: Deploy docs diff --git a/.github/workflows/label_issues.yaml b/.github/workflows/label_issues.yaml index 9504b5705..d5f99f015 100644 --- a/.github/workflows/label_issues.yaml +++ b/.github/workflows/label_issues.yaml @@ -15,4 +15,4 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }} NUMBER: ${{ github.event.issue.number }} - LABELS: triage \ No newline at end of file + LABELS: triage diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 000000000..1b012f1f9 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,29 @@ +name: Test +on: + push: + branches: + - "**" # every branch + - "!gh-pages" # exclude gh-pages branch + - "!stage*" # exclude branches beginning with stage + pull_request: + branches: + - "**" # every branch + - "!gh-pages" # exclude gh-pages branch + - "!stage*" # exclude branches beginning with stage +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + # enforce the same check as pre-commit + # but only run important checks + - uses: pre-commit/action@v3.0.1 + with: + extra_args: codespell --all-files + - uses: pre-commit/action@v3.0.1 + with: + extra_args: black --all-files + - uses: pre-commit/action@v3.0.1 + with: + extra_args: flake8 --all-files diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 000000000..ae848c310 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,127 @@ +name: Release +on: + workflow_dispatch: + inputs: + testpypi: + description: 'Release to TestPyPI then skip following' + default: 'false' + type: choice + options: + - 'true' + - 'false' +jobs: + build-release: + runs-on: ubuntu-latest + # Use the oldest supported version to build, just in case there are issues + # for our case, this doesn't matter that much, since the build is for 3.x + strategy: + matrix: + include: + - py_ver: "3.9" + env: + PY_VER: ${{matrix.py_ver}} + TWINE_USERNAME: ${{secrets.twine_username}} + TWINE_PASSWORD: ${{secrets.twine_password}} + TWINE_TEST_USERNAME: ${{secrets.twine_test_username}} + TWINE_TEST_PASSWORD: ${{secrets.twine_test_password}} + TESTPYPI: ${{ github.event.inputs.testpypi }} + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{matrix.py_ver}} + uses: actions/setup-python@v5 + with: + python-version: ${{matrix.py_ver}} + # Merging build and release steps just for the simplicity, + # since datajoint-python doesn't have platform specific dependencies or binaries, + # and the build process is fairly fast, so removed upload/download artifacts + - name: Build package + run: | + python -m pip install build + python -m build . + echo "DJ_WHEEL_PATH=$(ls dist/datajoint-*.whl)" >> $GITHUB_ENV + echo "DJ_SDIST_PATH=$(ls dist/datajoint-*.tar.gz)" >> $GITHUB_ENV + - name: Publish package + run: | + export HOST_UID=$(id -u) + if [ "$TESTPYPI" == "true" ]; then + export TWINE_REPOSITORY="testpypi" + export TWINE_USERNAME=${TWINE_TEST_USERNAME} + export TWINE_PASSWORD=${TWINE_TEST_PASSWORD} + else + export TWINE_REPOSITORY="pypi" + fi + docker compose run --build --quiet-pull \ + -e TWINE_USERNAME=${TWINE_USERNAME} \ + -e TWINE_PASSWORD=${TWINE_PASSWORD} \ + -e TWINE_REPOSITORY=${TWINE_REPOSITORY} \ + app sh -c "pip install twine && python -m twine upload dist/*" + - name: Login to DockerHub + if: ${{ github.event.inputs.testpypi == 'false' }} + uses: docker/login-action@v3 + with: + username: ${{secrets.docker_username}} + password: ${{secrets.docker_password}} + - name: Publish image + if: ${{ github.event.inputs.testpypi == 'false' }} + run: | + IMAGE=$(docker images --filter "reference=datajoint/datajoint*" --format "{{.Repository}}") + TAG=$(docker images --filter "reference=datajoint/datajoint*" --format "{{.Tag}}") + docker push "${IMAGE}:${TAG}" + docker tag "${IMAGE}:${TAG}" "${IMAGE}:${TAG}-${GITHUB_SHA:0:7}" + docker push "${IMAGE}:${TAG}-${GITHUB_SHA:0:7}" + [ "$PY_VER" == "3.9" ] && [ "$DISTRO" == "debian" ] \ + && docker tag "${IMAGE}:${TAG}" "${IMAGE}:latest" \ + && docker push "${IMAGE}:latest" \ + || echo "skipping 'latest' tag..." + # Make sure all above release targets are done first, then make a GH release + - name: Make release notes + if: ${{ github.event.inputs.testpypi == 'false' }} + run: | + DJ_VERSION=$(grep -oP '\d+\.\d+\.\d+' datajoint/version.py) + RELEASE_BODY=$(python -c \ + 'print(open("./CHANGELOG.md").read().split("\n\n")[1].split("\n", 1)[1])' \ + ) + echo "DJ_VERSION=${DJ_VERSION}" >> $GITHUB_ENV + echo "RELEASE_BODY<> $GITHUB_ENV + echo "$RELEASE_BODY" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + - name: Create GH release + if: ${{ github.event.inputs.testpypi == 'false' }} + id: create_gh_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + tag_name: ${{env.DJ_VERSION}} + release_name: Release ${{env.DJ_VERSION}} + body: ${{env.RELEASE_BODY}} + prerelease: false + draft: false + # Upload package as release assets + - name: Upload pip wheel asset to release + if: ${{ github.event.inputs.testpypi == 'false' }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + upload_url: ${{steps.create_gh_release.outputs.upload_url}} + asset_path: ${{env.DJ_WHEEL_PATH}} + asset_name: pip-datajoint-${{env.DJ_VERSION}}.whl + asset_content_type: application/zip + - name: Upload pip sdist asset to release + if: ${{ github.event.inputs.testpypi == 'false' }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + upload_url: ${{steps.create_gh_release.outputs.upload_url}} + asset_path: ${{env.DJ_SDIST_PATH}} + asset_name: pip-datajoint-${{env.DJ_VERSION}}.tar.gz + asset_content_type: application/gzip + # only release docs when a release is published + call-publish-docs: + if: ${{ github.event.inputs.testpypi == 'false' }} + needs: build-release + runs-on: ubuntu-latest + steps: + - uses: ./.github/workflows/docs.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 000000000..196ddec22 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,42 @@ +name: Test +on: + push: + branches: + - "**" # every branch + - "!gh-pages" # exclude gh-pages branch + - "!stage*" # exclude branches beginning with stage + paths: + - "datajoint" + - "tests" + pull_request: + branches: + - "**" # every branch + - "!gh-pages" # exclude gh-pages branch + - "!stage*" # exclude branches beginning with stage + paths: + - "datajoint" + - "tests" +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + py_ver: ["3.9", "3.10", "3.11", "3.12", "3.13"] + mysql_ver: ["8.0"] + include: + - py_ver: "3.9" + mysql_ver: "5.7" + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{matrix.py_ver}} + uses: actions/setup-python@v5 + with: + python-version: ${{matrix.py_ver}} + - name: Integration test + env: + PY_VER: ${{matrix.py_ver}} + MYSQL_VER: ${{matrix.mysql_ver}} + # taking default variables set in docker-compose.yaml to sync with local test + run: | + export HOST_UID=$(id -u) + docker compose --profile test up --quiet-pull --build --exit-code-from djtest djtest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3ba3bdac1..b8992481a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,8 +15,6 @@ repos: - id: check-json exclude: '(.vscode|.devcontainer)' # exclude these since // was used for comments - id: check-toml - - id: trailing-whitespace - - id: end-of-file-fixer - id: check-added-large-files - repo: https://github.com/codespell-project/codespell rev: v2.4.1 @@ -36,6 +34,15 @@ repos: - repo: https://github.com/PyCQA/flake8 rev: 7.1.2 hooks: + # syntax tests + - id: flake8 + args: + - --select=E9,F63,F7,F82 + - --count + - --show-source + - --statistics + files: datajoint # a lot of files in tests are not compliant + # style tests - id: flake8 args: - --ignore=E203,E722,W503 @@ -45,6 +52,11 @@ repos: - --statistics - --per-file-ignores=datajoint/diagram.py:C901 files: datajoint # a lot of files in tests are not compliant +- repo: https://github.com/rhysd/actionlint + rev: v1.7.7 + hooks: + # lint github actions workflow yaml + - id: actionlint ## Suggest to add pytest hook that runs unit test | Prerequisite: split unit/integration test ## https://github.com/datajoint/datajoint-python/issues/1211 diff --git a/datajoint/autopopulate.py b/datajoint/autopopulate.py index d0b0a67c6..a57d74a89 100644 --- a/datajoint/autopopulate.py +++ b/datajoint/autopopulate.py @@ -265,13 +265,16 @@ def handler(signum, frame): # spawn multiple processes self.connection.close() # disconnect parent process from MySQL server del self.connection._conn.ctx # SSLContext is not pickleable - with mp.Pool( - processes, _initialize_populate, (self, jobs, populate_kwargs) - ) as pool, ( - tqdm(desc="Processes: ", total=nkeys) - if display_progress - else contextlib.nullcontext() - ) as progress_bar: + with ( + mp.Pool( + processes, _initialize_populate, (self, jobs, populate_kwargs) + ) as pool, + ( + tqdm(desc="Processes: ", total=nkeys) + if display_progress + else contextlib.nullcontext() + ) as progress_bar, + ): for status in pool.imap(_call_populate1, keys, chunksize=1): if status is True: success_list.append(1) diff --git a/docker-compose.yaml b/docker-compose.yaml index 9e413bdb3..d09d06d49 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,7 +15,7 @@ services: retries: 5 interval: 15s minio: - image: minio/minio:${MINIO_VER:-RELEASE.2022-08-11T04-37-28Z} + image: minio/minio:${MINIO_VER:-RELEASE.2025-02-28T09-55-16Z} environment: - MINIO_ACCESS_KEY=datajoint - MINIO_SECRET_KEY=datajoint diff --git a/docs/src/develop.md b/docs/src/develop.md index 5643623d5..4c66d52de 100644 --- a/docs/src/develop.md +++ b/docs/src/develop.md @@ -23,7 +23,7 @@ Here are some options that provide a great developer experience: - Ensure you have [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) - Ensure you have [Docker](https://docs.docker.com/get-docker/) - `git clone` the codebase repository and open it in VSCode - - Issue the following command in the terminal to build and run the Docker container: `HOST_UID=$(id -u) PY_VER=3.11 DJ_VERSION=$(grep -oP '\d+\.\d+\.\d+' datajoint/version.py) docker compose --profile test run --rm -it djtest -- sh -c 'pip install -qe ".[test]" && bash'` + - Issue the following command in the terminal to build and run the Docker container: `HOST_UID=$(id -u) PY_VER=3.11 DJ_VERSION=$(grep -oP '\d+\.\d+\.\d+' datajoint/version.py) docker compose --profile test run --rm -it djtest -- sh -c 'pip install -qe ".[dev]" && bash'` - Issue the following command in the terminal to stop the Docker compose stack: `docker compose --profile test down` ## Features diff --git a/pyproject.toml b/pyproject.toml index 6040be300..5668d2bd4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,11 @@ +[build-system] +requires = ["setuptools>=60"] +build-backend = "setuptools.build_meta" + [project] name = "datajoint" -version = "0.14.3" +# dynamically set in tools.setuptools.dynamic +dynamic = ["version"] dependencies = [ "numpy", "pymysql>=0.7.2", @@ -18,7 +23,7 @@ dependencies = [ "cryptography", "urllib3" ] -requires-python = ">=3.8,<4.0" +requires-python = ">=3.9,<4.0" authors = [ {name = "Dimitri Yatsenko", email = "dimitri@datajoint.com"}, {name = "Raphael Guzman"}, @@ -29,26 +34,37 @@ maintainers = [ {name = "Dimitri Yatsenko", email = "dimitri@datajoint.com"}, {name = "DataJoint Contributors", email = "support@datajoint.com"}, ] -description = "A relational data pipeline framework." +# manually sync here: https://datajoint.com/docs/core/datajoint-python/latest/#welcome-to-datajoint-for-python +description = "DataJoint for Python is a framework for scientific workflow management based on relational principles. DataJoint is built on the foundation of the relational data model and prescribes a consistent method for organizing, populating, computing, and querying data." readme = "README.md" license = {file = "LICENSE.txt"} keywords = [ "database", - "data pipelines", - "scientific computing", - "automated research workflows", + "automated", + "automation", + "compute", + "data", + "pipeline", + "workflow", + "scientific", + "science", + "research", + "neuroscience", + "bioinformatics", + "bio-informatics", + "datajoint", ] +# https://pypi.org/classifiers/ classifiers = [ - "Programming Language :: Python" -] - -[project.optional-dependencies] -test = [ - "pre-commit", - "pytest", - "pytest-cov", - "black==24.2.0", - "flake8", + "Programming Language :: Python", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "Intended Audience :: Healthcare Industry", + "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Bio-Informatics", + "Topic :: Scientific/Engineering :: Neuroscience", # Not standard, but just in case ] [project.urls] @@ -56,18 +72,33 @@ Homepage = "https://datajoint.com/docs" Documentation = "https://datajoint.com/docs" Repository = "https://github.com/datajoint/datajoint-python" "Bug Tracker" = "https://github.com/datajoint/datajoint-python/issues" -Changelog = "https://github.com/datajoint/datajoint-python/blob/master/CHANGELOG.md" +"Release Notes" = "https://github.com/datajoint/datajoint-python/releases" [project.entry-points."console_scripts"] dj = "datajoint.cli:cli" datajoint = "datajoint.cli:cli" +[project.optional-dependencies] +test = [ + "pytest", + "pytest-cov", +] +dev = [ + "pre-commit", + "black==24.2.0", + "flake8", + "isort", + "codespell", + # including test + "pytest", + "pytest-cov", +] + +[tool.isort] +profile = "black" + [tool.setuptools] packages = ["datajoint"] -[build-system] -requires = [ - "setuptools>=60", - "setuptools-scm>=8.0" -] -build-backend = "setuptools.build_meta" +[tool.setuptools.dynamic] +version = { attr = "datajoint.version.__version__"}