From 0e2df68fcc9e90823fd6a3dedad002da1e9f7404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:09:25 -0600 Subject: [PATCH 01/12] docs: Reference `get_starting_timestamp` in incremental replication guide (#2629) * docs: Reference `get_starting_timestamp` in incremental replication guide * Use correct paren * Add comma --- docs/incremental_replication.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/incremental_replication.md b/docs/incremental_replication.md index 757f15802..085f20afc 100644 --- a/docs/incremental_replication.md +++ b/docs/incremental_replication.md @@ -38,6 +38,7 @@ class CommentsStream(RESTStream): 3. Last, we have to adapt the query to the remote system, in this example by adding a query parameter with the ISO timestamp. + The [`get_starting_timestamp`](singer_sdk.Stream.get_starting_timestamp) method and the related [`get_starting_replication_key_value`](singer_sdk.Stream.get_starting_replication_key_value) method, are provided by the SDK and return the last replication key value seen in the previous run. If the tap is run for the first time and the value for the `start_date` setting is null, the method will return `None`. ```{note} - The SDK will throw an error if records come out of order when `is_sorted` is true. From 190a9e6d1867a0fd32c137e442addd91b852e15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:41:40 -0600 Subject: [PATCH 02/12] ci: Use `include-hidden-files: true` to upload coverage artifacts (#2638) --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3acc509fb..cf0602a29 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -99,6 +99,7 @@ jobs: - uses: actions/upload-artifact@v4 if: always() && (matrix.session == 'tests') with: + include-hidden-files: true name: coverage-data-nox_${{ matrix.session }}-${{ matrix.os }}-py${{ matrix.python-version }}_sqlalchemy_${{ matrix.sqlalchemy }} path: ".coverage.*" From 984b2cd3edc82e2bec4af56e4510f7c4c63b572d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:51:14 -0600 Subject: [PATCH 03/12] docs: Documented versions where `fake` and `Faker` objects were added to the stream maps context (#2639) --- docs/stream_maps.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/stream_maps.md b/docs/stream_maps.md index 9d4a7d8a3..94d9ac72a 100644 --- a/docs/stream_maps.md +++ b/docs/stream_maps.md @@ -253,9 +253,17 @@ can be referenced directly by mapping expressions. masking by allowing users to call `Faker.seed()`. ```{tip} - The `fake` object is only available if the plugin specifies `faker` as an additional dependency (through the `singer-sdk` `faker` extra, or directly). + The `fake` object and `Faker` are only available if the plugin specifies `faker` as an additional dependency (through the `singer-sdk` `faker` extra, or directly). ``` +:::{versionadded} 0.35.0 +The `faker` object. +::: + +:::{versionadded} 0.40.0 +The `Faker` class. +::: + #### Automatic Schema Detection For performance reasons, type detection is performed at runtime using text analysis From aaed6c7d0898840e443f56761d24b98ef259241d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:56:28 -0600 Subject: [PATCH 04/12] packaging: Remove upper constraint on `faker` extra (#2640) --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index e80a8ace3..36101c0b0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -642,13 +642,13 @@ test = ["pytest (>=6)"] [[package]] name = "faker" -version = "28.0.0" +version = "28.1.0" description = "Faker is a Python package that generates fake data for you." optional = true python-versions = ">=3.8" files = [ - {file = "Faker-28.0.0-py3-none-any.whl", hash = "sha256:6a3a08be54c37e05f7943d7ba5211d252c1de737687a46ad6f29209d8d5db11f"}, - {file = "faker-28.0.0.tar.gz", hash = "sha256:0d3c0399204aaf8205cc1750db443474ca0436f177126b2c27b798e8336cc74f"}, + {file = "Faker-28.1.0-py3-none-any.whl", hash = "sha256:b17d69312ef6485a720e21bffa997668c88876a5298b278e903ba706243c9c6b"}, + {file = "faker-28.1.0.tar.gz", hash = "sha256:bc460a0e6020966410d0b276043879abca0fac51890f3324bc254bb0a383ee3a"}, ] [package.dependencies] @@ -2592,4 +2592,4 @@ testing = ["pytest"] [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "cdb61b3c2edc05495046425e778c37240b7035bbed822153ec4d5c38c8e54d57" +content-hash = "34a80dcb1e59005ff2d6e534b2fed2cf683cf8c0b4a54ce5af6e779cf07090d0" diff --git a/pyproject.toml b/pyproject.toml index b79ae3615..bde6e8519 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -90,7 +90,7 @@ pyarrow = { version = ">=13", optional = true } pytest = {version=">=7.2.1", optional = true} # installed as optional 'faker' extra -faker = {version = ">=22.5,<29.0", optional = true} +faker = {version = ">=22.5", optional = true} # Crypto extras cryptography = { version = ">=3.4.6", optional = true } From baefbe02a226eb6b615fce4d875e75fede48a385 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:57:02 -0600 Subject: [PATCH 05/12] chore(deps): bump pypa/gh-action-pypi-publish from 1.9.0 to 1.10.0 in the actions group (#2636) chore(deps): bump pypa/gh-action-pypi-publish in the actions group Bumps the actions group with 1 update: [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish). Updates `pypa/gh-action-pypi-publish` from 1.9.0 to 1.10.0 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cfb5ac75e..3974249d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,7 +65,7 @@ jobs: name: Packages path: dist - name: Publish - uses: pypa/gh-action-pypi-publish@v1.9.0 + uses: pypa/gh-action-pypi-publish@v1.10.0 upload-to-release: name: Upload files to release From 1f8d471c4fc0389bc66a7f5bd33774e1d1929d15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:57:23 -0600 Subject: [PATCH 06/12] chore(deps-dev): bump deptry from 0.19.1 to 0.20.0 in the development-dependencies group (#2634) chore(deps-dev): bump deptry in the development-dependencies group Bumps the development-dependencies group with 1 update: [deptry](https://github.com/fpgmaas/deptry). Updates `deptry` from 0.19.1 to 0.20.0 - [Release notes](https://github.com/fpgmaas/deptry/releases) - [Changelog](https://github.com/fpgmaas/deptry/blob/main/CHANGELOG.md) - [Commits](https://github.com/fpgmaas/deptry/compare/0.19.1...0.20.0) --- updated-dependencies: - dependency-name: deptry dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index 36101c0b0..cbe1d81a5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -520,23 +520,23 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deptry" -version = "0.19.1" +version = "0.20.0" description = "A command line utility to check for unused, missing and transitive dependencies in a Python project." optional = false python-versions = ">=3.8" files = [ - {file = "deptry-0.19.1-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:3a20ef0dd1c737fb05553d1b9c2fa9f185d0c9d3d881d255334cef401ffdc599"}, - {file = "deptry-0.19.1-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:2c6b2df353e5113fd2f787c2f7e694657548d388929e988e8644bd178e19fc5c"}, - {file = "deptry-0.19.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a407bab3486e3844f93d702f1a381942873b2a46056c693b5634bbde219bb056"}, - {file = "deptry-0.19.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43f33789b97b47313609e92b62fabf8a71bba0d35a7476806da5d3d152e32345"}, - {file = "deptry-0.19.1-cp38-abi3-win_amd64.whl", hash = "sha256:0bad85a77b31360d0f52383b14783fdae4a201b597c0158fe10e91a779c67079"}, - {file = "deptry-0.19.1-cp38-abi3-win_arm64.whl", hash = "sha256:c59142d9dca8873325692fbb7aa1d2902fde87020dcc8102f75120ba95515172"}, - {file = "deptry-0.19.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1abc119f9c8536b8ab1ee2122d4130665f33225d00d8615256ce354eb2c11ba"}, - {file = "deptry-0.19.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7344c6cea032b549d86e156aa1e679fb94cd44deb7e93f25cb6d9c0ded5ea06f"}, - {file = "deptry-0.19.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff7d8954265c48ea334fdd508339c51d3fba05e2d4a8be47712c69d1c8d35c94"}, - {file = "deptry-0.19.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:023073247e5dac21254bf7b600ca2e2b71560652d2dfbe11535445ee912ca059"}, - {file = "deptry-0.19.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:af8a0a9c42f8f92dfbc048e724fa89b9131f032f7e245812260560c214395abf"}, - {file = "deptry-0.19.1.tar.gz", hash = "sha256:1c12fea1d2301f42c7035c5636e4b9421457fde256fe7a241245662d20b4c841"}, + {file = "deptry-0.20.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:41434d95124851b83cb05524d1a09ad6fea62006beafed2ef90a6b501c1b237f"}, + {file = "deptry-0.20.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:b3b4b22d1406147de5d606a24042126cd74d52fdfdb0232b9c5fd0270d601610"}, + {file = "deptry-0.20.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012fb106dbea6ca95196cdcd75ac90c516c8f01292f7934f2e802a7cf025a660"}, + {file = "deptry-0.20.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ce3920e2bd6d2b4427ab31ab8efb94bbef897001c2d395782bc30002966d12d"}, + {file = "deptry-0.20.0-cp38-abi3-win_amd64.whl", hash = "sha256:0c90ce64e637d0e902bc97c5a020adecfee9e9f09ee0bf4c61554994139bebdb"}, + {file = "deptry-0.20.0-cp38-abi3-win_arm64.whl", hash = "sha256:6886ff44aaf26fd83093f14f844ebc84589d90df9bbad9a1625e8a080e6f1be2"}, + {file = "deptry-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ace3b39b1d0763f357c79bab003d1b135bea2eb61102be539992621a42d1ac7b"}, + {file = "deptry-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d1a00f8c9e6c0829a4a523edd5e526e3df06d2b50e0a99446f09f9723df2efad"}, + {file = "deptry-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e233859f150df70ffff76e95f9b7326fc25494b9beb26e776edae20f0f515e7d"}, + {file = "deptry-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f92e7e97ef42477717747b190bc6796ab94b35655af126d8c577f7eae0eb3a9"}, + {file = "deptry-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f6cee6005997791bb77155667be055333fb63ae9a24f0f103f25faf1e7affe34"}, + {file = "deptry-0.20.0.tar.gz", hash = "sha256:62e9aaf3aea9e2ca66c85da98a0ba0290b4d3daea4e1d0ad937d447bd3c36402"}, ] [package.dependencies] From 5d53b18d44fa5efdd19d171771ba0e9fb8ad03cf Mon Sep 17 00:00:00 2001 From: MeltyBot <105875157+MeltyBot@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:44:55 -0400 Subject: [PATCH 07/12] chore: Release v0.40.0 (#2633) chore: Bump package version Co-authored-by: edgarrmondragon <16805946+edgarrmondragon@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- CHANGELOG.md | 34 +++++++++++++++++++ .../{{cookiecutter.mapper_id}}/pyproject.toml | 4 +-- .../{{cookiecutter.tap_id}}/pyproject.toml | 6 ++-- .../{{cookiecutter.target_id}}/pyproject.toml | 4 +-- docs/conf.py | 2 +- pyproject.toml | 2 +- 7 files changed, 44 insertions(+), 10 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 79c4b98d1..222eff237 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -13,7 +13,7 @@ body: attributes: label: Singer SDK Version description: Version of the library you are using - placeholder: "0.39.1" + placeholder: "0.40.0" validations: required: true - type: checkboxes diff --git a/CHANGELOG.md b/CHANGELOG.md index 27d538a6d..46715c382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v0.40.0 (2024-09-02) + +### ✨ New + +- [#2486](https://github.com/meltano/sdk/issues/2486) Emit target metrics +- [#2567](https://github.com/meltano/sdk/issues/2567) A new `schema_is_valid` built-in tap test validates stream schemas against the JSON Schema specification +- [#2598](https://github.com/meltano/sdk/issues/2598) Stream map expressions now have access to the `Faker` class, rather than just a faker instance +- [#2549](https://github.com/meltano/sdk/issues/2549) Added a default user agent for REST and GraphQL taps + +### 🐛 Fixes + +- [#2613](https://github.com/meltano/sdk/issues/2613) Mismatch between timezone-aware and naive datetimes in start date and bookmarks is now correctly handled + +### ⚙️ Under the Hood + +- [#2628](https://github.com/meltano/sdk/issues/2628) Use context manager to read gzip batch files +- [#2619](https://github.com/meltano/sdk/issues/2619) Default to UTC when parsing dates without a known timezone +- [#2603](https://github.com/meltano/sdk/issues/2603) Backwards-compatible identifier quoting in fully qualified names +- [#2601](https://github.com/meltano/sdk/issues/2601) Improved SQL identifier (de)normalization +- [#2599](https://github.com/meltano/sdk/issues/2599) Remove `pytest-durations` dependency from `testing` and use native pytest option `--durations` +- [#2597](https://github.com/meltano/sdk/issues/2597) Mark pagination classes with `@override` decorator +- [#2596](https://github.com/meltano/sdk/issues/2596) Made `auth_headers` and `auth_params` of `APIAuthenticatorBase` simple instance attributes instead of decorated properties + +### 📚 Documentation Improvements + +- [#2639](https://github.com/meltano/sdk/issues/2639) Documented versions where `fake` and `Faker` objects were added to the stream maps context +- [#2629](https://github.com/meltano/sdk/issues/2629) Reference `get_starting_timestamp` in incremental replication guide +- [#2604](https://github.com/meltano/sdk/issues/2604) Update project sample links +- [#2595](https://github.com/meltano/sdk/issues/2595) Documented examples of stream glob expressions and property aliasing + +### 📦 Packaging changes + +- [#2640](https://github.com/meltano/sdk/issues/2640) Remove upper constraint on `faker` extra + ## v0.39.1 (2024-08-07) ### 🐛 Fixes diff --git a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml index e77cf5346..b397face4 100644 --- a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml +++ b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/pyproject.toml @@ -31,12 +31,12 @@ packages = [ [tool.poetry.dependencies] python = ">=3.8" -singer-sdk = { version="~=0.39.1"{{ ', extras = ["faker"]' if cookiecutter.faker_extra }} } +singer-sdk = { version="~=0.40.0"{{ ', extras = ["faker"]' if cookiecutter.faker_extra }} } fs-s3fs = { version = "~=1.1.1", optional = true } [tool.poetry.group.dev.dependencies] pytest = ">=8" -singer-sdk = { version="~=0.39.1", extras = ["testing"] } +singer-sdk = { version="~=0.40.0", extras = ["testing"] } [tool.poetry.extras] s3 = ["fs-s3fs"] diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml index 98851d925..3037bcabf 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml @@ -31,7 +31,7 @@ packages = [ [tool.poetry.dependencies] python = ">=3.8" importlib-resources = { version = "==6.4.*", python = "<3.9" } -singer-sdk = { version="~=0.39.1", extras = [ +singer-sdk = { version="~=0.40.0", extras = [ {%- if cookiecutter.auth_method == "JWT" -%}"jwt", {% endif -%} {%- if cookiecutter.faker_extra -%}"faker",{%- endif -%} ] } @@ -43,9 +43,9 @@ requests = "~=2.32.3" [tool.poetry.group.dev.dependencies] pytest = ">=8" {%- if cookiecutter.auth_method == "JWT" %} -singer-sdk = { version="~=0.39.1", extras = ["jwt", "testing"] } +singer-sdk = { version="~=0.40.0", extras = ["jwt", "testing"] } {%- else %} -singer-sdk = { version="~=0.39.1", extras = ["testing"] } +singer-sdk = { version="~=0.40.0", extras = ["testing"] } {%- endif %} [tool.poetry.extras] diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml b/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml index 5aa268f7c..42d71ae99 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml @@ -30,7 +30,7 @@ packages = [ [tool.poetry.dependencies] python = ">=3.8" -singer-sdk = { version="~=0.39.1"{{ ', extras = ["faker"]' if cookiecutter.faker_extra }} } +singer-sdk = { version="~=0.40.0"{{ ', extras = ["faker"]' if cookiecutter.faker_extra }} } fs-s3fs = { version = "~=1.1.1", optional = true } {%- if cookiecutter.serialization_method != "SQL" %} requests = "~=2.32.3" @@ -38,7 +38,7 @@ requests = "~=2.32.3" [tool.poetry.dev-dependencies] pytest = ">=8" -singer-sdk = { version="~=0.39.1", extras = ["testing"] } +singer-sdk = { version="~=0.40.0", extras = ["testing"] } [tool.poetry.extras] s3 = ["fs-s3fs"] diff --git a/docs/conf.py b/docs/conf.py index 447549f24..fec62280e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -29,7 +29,7 @@ author = "Meltano Core Team and Contributors" # The full version, including alpha/beta/rc tags -release = "0.39.1" +release = "0.40.0" # -- General configuration ------------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index bde6e8519..3d4d12787 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -177,7 +177,7 @@ norecursedirs = "cookiecutter" [tool.commitizen] name = "cz_version_bump" -version = "0.39.1" +version = "0.40.0" changelog_merge_prerelease = true prerelease_offset = 1 tag_format = "v$major.$minor.$patch$prerelease" From 640e00b97cba8fb7494253d2fe027c88d20da1d4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 16:18:42 -0600 Subject: [PATCH 08/12] chore: pre-commit autoupdate (#2642) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.2 → v0.6.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.2...v0.6.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 587f7a213..7a04798f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -50,7 +50,7 @@ repos: - id: check-readthedocs - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.2 + rev: v0.6.3 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] From 63cc0a3e9a483e599a9f87514c68db7458126ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:57:49 -0600 Subject: [PATCH 09/12] chore: Apply repo-review to this project (#2645) Applied `pipx run 'sp-repo-review[cli]' .` to this proejct. --- pyproject.toml | 17 +++++++++++++++-- singer_sdk/_singerlib/encoding/_simple.py | 4 ++-- singer_sdk/authenticators.py | 12 ++++++------ singer_sdk/connectors/sql.py | 4 ++-- singer_sdk/helpers/_batch.py | 2 +- singer_sdk/helpers/_catalog.py | 4 ++-- singer_sdk/helpers/_state.py | 2 +- singer_sdk/mapper.py | 10 ++++------ singer_sdk/plugin_base.py | 2 +- singer_sdk/streams/core.py | 4 ++-- singer_sdk/streams/graphql.py | 2 +- singer_sdk/tap_base.py | 4 ++-- singer_sdk/testing/legacy.py | 2 +- singer_sdk/testing/tap_tests.py | 4 ++-- singer_sdk/typing.py | 9 +++------ 15 files changed, 45 insertions(+), 37 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3d4d12787..d13255b57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,7 +146,15 @@ types-PyYAML = ">=6.0.12" pytest-codspeed = ">=2.2.0" [tool.pytest.ini_options] -addopts = '--durations=10 --ignore=singer_sdk/helpers/_simpleeval.py -m "not external"' +addopts = [ + "--durations=10", + "--ignore=singer_sdk/helpers/_simpleeval.py", + "-m", + "not external", + "-ra", + "--strict-config", + "--strict-markers", +] filterwarnings = [ "error", "ignore:Could not configure external gitlab tests:UserWarning", @@ -167,13 +175,16 @@ filterwarnings = [ # https://github.com/joblib/joblib/pull/1518 "ignore:Attribute n is deprecated:DeprecationWarning:joblib._utils", ] +log_cli_level = "INFO" markers = [ "external: Tests relying on external resources", "windows: Tests that only run on Windows", "snapshot: Tests that use pytest-snapshot", ] +minversion = "7" testpaths = ["tests"] norecursedirs = "cookiecutter" +xfail_strict = false [tool.commitizen] name = "cz_version_bump" @@ -257,11 +268,14 @@ DEP002 = [ ] [tool.mypy] +enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] exclude = "tests" files = "singer_sdk" local_partial_types = true +strict = false warn_redundant_casts = true warn_return_any = true +warn_unreachable = true warn_unused_configs = true warn_unused_ignores = true @@ -295,7 +309,6 @@ extend-exclude = [ "*simpleeval*", ] line-length = 88 -src = ["samples", "singer_sdk", "tests"] target-version = "py38" [tool.ruff.format] diff --git a/singer_sdk/_singerlib/encoding/_simple.py b/singer_sdk/_singerlib/encoding/_simple.py index 7ce148fc3..5c8fec549 100644 --- a/singer_sdk/_singerlib/encoding/_simple.py +++ b/singer_sdk/_singerlib/encoding/_simple.py @@ -161,9 +161,9 @@ def __post_init__(self) -> None: self.type = SingerMessageType.SCHEMA if isinstance(self.bookmark_properties, (str, bytes)): - self.bookmark_properties = [self.bookmark_properties] + self.bookmark_properties = [self.bookmark_properties] # type: ignore[unreachable] if self.bookmark_properties and not isinstance(self.bookmark_properties, list): - msg = "bookmark_properties must be a string or list of strings" + msg = "bookmark_properties must be a string or list of strings" # type: ignore[unreachable] raise ValueError(msg) diff --git a/singer_sdk/authenticators.py b/singer_sdk/authenticators.py index c6478cb92..4c15304e5 100644 --- a/singer_sdk/authenticators.py +++ b/singer_sdk/authenticators.py @@ -71,7 +71,7 @@ def __call__(cls, *args: t.Any, **kwargs: t.Any) -> t.Any: # noqa: ANN401 A singleton instance of the derived class. """ if cls.__single_instance: - return cls.__single_instance + return cls.__single_instance # type: ignore[unreachable] single_obj = cls.__new__(cls, None) # type: ignore[call-overload] single_obj.__init__(*args, **kwargs) cls.__single_instance = single_obj @@ -165,7 +165,7 @@ def __init__( """ super().__init__(stream=stream) if self.auth_headers is None: - self.auth_headers = {} + self.auth_headers = {} # type: ignore[unreachable] if auth_headers: self.auth_headers.update(auth_headers) @@ -206,11 +206,11 @@ def __init__( if location == "header": if self.auth_headers is None: - self.auth_headers = {} + self.auth_headers = {} # type: ignore[unreachable] self.auth_headers.update(auth_credentials) elif location == "params": if self.auth_params is None: - self.auth_params = {} + self.auth_params = {} # type: ignore[unreachable] self.auth_params.update(auth_credentials) @classmethod @@ -255,7 +255,7 @@ def __init__(self, stream: RESTStream, token: str) -> None: auth_credentials = {"Authorization": f"Bearer {token}"} if self.auth_headers is None: - self.auth_headers = {} + self.auth_headers = {} # type: ignore[unreachable] self.auth_headers.update(auth_credentials) @classmethod @@ -314,7 +314,7 @@ def __init__( auth_credentials = {"Authorization": f"Basic {auth_token}"} if self.auth_headers is None: - self.auth_headers = {} + self.auth_headers = {} # type: ignore[unreachable] self.auth_headers.update(auth_credentials) @classmethod diff --git a/singer_sdk/connectors/sql.py b/singer_sdk/connectors/sql.py index b6a74a976..c9f18cbf3 100644 --- a/singer_sdk/connectors/sql.py +++ b/singer_sdk/connectors/sql.py @@ -496,7 +496,7 @@ def discover_catalog_entry( # Detect key properties possible_primary_keys: list[list[str]] = [] pk_def = inspected.get_pk_constraint(table_name, schema=schema_name) - if pk_def and "constrained_columns" in pk_def: + if pk_def and "constrained_columns" in pk_def: # type: ignore[redundant-expr] possible_primary_keys.append(pk_def["constrained_columns"]) # An element of the columns list is ``None`` if it's an expression and is @@ -953,7 +953,7 @@ def merge_sql_types( # Get the generic type class for opt in sql_types: # Get the length - opt_len: int = getattr(opt, "length", 0) + opt_len: int | None = getattr(opt, "length", 0) generic_type = type(opt.as_generic()) if isinstance(generic_type, type): diff --git a/singer_sdk/helpers/_batch.py b/singer_sdk/helpers/_batch.py index b57002e1d..2e4ae4615 100644 --- a/singer_sdk/helpers/_batch.py +++ b/singer_sdk/helpers/_batch.py @@ -232,7 +232,7 @@ def __post_init__(self) -> None: self.storage = StorageTarget.from_dict(self.storage) if self.batch_size is None: - self.batch_size = DEFAULT_BATCH_SIZE + self.batch_size = DEFAULT_BATCH_SIZE # type: ignore[unreachable] def asdict(self) -> dict[str, t.Any]: """Return a dictionary representation of the message. diff --git a/singer_sdk/helpers/_catalog.py b/singer_sdk/helpers/_catalog.py index 90eec4c5e..a8747d30c 100644 --- a/singer_sdk/helpers/_catalog.py +++ b/singer_sdk/helpers/_catalog.py @@ -43,7 +43,7 @@ def _pop_deselected_schema( schema_at_breadcrumb = schema_at_breadcrumb.get(crumb, {}) if not isinstance(schema_at_breadcrumb, dict): # pragma: no cover - msg = ( + msg = ( # type: ignore[unreachable] "Expected dictionary type instead of " f"'{type(schema_at_breadcrumb).__name__}' '{schema_at_breadcrumb}' for " f"'{stream_name}' bookmark '{breadcrumb!s}' in '{schema}'" @@ -123,7 +123,7 @@ def set_catalog_stream_selected( """ breadcrumb = breadcrumb or () if not isinstance(breadcrumb, tuple): # pragma: no cover - msg = ( + msg = ( # type: ignore[unreachable] f"Expected tuple value for breadcrumb '{breadcrumb}'. Got " f"{type(breadcrumb).__name__}" ) diff --git a/singer_sdk/helpers/_state.py b/singer_sdk/helpers/_state.py index a910bb71e..fd7dee377 100644 --- a/singer_sdk/helpers/_state.py +++ b/singer_sdk/helpers/_state.py @@ -118,7 +118,7 @@ def get_writeable_state_dict( ValueError: Raise an error if duplicate entries are found. """ if tap_state is None: - msg = "Cannot write state to missing state dictionary." + msg = "Cannot write state to missing state dictionary." # type: ignore[unreachable] raise ValueError(msg) if "bookmarks" not in tap_state: diff --git a/singer_sdk/mapper.py b/singer_sdk/mapper.py index a2e7bc956..0214fe9e9 100644 --- a/singer_sdk/mapper.py +++ b/singer_sdk/mapper.py @@ -377,7 +377,7 @@ def _eval_type( ValueError: If the expression is ``None``. """ if expr is None: - msg = "Expression should be str, not None" + msg = "Expression should be str, not None" # type: ignore[unreachable] raise ValueError(msg) default = default or th.StringType() @@ -564,7 +564,7 @@ def always_true(record: dict) -> bool: elif filter_rule is None: filter_fn = always_true else: - msg = ( + msg = ( # type: ignore[unreachable] f"Unexpected filter rule type '{type(filter_rule).__name__}' in " f"expression {filter_rule!s}. Expected 'str' or 'None'." ) @@ -783,9 +783,7 @@ def register_raw_stream_schema( # noqa: PLR0912, C901 key_properties=key_properties, flattening_options=self.flattening_options, ) - elif stream_def is None or ( - isinstance(stream_def, str) and stream_def == NULL_STRING - ): + elif stream_def is None or (stream_def == NULL_STRING): mapper = RemoveRecordTransform( stream_alias=stream_alias, raw_schema=schema, @@ -800,7 +798,7 @@ def register_raw_stream_schema( # noqa: PLR0912, C901 raise StreamMapConfigError(msg) else: - msg = ( + msg = ( # type: ignore[unreachable] f"Unexpected stream definition type. Expected str, dict, or None. " f"Got '{type(stream_def).__name__}'." ) diff --git a/singer_sdk/plugin_base.py b/singer_sdk/plugin_base.py index eb5b39de3..ed37bfb3f 100644 --- a/singer_sdk/plugin_base.py +++ b/singer_sdk/plugin_base.py @@ -153,7 +153,7 @@ def __init__( elif isinstance(config, dict): config_dict = config else: - msg = f"Error parsing config of type '{type(config).__name__}'." + msg = f"Error parsing config of type '{type(config).__name__}'." # type: ignore[unreachable] raise ValueError(msg) if parse_env_config: self.logger.info("Parsing env var for settings config...") diff --git a/singer_sdk/streams/core.py b/singer_sdk/streams/core.py index 51a968313..e65f577f2 100644 --- a/singer_sdk/streams/core.py +++ b/singer_sdk/streams/core.py @@ -162,7 +162,7 @@ def __init__( elif isinstance(schema, singer.Schema): self._schema = schema.to_dict() else: - msg = f"Unexpected type {type(schema).__name__} for arg 'schema'." + msg = f"Unexpected type {type(schema).__name__} for arg 'schema'." # type: ignore[unreachable] raise ValueError(msg) if self.schema_filepath: @@ -187,7 +187,7 @@ def stream_maps(self) -> list[StreamMap]: if self._stream_maps: return self._stream_maps - if self._tap.mapper: + if self._tap.mapper: # type: ignore[truthy-bool] self._stream_maps = self._tap.mapper.stream_maps[self.name] self.logger.info( "Tap has custom mapper. Using %d provided map(s).", diff --git a/singer_sdk/streams/graphql.py b/singer_sdk/streams/graphql.py index 4e5455bc3..22a5fb0cc 100644 --- a/singer_sdk/streams/graphql.py +++ b/singer_sdk/streams/graphql.py @@ -71,7 +71,7 @@ def prepare_request_payload( query = self.query if query is None: - msg = "Graphql `query` property not set." + msg = "Graphql `query` property not set." # type: ignore[unreachable] raise ValueError(msg) if not query.lstrip().startswith("query"): diff --git a/singer_sdk/tap_base.py b/singer_sdk/tap_base.py index d69fa5f38..d246a2790 100644 --- a/singer_sdk/tap_base.py +++ b/singer_sdk/tap_base.py @@ -148,7 +148,7 @@ def state(self) -> dict: RuntimeError: If state has not been initialized. """ if self._state is None: - msg = "Could not read from uninitialized state." + msg = "Could not read from uninitialized state." # type: ignore[unreachable] raise RuntimeError(msg) return self._state @@ -398,7 +398,7 @@ def load_state(self, state: dict[str, t.Any]) -> None: initialized. """ if self.state is None: - msg = "Cannot write to uninitialized state dictionary." + msg = "Cannot write to uninitialized state dictionary." # type: ignore[unreachable] raise ValueError(msg) for stream_name, stream_state in state.get("bookmarks", {}).items(): diff --git a/singer_sdk/testing/legacy.py b/singer_sdk/testing/legacy.py index a47d3e770..eae4c5b5d 100644 --- a/singer_sdk/testing/legacy.py +++ b/singer_sdk/testing/legacy.py @@ -40,7 +40,7 @@ def _test_discovery() -> None: catalog1 = _get_tap_catalog(tap_class, config or {}) # Reset and re-initialize with an input catalog tap2: Tap = tap_class(config=config, parse_env_config=True, catalog=catalog1) - assert tap2 + assert tap2 # type: ignore[truthy-bool] def _test_stream_connections() -> None: # Initialize with basic config diff --git a/singer_sdk/testing/tap_tests.py b/singer_sdk/testing/tap_tests.py index 5839e0cea..92e0b13e1 100644 --- a/singer_sdk/testing/tap_tests.py +++ b/singer_sdk/testing/tap_tests.py @@ -48,7 +48,7 @@ def test(self) -> None: catalog=catalog, **kwargs, ) - assert tap2 + assert tap2 # type: ignore[truthy-bool] class TapStreamConnectionTest(TapTestTemplate): @@ -218,7 +218,7 @@ def test(self) -> None: try: for v in self.non_null_attribute_values: error_message = f"Unable to parse value ('{v}') with datetime parser." - assert datetime_fromisoformat(v), error_message + assert datetime_fromisoformat(v), error_message # type: ignore[truthy-bool] except ValueError as e: raise AssertionError(error_message) from e diff --git a/singer_sdk/typing.py b/singer_sdk/typing.py index 6bf8d9527..2910125f8 100644 --- a/singer_sdk/typing.py +++ b/singer_sdk/typing.py @@ -189,7 +189,7 @@ def __get__(self, instance: P, owner: type[P]) -> t.Any: # noqa: ANN401 The property value. """ if instance is None: - instance = owner() + instance = owner() # type: ignore[unreachable] return self.fget(instance) @@ -1123,13 +1123,10 @@ def to_jsonschema_type( type_name = from_type elif isinstance(from_type, sa.types.TypeEngine): type_name = type(from_type).__name__ - elif isinstance(from_type, type) and issubclass( - from_type, - sa.types.TypeEngine, - ): + elif issubclass(from_type, sa.types.TypeEngine): type_name = from_type.__name__ else: # pragma: no cover - msg = "Expected `str` or a SQLAlchemy `TypeEngine` object or type." + msg = "Expected `str` or a SQLAlchemy `TypeEngine` object or type." # type: ignore[unreachable] # TODO: this should be a TypeError, but it's a breaking change. raise ValueError(msg) # noqa: TRY004 From 93a079673104a636995be42349f51419f03a3a43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:03:28 -0600 Subject: [PATCH 10/12] chore(deps): bump cryptography from 43.0.0 to 43.0.1 (#2646) Bumps [cryptography](https://github.com/pyca/cryptography) from 43.0.0 to 43.0.1. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/43.0.0...43.0.1) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/poetry.lock b/poetry.lock index cbe1d81a5..453b391a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -471,38 +471,38 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "43.0.0" +version = "43.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = true python-versions = ">=3.7" files = [ - {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, - {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, - {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, - {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, - {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, - {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, - {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, + {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"}, + {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"}, + {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"}, + {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"}, + {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"}, + {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"}, + {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"}, + {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"}, + {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"}, + {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"}, + {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"}, + {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"}, + {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"}, ] [package.dependencies] @@ -515,7 +515,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] From e46a1cd9ffb05ea48a57597f648b371795ef05d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:12:51 -0600 Subject: [PATCH 11/12] refactor: Use future `warnings.deprecated` decorator (#2647) --- singer_sdk/authenticators.py | 17 +++++++++------- singer_sdk/connectors/sql.py | 34 +++++++++++++++++++------------- tests/core/test_connector_sql.py | 2 +- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/singer_sdk/authenticators.py b/singer_sdk/authenticators.py index 4c15304e5..3a7fd8833 100644 --- a/singer_sdk/authenticators.py +++ b/singer_sdk/authenticators.py @@ -5,8 +5,8 @@ import base64 import datetime import math +import sys import typing as t -import warnings from types import MappingProxyType from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit @@ -14,6 +14,11 @@ from singer_sdk.helpers._util import utc_now +if sys.version_info < (3, 13): + from typing_extensions import deprecated +else: + from warnings import deprecated + if t.TYPE_CHECKING: import logging @@ -277,6 +282,10 @@ def create_for_stream( return cls(stream=stream, token=token) +@deprecated( + "BasicAuthenticator is deprecated. Use requests.auth.HTTPBasicAuth instead.", + category=DeprecationWarning, +) class BasicAuthenticator(APIAuthenticatorBase): """Implements basic authentication for REST Streams. @@ -302,12 +311,6 @@ def __init__( password: API password. """ super().__init__(stream=stream) - warnings.warn( - "BasicAuthenticator is deprecated. Use " - "requests.auth.HTTPBasicAuth instead.", - DeprecationWarning, - stacklevel=2, - ) credentials = f"{username}:{password}".encode() auth_token = base64.b64encode(credentials).decode("ascii") diff --git a/singer_sdk/connectors/sql.py b/singer_sdk/connectors/sql.py index c9f18cbf3..c79c6308f 100644 --- a/singer_sdk/connectors/sql.py +++ b/singer_sdk/connectors/sql.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +import sys import typing as t import warnings from collections import UserString @@ -18,6 +19,11 @@ from singer_sdk.helpers._util import dump_json, load_json from singer_sdk.helpers.capabilities import TargetLoadMethods +if sys.version_info < (3, 13): + from typing_extensions import deprecated +else: + from warnings import deprecated + if t.TYPE_CHECKING: from sqlalchemy.engine import Engine from sqlalchemy.engine.reflection import Inspector @@ -161,6 +167,14 @@ def _connect(self) -> t.Iterator[sa.engine.Connection]: with self._engine.connect().execution_options(stream_results=True) as conn: yield conn + @deprecated( + "`SQLConnector.create_sqlalchemy_connection` is deprecated. " + "If you need to execute something that isn't available " + "on the connector currently, make a child class and " + "add your required method on that connector.", + category=DeprecationWarning, + stacklevel=1, + ) def create_sqlalchemy_connection(self) -> sa.engine.Connection: """(DEPRECATED) Return a new SQLAlchemy connection using the provided config. @@ -180,16 +194,14 @@ def create_sqlalchemy_connection(self) -> sa.engine.Connection: Returns: A newly created SQLAlchemy engine object. """ - warnings.warn( - "`SQLConnector.create_sqlalchemy_connection` is deprecated. " - "If you need to execute something that isn't available " - "on the connector currently, make a child class and " - "add your required method on that connector.", - DeprecationWarning, - stacklevel=2, - ) return self._engine.connect().execution_options(stream_results=True) + @deprecated( + "`SQLConnector.create_sqlalchemy_engine` is deprecated. Override " + "`_engine` or `sqlalchemy_url` instead.", + category=DeprecationWarning, + stacklevel=1, + ) def create_sqlalchemy_engine(self) -> Engine: """(DEPRECATED) Return a new SQLAlchemy engine using the provided config. @@ -199,12 +211,6 @@ def create_sqlalchemy_engine(self) -> Engine: Returns: A newly created SQLAlchemy engine object. """ - warnings.warn( - "`SQLConnector.create_sqlalchemy_engine` is deprecated. Override" - "`_engine` or sqlalchemy_url` instead.", - DeprecationWarning, - stacklevel=2, - ) return self._engine @property diff --git a/tests/core/test_connector_sql.py b/tests/core/test_connector_sql.py index c8390f33d..f37fb953b 100644 --- a/tests/core/test_connector_sql.py +++ b/tests/core/test_connector_sql.py @@ -156,7 +156,7 @@ def test_engine_creates_and_returns_cached_engine(self, connector): engine2 = connector._cached_engine assert engine1 is engine2 - def test_deprecated_functions_warn(self, connector): + def test_deprecated_functions_warn(self, connector: SQLConnector): with pytest.deprecated_call(): connector.create_sqlalchemy_engine() with pytest.deprecated_call(): From 778c35866bede100e43467496568b54bf21b9952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:23:11 -0600 Subject: [PATCH 12/12] chore(templates): update pre-commit hooks (#2649) --- .pre-commit-config.yaml | 2 +- .../{{cookiecutter.mapper_id}}/.pre-commit-config.yaml | 6 +++--- .../{{cookiecutter.tap_id}}/.pre-commit-config.yaml | 6 +++--- .../{{cookiecutter.target_id}}/.pre-commit-config.yaml | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7a04798f3..22a0b74c7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -50,7 +50,7 @@ repos: - id: check-readthedocs - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.3 + rev: v0.6.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] diff --git a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.pre-commit-config.yaml b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.pre-commit-config.yaml index 29308ec2d..9e35a5cbe 100644 --- a/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.pre-commit-config.yaml +++ b/cookiecutter/mapper-template/{{cookiecutter.mapper_id}}/.pre-commit-config.yaml @@ -18,19 +18,19 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.29.1 + rev: 0.29.2 hooks: - id: check-dependabot - id: check-github-workflows - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.6.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.1 + rev: v1.11.2 hooks: - id: mypy diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.pre-commit-config.yaml b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.pre-commit-config.yaml index ced959bcc..45093ce09 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.pre-commit-config.yaml +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/.pre-commit-config.yaml @@ -18,20 +18,20 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.29.1 + rev: 0.29.2 hooks: - id: check-dependabot - id: check-github-workflows - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.6.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.1 + rev: v1.11.2 hooks: - id: mypy additional_dependencies: diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/.pre-commit-config.yaml b/cookiecutter/target-template/{{cookiecutter.target_id}}/.pre-commit-config.yaml index 3cab6f92b..ee72f1515 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/.pre-commit-config.yaml +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/.pre-commit-config.yaml @@ -18,20 +18,20 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.29.1 + rev: 0.29.2 hooks: - id: check-dependabot - id: check-github-workflows - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.6 + rev: v0.6.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.1 + rev: v1.11.2 hooks: - id: mypy additional_dependencies: