diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0dbb8bc22..75b4dc276 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 6596d2c0e..01217f3a3 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,5 +1,5 @@ pip==23.1.2 poetry==1.5.1 -pre-commit==3.3.2 +pre-commit==3.3.3 nox==2023.4.22 nox-poetry==1.0.2 diff --git a/.github/workflows/cookiecutter-e2e.yml b/.github/workflows/cookiecutter-e2e.yml index 766857ac0..7adca51d7 100644 --- a/.github/workflows/cookiecutter-e2e.yml +++ b/.github/workflows/cookiecutter-e2e.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Upgrade pip env: diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index dc7c94bbd..8048f9cad 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: GitHub dependency vulnerability check if: ${{ github.event_name == 'pull_request_target' }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35d1db076..f34a699f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Set up Python uses: actions/setup-python@v4.6.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ed83c627f..150901c93 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Install Poetry env: @@ -91,7 +91,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Install Poetry env: @@ -133,7 +133,7 @@ jobs: needs: tests steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Install Poetry run: | diff --git a/.github/workflows/version_bump.yml b/.github/workflows/version_bump.yml index 1889fcf22..47649408e 100644 --- a/.github/workflows/version_bump.yml +++ b/.github/workflows/version_bump.yml @@ -35,7 +35,7 @@ jobs: pull-requests: write # to create and update PRs steps: - - uses: actions/checkout@v3.5.2 + - uses: actions/checkout@v3.5.3 with: fetch-depth: 0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3b4bcc315..6ba7d32d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,14 +36,14 @@ repos: )$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.23.1 + rev: 0.23.2 hooks: - id: check-dependabot - id: check-github-workflows - id: check-readthedocs - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.270 + rev: v0.0.272 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/docs/conf.py b/docs/conf.py index 87df1b6b7..c97ea6a5a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -69,9 +69,12 @@ "source_branch": "main", "source_directory": "docs/", "sidebar_hide_name": True, + "announcement": 'Sign up for Public Beta today! Get a 20% discount on purchases before 27th of July!', # noqa: E501 # branding "light_css_variables": { "font-stack": "Hanken Grotesk,-apple-system,Helvetica,sans-serif", + "color-announcement-background": "#3A64FA", + "color-announcement-text": "#EEEBEE", "color-foreground-primary": "#080216", "color-background-primary": "#E9E5FB", "color-link": "#3A64FA", diff --git a/poetry.lock b/poetry.lock index eaad584e1..f7b47cb6e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1198,37 +1198,37 @@ files = [ [[package]] name = "mypy" -version = "1.3.0" +version = "1.4.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d"}, - {file = "mypy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85"}, - {file = "mypy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd"}, - {file = "mypy-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152"}, - {file = "mypy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c"}, - {file = "mypy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae"}, - {file = "mypy-1.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca"}, - {file = "mypy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf"}, - {file = "mypy-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409"}, - {file = "mypy-1.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929"}, - {file = "mypy-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a"}, - {file = "mypy-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb"}, - {file = "mypy-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4"}, - {file = "mypy-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305"}, - {file = "mypy-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703"}, - {file = "mypy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017"}, - {file = "mypy-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e"}, - {file = "mypy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a"}, - {file = "mypy-1.3.0-py3-none-any.whl", hash = "sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897"}, - {file = "mypy-1.3.0.tar.gz", hash = "sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11"}, + {file = "mypy-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3af348e0925a59213244f28c7c0c3a2c2088b4ba2fe9d6c8d4fbb0aba0b7d05"}, + {file = "mypy-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0b2e0da7ff9dd8d2066d093d35a169305fc4e38db378281fce096768a3dbdbf"}, + {file = "mypy-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210fe0f39ec5be45dd9d0de253cb79245f0a6f27631d62e0c9c7988be7152965"}, + {file = "mypy-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f7a5971490fd4a5a436e143105a1f78fa8b3fe95b30fff2a77542b4f3227a01f"}, + {file = "mypy-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:50f65f0e9985f1e50040e603baebab83efed9eb37e15a22a4246fa7cd660f981"}, + {file = "mypy-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b1b5c875fcf3e7217a3de7f708166f641ca154b589664c44a6fd6d9f17d9e7e"}, + {file = "mypy-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4c734d947e761c7ceb1f09a98359dd5666460acbc39f7d0a6b6beec373c5840"}, + {file = "mypy-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5984a8d13d35624e3b235a793c814433d810acba9eeefe665cdfed3d08bc3af"}, + {file = "mypy-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0f98973e39e4a98709546a9afd82e1ffcc50c6ec9ce6f7870f33ebbf0bd4f26d"}, + {file = "mypy-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:19d42b08c7532d736a7e0fb29525855e355fa51fd6aef4f9bbc80749ff64b1a2"}, + {file = "mypy-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6ba9a69172abaa73910643744d3848877d6aac4a20c41742027dcfd8d78f05d9"}, + {file = "mypy-1.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a34eed094c16cad0f6b0d889811592c7a9b7acf10d10a7356349e325d8704b4f"}, + {file = "mypy-1.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:53c2a1fed81e05ded10a4557fe12bae05b9ecf9153f162c662a71d924d504135"}, + {file = "mypy-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bba57b4d2328740749f676807fcf3036e9de723530781405cc5a5e41fc6e20de"}, + {file = "mypy-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:653863c75f0dbb687d92eb0d4bd9fe7047d096987ecac93bb7b1bc336de48ebd"}, + {file = "mypy-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7461469e163f87a087a5e7aa224102a30f037c11a096a0ceeb721cb0dce274c8"}, + {file = "mypy-1.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cf0ca95e4b8adeaf07815a78b4096b65adf64ea7871b39a2116c19497fcd0dd"}, + {file = "mypy-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94a81b9354545123feb1a99b960faeff9e1fa204fce47e0042335b473d71530d"}, + {file = "mypy-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:67242d5b28ed0fa88edd8f880aed24da481929467fdbca6487167cb5e3fd31ff"}, + {file = "mypy-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3f2b353eebef669529d9bd5ae3566905a685ae98b3af3aad7476d0d519714758"}, + {file = "mypy-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62bf18d97c6b089f77f0067b4e321db089d8520cdeefc6ae3ec0f873621c22e5"}, + {file = "mypy-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca33ab70a4aaa75bb01086a0b04f0ba8441e51e06fc57e28585176b08cad533b"}, + {file = "mypy-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5a0ee54c2cb0f957f8a6f41794d68f1a7e32b9968675ade5846f538504856d42"}, + {file = "mypy-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6c34d43e3d54ad05024576aef28081d9d0580f6fa7f131255f54020eb12f5352"}, + {file = "mypy-1.4.0-py3-none-any.whl", hash = "sha256:f051ca656be0c179c735a4c3193f307d34c92fdc4908d44fd4516fbe8b10567d"}, + {file = "mypy-1.4.0.tar.gz", hash = "sha256:de1e7e68148a213036276d1f5303b3836ad9a774188961eb2684eddff593b042"}, ] [package.dependencies] @@ -1488,36 +1488,36 @@ wcwidth = "*" [[package]] name = "pyarrow" -version = "12.0.0" +version = "12.0.1" description = "Python library for Apache Arrow" optional = false python-versions = ">=3.7" files = [ - {file = "pyarrow-12.0.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:3b97649c8a9a09e1d8dc76513054f1331bd9ece78ee39365e6bf6bc7503c1e94"}, - {file = "pyarrow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bc4ea634dacb03936f50fcf59574a8e727f90c17c24527e488d8ceb52ae284de"}, - {file = "pyarrow-12.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d568acfca3faa565d663e53ee34173be8e23a95f78f2abfdad198010ec8f745"}, - {file = "pyarrow-12.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b50bb9a82dca38a002d7cbd802a16b1af0f8c50ed2ec94a319f5f2afc047ee9"}, - {file = "pyarrow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:3d1733b1ea086b3c101427d0e57e2be3eb964686e83c2363862a887bb5c41fa8"}, - {file = "pyarrow-12.0.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:a7cd32fe77f967fe08228bc100433273020e58dd6caced12627bcc0a7675a513"}, - {file = "pyarrow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:92fb031e6777847f5c9b01eaa5aa0c9033e853ee80117dce895f116d8b0c3ca3"}, - {file = "pyarrow-12.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:280289ebfd4ac3570f6b776515baa01e4dcbf17122c401e4b7170a27c4be63fd"}, - {file = "pyarrow-12.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:272f147d4f8387bec95f17bb58dcfc7bc7278bb93e01cb7b08a0e93a8921e18e"}, - {file = "pyarrow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:0846ace49998825eda4722f8d7f83fa05601c832549c9087ea49d6d5397d8cec"}, - {file = "pyarrow-12.0.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:993287136369aca60005ee7d64130f9466489c4f7425f5c284315b0a5401ccd9"}, - {file = "pyarrow-12.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a7b6a765ee4f88efd7d8348d9a1f804487d60799d0428b6ddf3344eaef37282"}, - {file = "pyarrow-12.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c4fce253d5bdc8d62f11cfa3da5b0b34b562c04ce84abb8bd7447e63c2b327"}, - {file = "pyarrow-12.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e6be4d85707fc8e7a221c8ab86a40449ce62559ce25c94321df7c8500245888f"}, - {file = "pyarrow-12.0.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:ea830d9f66bfb82d30b5794642f83dd0e4a718846462d22328981e9eb149cba8"}, - {file = "pyarrow-12.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7b5b9f60d9ef756db59bec8d90e4576b7df57861e6a3d6a8bf99538f68ca15b3"}, - {file = "pyarrow-12.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99e559d27db36ad3a33868a475f03e3129430fc065accc839ef4daa12c6dab6"}, - {file = "pyarrow-12.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b0810864a593b89877120972d1f7af1d1c9389876dbed92b962ed81492d3ffc"}, - {file = "pyarrow-12.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:23a77d97f4d101ddfe81b9c2ee03a177f0e590a7e68af15eafa06e8f3cf05976"}, - {file = "pyarrow-12.0.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:2cc63e746221cddb9001f7281dee95fd658085dd5b717b076950e1ccc607059c"}, - {file = "pyarrow-12.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8c26912607e26c2991826bbaf3cf2b9c8c3e17566598c193b492f058b40d3a4"}, - {file = "pyarrow-12.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8b90efc290e99a81d06015f3a46601c259ecc81ffb6d8ce288c91bd1b868c9"}, - {file = "pyarrow-12.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2466be046b81863be24db370dffd30a2e7894b4f9823fb60ef0a733c31ac6256"}, - {file = "pyarrow-12.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:0e36425b1c1cbf5447718b3f1751bf86c58f2b3ad299f996cd9b1aa040967656"}, - {file = "pyarrow-12.0.0.tar.gz", hash = "sha256:19c812d303610ab5d664b7b1de4051ae23565f9f94d04cbea9e50569746ae1ee"}, + {file = "pyarrow-12.0.1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d288029a94a9bb5407ceebdd7110ba398a00412c5b0155ee9813a40d246c5df"}, + {file = "pyarrow-12.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345e1828efdbd9aa4d4de7d5676778aba384a2c3add896d995b23d368e60e5af"}, + {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d6009fdf8986332b2169314da482baed47ac053311c8934ac6651e614deacd6"}, + {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d3c4cbbf81e6dd23fe921bc91dc4619ea3b79bc58ef10bce0f49bdafb103daf"}, + {file = "pyarrow-12.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdacf515ec276709ac8042c7d9bd5be83b4f5f39c6c037a17a60d7ebfd92c890"}, + {file = "pyarrow-12.0.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:749be7fd2ff260683f9cc739cb862fb11be376de965a2a8ccbf2693b098db6c7"}, + {file = "pyarrow-12.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6895b5fb74289d055c43db3af0de6e16b07586c45763cb5e558d38b86a91e3a7"}, + {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1887bdae17ec3b4c046fcf19951e71b6a619f39fa674f9881216173566c8f718"}, + {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2c9cb8eeabbadf5fcfc3d1ddea616c7ce893db2ce4dcef0ac13b099ad7ca082"}, + {file = "pyarrow-12.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ce4aebdf412bd0eeb800d8e47db854f9f9f7e2f5a0220440acf219ddfddd4f63"}, + {file = "pyarrow-12.0.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:e0d8730c7f6e893f6db5d5b86eda42c0a130842d101992b581e2138e4d5663d3"}, + {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43364daec02f69fec89d2315f7fbfbeec956e0d991cbbef471681bd77875c40f"}, + {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051f9f5ccf585f12d7de836e50965b3c235542cc896959320d9776ab93f3b33d"}, + {file = "pyarrow-12.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:be2757e9275875d2a9c6e6052ac7957fbbfc7bc7370e4a036a9b893e96fedaba"}, + {file = "pyarrow-12.0.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:cf812306d66f40f69e684300f7af5111c11f6e0d89d6b733e05a3de44961529d"}, + {file = "pyarrow-12.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:459a1c0ed2d68671188b2118c63bac91eaef6fc150c77ddd8a583e3c795737bf"}, + {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e705e33eaf666bbe508a16fd5ba27ca061e177916b7a317ba5a51bee43384c"}, + {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9120c3eb2b1f6f516a3b7a9714ed860882d9ef98c4b17edcdc91d95b7528db60"}, + {file = "pyarrow-12.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c780f4dc40460015d80fcd6a6140de80b615349ed68ef9adb653fe351778c9b3"}, + {file = "pyarrow-12.0.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a3c63124fc26bf5f95f508f5d04e1ece8cc23a8b0af2a1e6ab2b1ec3fdc91b24"}, + {file = "pyarrow-12.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b13329f79fa4472324f8d32dc1b1216616d09bd1e77cfb13104dec5463632c36"}, + {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb656150d3d12ec1396f6dde542db1675a95c0cc8366d507347b0beed96e87ca"}, + {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6251e38470da97a5b2e00de5c6a049149f7b2bd62f12fa5dbb9ac674119ba71a"}, + {file = "pyarrow-12.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:3de26da901216149ce086920547dfff5cd22818c9eab67ebc41e863a5883bac7"}, + {file = "pyarrow-12.0.1.tar.gz", hash = "sha256:cce317fc96e5b71107bf1f9f184d5e54e2bd14bbf3f9a3d62819961f0af86fec"}, ] [package.dependencies] @@ -1690,13 +1690,13 @@ files = [ [[package]] name = "pytest" -version = "7.3.1" +version = "7.3.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, - {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, + {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, + {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, ] [package.dependencies] @@ -1709,7 +1709,7 @@ pluggy = ">=0.12,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-durations" diff --git a/singer_sdk/helpers/capabilities.py b/singer_sdk/helpers/capabilities.py index 00a420daf..55aff8ce3 100644 --- a/singer_sdk/helpers/capabilities.py +++ b/singer_sdk/helpers/capabilities.py @@ -59,11 +59,17 @@ "encoding", description="Specifies the format and compression of the batch files.", wrapped=ObjectType( - Property("format", StringType, allowed_values=["jsonl"]), + Property( + "format", + StringType, + allowed_values=["jsonl"], + description="Format to use for batch files.", + ), Property( "compression", StringType, allowed_values=["gzip", "none"], + description="Compression format to use for batch files.", ), ), ), @@ -71,8 +77,16 @@ "storage", description="Defines the storage layer to use when writing batch files", wrapped=ObjectType( - Property("root", StringType), - Property("prefix", StringType), + Property( + "root", + StringType, + description="Root path to use when writing batch files.", + ), + Property( + "prefix", + StringType, + description="Prefix to use when writing batch files.", + ), ), ), ), diff --git a/singer_sdk/sinks/core.py b/singer_sdk/sinks/core.py index 0c6351779..2510be03c 100644 --- a/singer_sdk/sinks/core.py +++ b/singer_sdk/sinks/core.py @@ -3,6 +3,7 @@ from __future__ import annotations import abc +import copy import datetime import json import time @@ -67,6 +68,7 @@ def __init__( "Initializing target sink for stream '%s'...", stream_name, ) + self.original_schema = copy.deepcopy(schema) self.schema = schema if self.include_sdc_metadata_properties: self._add_sdc_metadata_to_schema() @@ -254,17 +256,17 @@ def _add_sdc_metadata_to_schema(self) -> None: https://sdk.meltano.com/en/latest/implementation/record_metadata.html """ properties_dict = self.schema["properties"] - for col in { + for col in ( "_sdc_extracted_at", "_sdc_received_at", "_sdc_batched_at", "_sdc_deleted_at", - }: + ): properties_dict[col] = { "type": ["null", "string"], "format": "date-time", } - for col in {"_sdc_sequence", "_sdc_table_version"}: + for col in ("_sdc_sequence", "_sdc_table_version"): properties_dict[col] = {"type": ["null", "integer"]} def _remove_sdc_metadata_from_schema(self) -> None: @@ -274,14 +276,14 @@ def _remove_sdc_metadata_from_schema(self) -> None: https://sdk.meltano.com/en/latest/implementation/record_metadata.html """ properties_dict = self.schema["properties"] - for col in { + for col in ( "_sdc_extracted_at", "_sdc_received_at", "_sdc_batched_at", "_sdc_deleted_at", "_sdc_sequence", "_sdc_table_version", - }: + ): properties_dict.pop(col, None) def _remove_sdc_metadata_from_record(self, record: dict) -> None: diff --git a/singer_sdk/streams/core.py b/singer_sdk/streams/core.py index 31e16dc8b..a414123dd 100644 --- a/singer_sdk/streams/core.py +++ b/singer_sdk/streams/core.py @@ -269,7 +269,6 @@ def get_starting_timestamp(self, context: dict | None) -> datetime.datetime | No return t.cast(datetime.datetime, pendulum.parse(value)) - @final @property def selected(self) -> bool: """Check if stream is selected. @@ -279,6 +278,16 @@ def selected(self) -> bool: """ return self.mask.get((), True) + @selected.setter + def selected(self, value: bool | None) -> None: + """Set stream selection. + + Args: + value: True if the stream is selected. + """ + self.metadata.root.selected = value + self._mask = self.metadata.resolve_selection() + @final @property def has_selected_descendents(self) -> bool: diff --git a/singer_sdk/tap_base.py b/singer_sdk/tap_base.py index 23d8e815b..150f0ee81 100644 --- a/singer_sdk/tap_base.py +++ b/singer_sdk/tap_base.py @@ -246,6 +246,9 @@ def run_sync_dry_run( # Initialize streams' record limits before beginning the sync test. stream.ABORT_AT_RECORD_COUNT = dry_run_record_limit + # Force selection of streams. + stream.selected = True + for stream in streams: if stream.parent_stream_type: self.logger.debug( @@ -267,6 +270,7 @@ def run_sync_dry_run( def write_schemas(self) -> None: """Write a SCHEMA message for all known streams to STDOUT.""" for stream in self.streams.values(): + stream.selected = True stream._write_schema_message() # Stream detection: diff --git a/singer_sdk/target_base.py b/singer_sdk/target_base.py index f59f9be32..facd69c87 100644 --- a/singer_sdk/target_base.py +++ b/singer_sdk/target_base.py @@ -166,7 +166,7 @@ def get_sink( return self.add_sink(stream_name, schema, key_properties) if ( - existing_sink.schema != schema + existing_sink.original_schema != schema or existing_sink.key_properties != key_properties ): self.logger.info( diff --git a/singer_sdk/typing.py b/singer_sdk/typing.py index f2766944c..1e70f6201 100644 --- a/singer_sdk/typing.py +++ b/singer_sdk/typing.py @@ -825,7 +825,9 @@ def _jsonschema_type_check(jsonschema_type: dict, type_check: tuple[str]) -> boo if jsonschema_type.get("type") in type_check: # noqa: PLR5501 return True - if any(t in type_check for t in jsonschema_type.get("anyOf", ())): + if any( + _jsonschema_type_check(t, type_check) for t in jsonschema_type.get("anyOf", ()) + ): return True return False diff --git a/tests/conftest.py b/tests/conftest.py index c2992328a..142e76fe1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,6 +9,10 @@ import pytest +from singer_sdk import typing as th +from singer_sdk.sinks import BatchSink +from singer_sdk.target_base import Target + if t.TYPE_CHECKING: from _pytest.config import Config @@ -54,3 +58,51 @@ def outdir() -> t.Generator[str, None, None]: def snapshot_dir() -> pathlib.Path: """Return the path to the snapshot directory.""" return pathlib.Path("tests/snapshots/") + + +class BatchSinkMock(BatchSink): + """A mock Sink class.""" + + name = "batch-sink-mock" + + def __init__( + self, + target: TargetMock, + stream_name: str, + schema: dict, + key_properties: list[str] | None, + ): + """Create the Mock batch-based sink.""" + super().__init__(target, stream_name, schema, key_properties) + self.target = target + + def process_record(self, record: dict, context: dict) -> None: + """Tracks the count of processed records.""" + self.target.num_records_processed += 1 + super().process_record(record, context) + + def process_batch(self, context: dict) -> None: + """Write to mock trackers.""" + self.target.records_written.extend(context["records"]) + self.target.num_batches_processed += 1 + + +class TargetMock(Target): + """A mock Target class.""" + + name = "target-mock" + config_jsonschema = th.PropertiesList().to_dict() + default_sink_class = BatchSinkMock + + def __init__(self, *args, **kwargs): + """Create the Mock target sync.""" + super().__init__(*args, **kwargs) + self.state_messages_written: list[dict] = [] + self.records_written: list[dict] = [] + self.num_records_processed: int = 0 + self.num_batches_processed: int = 0 + + def _write_state_message(self, state: dict): + """Emit the stream's latest state.""" + super()._write_state_message(state) + self.state_messages_written.append(state) diff --git a/tests/core/test_target_base.py b/tests/core/test_target_base.py new file mode 100644 index 000000000..778fab722 --- /dev/null +++ b/tests/core/test_target_base.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import copy + +from tests.conftest import BatchSinkMock, TargetMock + + +def test_get_sink(): + input_schema_1 = { + "properties": { + "id": { + "type": ["string", "null"], + }, + "col_ts": { + "format": "date-time", + "type": ["string", "null"], + }, + }, + } + input_schema_2 = copy.deepcopy(input_schema_1) + key_properties = [] + target = TargetMock(config={"add_record_metadata": True}) + sink = BatchSinkMock(target, "foo", input_schema_1, key_properties) + target._sinks_active["foo"] = sink + sink_returned = target.get_sink( + "foo", + schema=input_schema_2, + key_properties=key_properties, + ) + assert sink_returned == sink diff --git a/tests/core/test_typing.py b/tests/core/test_typing.py index 854669e5b..b2cf9c691 100644 --- a/tests/core/test_typing.py +++ b/tests/core/test_typing.py @@ -4,7 +4,9 @@ import datetime import logging -import typing as t + +import pytest +import sqlalchemy from singer_sdk.helpers._typing import ( TypeConformanceLevel, @@ -17,11 +19,9 @@ PropertiesList, Property, StringType, + to_sql_type, ) -if t.TYPE_CHECKING: - import pytest - logger = logging.getLogger("log") @@ -292,3 +292,29 @@ def test_conform_primitives(): assert _conform_primitive_property(None, {"type": "boolean"}) is None assert _conform_primitive_property(0, {"type": "boolean"}) is False assert _conform_primitive_property(1, {"type": "boolean"}) is True + + +@pytest.mark.parametrize( + "jsonschema_type,expected", + [ + ({"type": ["string", "null"]}, sqlalchemy.types.VARCHAR), + ({"type": ["integer", "null"]}, sqlalchemy.types.INTEGER), + ({"type": ["number", "null"]}, sqlalchemy.types.DECIMAL), + ({"type": ["boolean", "null"]}, sqlalchemy.types.BOOLEAN), + ({"type": "object", "properties": {}}, sqlalchemy.types.VARCHAR), + ({"type": "array"}, sqlalchemy.types.VARCHAR), + ({"format": "date", "type": ["string", "null"]}, sqlalchemy.types.DATE), + ({"format": "time", "type": ["string", "null"]}, sqlalchemy.types.TIME), + ( + {"format": "date-time", "type": ["string", "null"]}, + sqlalchemy.types.DATETIME, + ), + ( + {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}]}, + sqlalchemy.types.DATETIME, + ), + ({"anyOf": [{"type": "integer"}, {"type": "null"}]}, sqlalchemy.types.INTEGER), + ], +) +def test_to_sql_type(jsonschema_type, expected): + assert isinstance(to_sql_type(jsonschema_type), expected) diff --git a/tests/samples/test_tap_countries.py b/tests/samples/test_tap_countries.py index f822f5c8b..e1910d0cb 100644 --- a/tests/samples/test_tap_countries.py +++ b/tests/samples/test_tap_countries.py @@ -9,6 +9,9 @@ import typing as t from contextlib import redirect_stdout +import pytest +from click.testing import CliRunner + from samples.sample_tap_countries.countries_tap import SampleTapCountries from singer_sdk.helpers._catalog import ( get_selected_schema, @@ -17,6 +20,11 @@ from singer_sdk.testing import get_tap_test_class from singer_sdk.testing.config import SuiteConfig +if t.TYPE_CHECKING: + from pathlib import Path + + from pytest_snapshot.plugin import Snapshot + SAMPLE_CONFIG = {} SAMPLE_CONFIG_BAD = {"not": "correct"} @@ -136,3 +144,17 @@ def tally_messages(messages: list) -> t.Counter: assert counter["BATCH", "countries"] == 1 assert counter[("STATE",)] == 3 + + +@pytest.mark.snapshot() +def test_write_schema( + snapshot: Snapshot, + snapshot_dir: Path, +): + snapshot.snapshot_dir = snapshot_dir.joinpath("countries_write_schemas") + + runner = CliRunner(mix_stderr=False) + result = runner.invoke(SampleTapCountries.cli, ["--test", "schema"]) + + snapshot_name = "countries_write_schemas" + snapshot.assert_match(result.stdout, snapshot_name) diff --git a/tests/samples/test_target_csv.py b/tests/samples/test_target_csv.py index 54f50fc38..715edbb65 100644 --- a/tests/samples/test_target_csv.py +++ b/tests/samples/test_target_csv.py @@ -14,9 +14,6 @@ from samples.sample_mapper.mapper import StreamTransform from samples.sample_tap_countries.countries_tap import SampleTapCountries from samples.sample_target_csv.csv_target import SampleTargetCSV -from singer_sdk import typing as th -from singer_sdk.sinks import BatchSink -from singer_sdk.target_base import Target from singer_sdk.testing import ( get_target_test_class, sync_end_to_end, @@ -24,6 +21,7 @@ tap_to_target_sync_test, target_sync_test, ) +from tests.conftest import TargetMock TEST_OUTPUT_DIR = Path(f".output/test_{uuid.uuid4()}/") SAMPLE_CONFIG = {"target_folder": f"{TEST_OUTPUT_DIR}/"} @@ -55,54 +53,6 @@ def resource(self, test_output_dir): } -class BatchSinkMock(BatchSink): - """A mock Sink class.""" - - name = "batch-sink-mock" - - def __init__( - self, - target: TargetMock, - stream_name: str, - schema: dict, - key_properties: list[str] | None, - ): - """Create the Mock batch-based sink.""" - super().__init__(target, stream_name, schema, key_properties) - self.target = target - - def process_record(self, record: dict, context: dict) -> None: - """Tracks the count of processed records.""" - self.target.num_records_processed += 1 - super().process_record(record, context) - - def process_batch(self, context: dict) -> None: - """Write to mock trackers.""" - self.target.records_written.extend(context["records"]) - self.target.num_batches_processed += 1 - - -class TargetMock(Target): - """A mock Target class.""" - - name = "target-mock" - config_jsonschema = th.PropertiesList().to_dict() - default_sink_class = BatchSinkMock - - def __init__(self): - """Create the Mock target sync.""" - super().__init__(config={}) - self.state_messages_written: list[dict] = [] - self.records_written: list[dict] = [] - self.num_records_processed: int = 0 - self.num_batches_processed: int = 0 - - def _write_state_message(self, state: dict): - """Emit the stream's latest state.""" - super()._write_state_message(state) - self.state_messages_written.append(state) - - def test_countries_to_csv(csv_config: dict): tap = SampleTapCountries(config=SAMPLE_TAP_CONFIG, state=None) target = SampleTargetCSV(config=csv_config) @@ -133,7 +83,7 @@ def test_target_batching(): countries_record_count = 257 with freeze_time(mocked_starttime): - target = TargetMock() + target = TargetMock(config={}) target.max_parallelism = 1 # Limit unit test to 1 process assert target.num_records_processed == 0 assert len(target.records_written) == 0 diff --git a/tests/snapshots/countries_write_schemas/countries_write_schemas b/tests/snapshots/countries_write_schemas/countries_write_schemas new file mode 100644 index 000000000..b0808ce23 --- /dev/null +++ b/tests/snapshots/countries_write_schemas/countries_write_schemas @@ -0,0 +1,2 @@ +{"type": "SCHEMA", "stream": "continents", "schema": {"properties": {"code": {"type": ["null", "string"]}, "name": {"type": ["null", "string"]}}, "type": "object"}, "key_properties": ["code"]} +{"type": "SCHEMA", "stream": "countries", "schema": {"properties": {"code": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]}, "native": {"type": ["string", "null"]}, "phone": {"type": ["string", "null"]}, "capital": {"type": ["string", "null"]}, "currency": {"type": ["string", "null"]}, "emoji": {"type": ["string", "null"]}, "continent": {"properties": {"code": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]}}, "type": ["object", "null"]}, "languages": {"items": {"properties": {"code": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]}}, "type": "object"}, "type": ["array", "null"]}}, "type": "object"}, "key_properties": ["code"]}