diff --git a/.github/ISSUE_TEMPLATE/1-airflow_bug_report.yml b/.github/ISSUE_TEMPLATE/1-airflow_bug_report.yml
index 50b2399564e0d..acd51783cf80b 100644
--- a/.github/ISSUE_TEMPLATE/1-airflow_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/1-airflow_bug_report.yml
@@ -165,6 +165,7 @@ body:
- grpc
- hashicorp
- http
+ - ibm-db2
- ibm-mq
- imap
- influxdb
diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml
index e1535a247cec3..1801299ad8876 100644
--- a/.github/boring-cyborg.yml
+++ b/.github/boring-cyborg.yml
@@ -131,6 +131,8 @@ labelPRBasedOnFilePath:
provider:datadog:
- providers/datadog/**
+ provider:ibm-db2:
+ - providers/ibm/db2/**
provider:dbt-cloud:
- providers/dbt/cloud/**
diff --git a/airflow-core/docs/extra-packages-ref.rst b/airflow-core/docs/extra-packages-ref.rst
index b6617690de233..155403b045a38 100644
--- a/airflow-core/docs/extra-packages-ref.rst
+++ b/airflow-core/docs/extra-packages-ref.rst
@@ -345,6 +345,8 @@ Some of those enable Airflow to use executors to run tasks with them - other tha
+---------------------+-----------------------------------------------------+-----------------------------------------------------------------+----------------------------------------------+
| github | ``pip install 'apache-airflow[github]'`` | GitHub operators and hook | |
+---------------------+-----------------------------------------------------+-----------------------------------------------------------------+----------------------------------------------+
+| ibm-db2 | ``pip install 'apache-airflow[ibm-db2]'`` | IBM Db2 hook | |
++---------------------+-----------------------------------------------------+-----------------------------------------------------------------+----------------------------------------------+
| influxdb | ``pip install 'apache-airflow[influxdb]'`` | Influxdb operators and hook | |
+---------------------+-----------------------------------------------------+-----------------------------------------------------------------+----------------------------------------------+
| ibm-mq | ``pip install 'apache-airflow[ibm-mq]'`` | IBM MQ hook and trigger | |
diff --git a/airflow-core/tests/unit/always/test_providers_manager.py b/airflow-core/tests/unit/always/test_providers_manager.py
index 25e3774d4f7e7..fb9a96862e855 100644
--- a/airflow-core/tests/unit/always/test_providers_manager.py
+++ b/airflow-core/tests/unit/always/test_providers_manager.py
@@ -338,8 +338,8 @@ def test_cli(self):
def test_dialects(self):
provider_manager = ProvidersManager()
dialect_class_names = list(provider_manager.dialects)
- assert len(dialect_class_names) == 3
- assert dialect_class_names == ["default", "mssql", "postgresql"]
+ assert len(dialect_class_names) == 4
+ assert dialect_class_names == ["default", "db2", "mssql", "postgresql"]
class TestWithoutCheckProviderManager:
diff --git a/dev/breeze/doc/images/output_build-docs.svg b/dev/breeze/doc/images/output_build-docs.svg
index 99bc5dbc0de1e..3c91af180e04f 100644
--- a/dev/breeze/doc/images/output_build-docs.svg
+++ b/dev/breeze/doc/images/output_build-docs.svg
@@ -246,12 +246,12 @@
| apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | clickhousedb | cloudant | cncf.kubernetes
| cohere | common.ai | common.compat | common.dataquality | common.io | common.messaging | common.sql | databricks |
datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook |
-ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.mq | imap | influxdb | informatica | java-sdk
-| jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |
-neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |
-pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack |
-smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino | vertica | vespa |
-weaviate | yandex | ydb | zendesk]...
+ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.db2 | ibm.mq | imap | influxdb | informatica
+| java-sdk | jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo
+| mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |
+pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp |
+singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino |
+vertica | vespa | weaviate | yandex | ydb | zendesk]...
Build documents.
diff --git a/dev/breeze/doc/images/output_build-docs.txt b/dev/breeze/doc/images/output_build-docs.txt
index 75dd9355bcff2..5db68384f6c9c 100644
--- a/dev/breeze/doc/images/output_build-docs.txt
+++ b/dev/breeze/doc/images/output_build-docs.txt
@@ -1 +1 @@
-e22969fb5e92a3efafb744881fea5ef8
+7def343508d800dbd73aae70ed97c71c
diff --git a/dev/breeze/doc/images/output_release-management_add-back-references.svg b/dev/breeze/doc/images/output_release-management_add-back-references.svg
index 9df4462030484..af48c5af91b01 100644
--- a/dev/breeze/doc/images/output_release-management_add-back-references.svg
+++ b/dev/breeze/doc/images/output_release-management_add-back-references.svg
@@ -155,12 +155,12 @@
| apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | clickhousedb | cloudant | cncf.kubernetes
| cohere | common.ai | common.compat | common.dataquality | common.io | common.messaging | common.sql | databricks |
datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook |
-ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.mq | imap | influxdb | informatica | java-sdk
-| jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |
-neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |
-pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack |
-smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino | vertica | vespa |
-weaviate | yandex | ydb | zendesk]...
+ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.db2 | ibm.mq | imap | influxdb | informatica
+| java-sdk | jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo
+| mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |
+pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp |
+singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino |
+vertica | vespa | weaviate | yandex | ydb | zendesk]...
Command to add back references for documentation to make it backward compatible.
diff --git a/dev/breeze/doc/images/output_release-management_add-back-references.txt b/dev/breeze/doc/images/output_release-management_add-back-references.txt
index 152f412a472d3..243b3ec4cd279 100644
--- a/dev/breeze/doc/images/output_release-management_add-back-references.txt
+++ b/dev/breeze/doc/images/output_release-management_add-back-references.txt
@@ -1 +1 @@
-963d8b3e84cb64aa0d69026638b9fb1b
+7fbc80f910293a0a2ad25eca6ef7c338
diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.svg b/dev/breeze/doc/images/output_release-management_publish-docs.svg
index 59c03ad4d408a..a3da8ab868170 100644
--- a/dev/breeze/doc/images/output_release-management_publish-docs.svg
+++ b/dev/breeze/doc/images/output_release-management_publish-docs.svg
@@ -194,12 +194,12 @@
| apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | clickhousedb | cloudant | cncf.kubernetes
| cohere | common.ai | common.compat | common.dataquality | common.io | common.messaging | common.sql | databricks |
datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook |
-ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.mq | imap | influxdb | informatica | java-sdk
-| jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |
-neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |
-pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack |
-smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino | vertica | vespa |
-weaviate | yandex | ydb | zendesk]...
+ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.db2 | ibm.mq | imap | influxdb | informatica
+| java-sdk | jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo
+| mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |
+pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp |
+singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino |
+vertica | vespa | weaviate | yandex | ydb | zendesk]...
Command to publish generated documentation to airflow-site
diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.txt b/dev/breeze/doc/images/output_release-management_publish-docs.txt
index 585d41d6275cb..f445d7c3f3128 100644
--- a/dev/breeze/doc/images/output_release-management_publish-docs.txt
+++ b/dev/breeze/doc/images/output_release-management_publish-docs.txt
@@ -1 +1 @@
-217c089e723c5584da63135bbf011504
+f63e4ca68d77111b2d3c6f05111353af
diff --git a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg
index 8e1ee534c9b46..7fd604c1b66e2 100644
--- a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg
+++ b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg
@@ -189,13 +189,13 @@
│atlassian.jira | celery | clickhousedb | cloudant | cncf.kubernetes | cohere | common.ai | │
│common.compat | common.dataquality | common.io | common.messaging | common.sql | databricks | │
│datadog | dbt.cloud | dingding | discord | docker | edge3 | elasticsearch | exasol | fab | │
-│facebook | ftp | git | github | google | grpc | hashicorp | http | ibm.mq | imap | influxdb | │
-│informatica | jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | │
-│microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | │
-│opsgenie | oracle | pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | │
-│redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack | smtp | snowflake │
-│| sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | vespa | weaviate |│
-│yandex | ydb | zendesk)│
+│facebook | ftp | git | github | google | grpc | hashicorp | http | ibm.db2 | ibm.mq | imap | │
+│influxdb | informatica | jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | │
+│microsoft.psrp | microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | │
+│openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector | pinecone | │
+│postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | │
+│singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata│
+│| trino | vertica | vespa | weaviate | yandex | ydb | zendesk)│
│--provider-versionProvider version to generate the requirements for i.e `2.1.0`. `latest` is also a supported │
│value to account for the most recent version of the provider (TEXT)│
│--force Force update providers requirements even if they already exist.│
diff --git a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt
index ca3930b91a1a2..815858fd19c08 100644
--- a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt
+++ b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt
@@ -1 +1 @@
-7cbc3f1d6c0c4f1745702d867f9e7fdc
+fbadce49313f856f69861005e009e602
diff --git a/dev/breeze/doc/images/output_workflow-run_publish-docs.svg b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
index 13e7e9bf14620..0f02b32556551 100644
--- a/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
@@ -209,12 +209,12 @@
| apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | clickhousedb | cloudant | cncf.kubernetes
| cohere | common.ai | common.compat | common.dataquality | common.io | common.messaging | common.sql | databricks |
datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook |
-ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.mq | imap | influxdb | informatica | java-sdk
-| jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |
-neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |
-pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack |
-smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino | vertica | vespa |
-weaviate | yandex | ydb | zendesk]...
+ftp | git | github | google | grpc | hashicorp | helm-chart | http | ibm.db2 | ibm.mq | imap | influxdb | informatica
+| java-sdk | jdbc | jenkins | keycloak | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo
+| mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |
+pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp |
+singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | task-sdk | telegram | teradata | trino |
+vertica | vespa | weaviate | yandex | ydb | zendesk]...
Trigger publish docs to S3 workflow
diff --git a/dev/breeze/doc/images/output_workflow-run_publish-docs.txt b/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
index a86438aee4e27..3eb078f51416e 100644
--- a/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
@@ -1 +1 @@
-cb87f41a19fbc8895cd38aa6351139ae
+7d570131e213f83074239d395a5989f3
diff --git a/dev/breeze/tests/test_selective_checks.py b/dev/breeze/tests/test_selective_checks.py
index 1dac0e3dd8354..f29feb863195c 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -2926,7 +2926,7 @@ def test_upgrade_to_newer_dependencies(
{
"docs-list-as-string": "amazon apache.drill apache.druid apache.hive apache.iceberg "
"apache.impala apache.pinot clickhousedb common.ai common.compat common.sql databricks elasticsearch "
- "exasol google informatica jdbc microsoft.mssql mysql odbc openlineage "
+ "exasol google ibm.db2 informatica jdbc microsoft.mssql mysql odbc openlineage "
"oracle pgvector postgres presto slack snowflake sqlite teradata trino vertica ydb",
},
id="Common SQL provider package python files changed",
diff --git a/providers/ibm/db2/.gitignore b/providers/ibm/db2/.gitignore
new file mode 100644
index 0000000000000..bff2d7629604d
--- /dev/null
+++ b/providers/ibm/db2/.gitignore
@@ -0,0 +1 @@
+*.iml
diff --git a/providers/ibm/db2/LICENSE b/providers/ibm/db2/LICENSE
new file mode 100644
index 0000000000000..11069edd79019
--- /dev/null
+++ b/providers/ibm/db2/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/providers/ibm/db2/NOTICE b/providers/ibm/db2/NOTICE
new file mode 100644
index 0000000000000..a51bd9390d030
--- /dev/null
+++ b/providers/ibm/db2/NOTICE
@@ -0,0 +1,5 @@
+Apache Airflow
+Copyright 2016-2026 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/providers/ibm/db2/README.rst b/providers/ibm/db2/README.rst
new file mode 100644
index 0000000000000..18585591619c5
--- /dev/null
+++ b/providers/ibm/db2/README.rst
@@ -0,0 +1,104 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+.. http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+``apache-airflow-providers-ibm-db2``
+=====================================
+
+Provider package for IBM Db2 database support in Apache Airflow.
+
+Installation
+------------
+
+You can install this package via pip:
+
+.. code-block:: bash
+
+ pip install apache-airflow-providers-ibm-db2
+
+Requirements
+------------
+
+This provider requires the following packages:
+
+- ``ibm-db>=3.0.0`` - IBM Db2 Python driver
+- ``ibm-db-sa>=0.4.0`` - SQLAlchemy dialect for Db2
+
+Configuration
+-------------
+
+To use this provider, you need to configure a Db2 connection in Airflow:
+
+1. In the Airflow UI, go to Admin -> Connections
+2. Create a new connection with the following details:
+
+ - **Connection ID**: ``db2_default`` (or any custom name)
+ - **Connection Type**: ``IBM Db2``
+ - **Host**: Your Db2 server hostname
+ - **Schema**: Database name
+ - **Login**: Db2 username
+ - **Password**: Db2 password
+ - **Port**: Db2 port (default: 50000)
+ - **Extra**: Optional JSON with additional parameters:
+
+ .. code-block:: json
+
+ {
+ "ssl": true,
+ "sslcert": "/path/to/cert.pem"
+ }
+
+Usage
+-----
+
+Using the Db2Hook
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ from airflow.providers.ibm.db2.hooks.db2 import Db2Hook
+
+ hook = Db2Hook(db2_conn_id="db2_default")
+ records = hook.get_records("SELECT * FROM employees WHERE dept = %s", parameters=("IT",))
+
+Using with SQLExecuteQueryOperator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ from airflow import DAG
+ from airflow.providers.common.sql.operators.sql import SQLExecuteQueryOperator
+ from datetime import datetime
+
+ with DAG("db2_example", start_date=datetime(2024, 1, 1)) as dag:
+ query_task = SQLExecuteQueryOperator(
+ task_id="query_db2",
+ conn_id="db2_default",
+ sql="SELECT * FROM employees WHERE dept = %(dept)s",
+ parameters={"dept": "IT"},
+ )
+
+Features
+--------
+
+- Full Db2 database connectivity via ``ibm_db_dbi``
+- Support for SSL connections
+- Autocommit and executemany support
+
+License
+-------
+
+Apache License 2.0
diff --git a/providers/ibm/db2/docs/changelog.rst b/providers/ibm/db2/docs/changelog.rst
new file mode 100644
index 0000000000000..eb432ae8580bb
--- /dev/null
+++ b/providers/ibm/db2/docs/changelog.rst
@@ -0,0 +1,32 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+.. NOTE TO CONTRIBUTORS:
+ Please, only add notes to the Changelog just below the "Changelog" header when there are some breaking changes
+ and you want to add an explanation to the users on how they are supposed to deal with them.
+ The changelog is updated and maintained semi-automatically by release manager.
+
+``apache-airflow-providers-ibm-db2``
+
+
+Changelog
+---------
+
+0.1.0
+.....
+
+Initial version of the provider.
diff --git a/providers/ibm/db2/docs/commits.rst b/providers/ibm/db2/docs/commits.rst
new file mode 100644
index 0000000000000..94c43167a1a14
--- /dev/null
+++ b/providers/ibm/db2/docs/commits.rst
@@ -0,0 +1,34 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+ .. NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN!
+
+ .. IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE
+ `PROVIDER_COMMITS_TEMPLATE.rst.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
+
+ .. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN!
+
+Package apache-airflow-providers-ibm-db2
+------------------------------------------------------
+
+`IBM Db2 `__
+
+
+This is detailed commit list of changes for versions provider package: ``ibm.db2``.
+For high-level changelog, see :doc:`package information including changelog `.
+
+.. airflow-providers-commits::
diff --git a/providers/ibm/db2/docs/conf.py b/providers/ibm/db2/docs/conf.py
new file mode 100644
index 0000000000000..26b4f72968f32
--- /dev/null
+++ b/providers/ibm/db2/docs/conf.py
@@ -0,0 +1,27 @@
+# Disable Flake8 because of all the sphinx imports
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Configuration of Providers docs building."""
+
+from __future__ import annotations
+
+import os
+
+os.environ["AIRFLOW_PACKAGE_NAME"] = "apache-airflow-providers-ibm-db2"
+
+from docs.provider_conf import * # noqa: F403
diff --git a/providers/ibm/db2/docs/connections/db2.rst b/providers/ibm/db2/docs/connections/db2.rst
new file mode 100644
index 0000000000000..f9a267fe52318
--- /dev/null
+++ b/providers/ibm/db2/docs/connections/db2.rst
@@ -0,0 +1,60 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+.. _howto/connection:ibmdb2:
+
+IBM Db2 Connection
+==================
+
+The IBM Db2 connection type enables connection to IBM Db2 databases.
+
+Configuring the Connection
+---------------------------
+
+Host (required)
+ The host to connect to.
+
+Schema (optional)
+ Specify the schema name to be used in the database.
+
+Login (required)
+ Specify the user name to connect.
+
+Password (required)
+ Specify the password to connect.
+
+Port (optional)
+ Port of the Db2 database. Default is 50000.
+
+Extra (optional)
+ Specify the extra parameters (as json dictionary) that can be used in the
+ Db2 connection. The following parameters are supported:
+
+ * ``database`` - The database name to connect to.
+ * ``protocol`` - The protocol to use (default: TCPIP).
+ * ``security`` - Security protocol (e.g., SSL).
+ * Any other parameter supported by the IBM Db2 driver.
+
+ Example "extras" field:
+
+ .. code-block:: json
+
+ {
+ "database": "sample",
+ "protocol": "TCPIP",
+ "security": "SSL"
+ }
diff --git a/providers/ibm/db2/docs/dialects.rst b/providers/ibm/db2/docs/dialects.rst
new file mode 100644
index 0000000000000..fd070253bc72a
--- /dev/null
+++ b/providers/ibm/db2/docs/dialects.rst
@@ -0,0 +1,53 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+SQL Dialects
+=============
+
+The :class:`~airflow.providers.common.sql.dialects.dialect.Dialect` offers an abstraction layer between the
+:class:`~airflow.providers.common.sql.hooks.sql.DbApiHook` implementation and the database. For some database multiple
+connection types are available, like native, ODBC and or JDBC. As the :class:`~airflow.providers.odbc.hooks.odbc.OdbcHook`
+and the :class:`~airflow.providers.jdbc.hooks.jdbc.JdbcHook` are generic hooks which allows you to interact with any
+database that has a driver for it, it needed an abstraction layer which allows us to run specialized queries
+depending of the database to which we connect and that's why dialects where introduced.
+
+The default :class:`~airflow.providers.common.sql.dialects.dialect.Dialect` class has following operations
+available which underneath use SQLAlchemy to execute, but can be overloaded with specialized implementations
+per database:
+
+- ``placeholder`` specifies the database specific placeholder used in prepared statements (default: ``%s``);
+- ``inspector`` returns the SQLAlchemy inspector which allows us to retrieve database metadata;
+- ``extract_schema_from_table`` allows us to extract the schema name from a string.
+- ``get_column_names`` returns the column names for the given table and schema (optional) using the SQLAlchemy inspector.
+- ``get_primary_keys`` returns the primary keys for the given table and schema (optional) using the SQLAlchemy inspector.
+- ``get_target_fields`` returns the columns names that aren't identity or auto incremented columns, this will be used by the insert_rows method of the :class:`~airflow.providers.common.sql.hooks.sql.DbApiHook` if the target_fields parameter wasn't specified and the Airflow property ``core.dbapihook_resolve_target_fields`` is set to True (default: False).
+- ``reserved_words`` returns the reserved words in SQL for the target database using the SQLAlchemy inspector.
+- ``generate_insert_sql`` generates the insert SQL statement for the target database.
+- ``generate_replace_sql`` generates the upsert SQL statement for the target database.
+
+The IBM Db2 provider includes a specialized dialect:
+
+- ``db2`` :class:`~airflow.providers.ibm.db2.dialects.db2.Db2Dialect` specialized for IBM Db2;
+
+The dialect to be used will be derived from the connection string, which sometimes won't be possible. There is always
+the possibility to specify the dialect name through the extra options of the connection:
+
+.. code-block::
+
+ dialect_name: 'db2'
+
+If a specific dialect isn't available for a database, the default one will be used, same when a non-existing dialect name is specified.
diff --git a/providers/ibm/db2/docs/index.rst b/providers/ibm/db2/docs/index.rst
new file mode 100644
index 0000000000000..b194c4ca611a5
--- /dev/null
+++ b/providers/ibm/db2/docs/index.rst
@@ -0,0 +1,134 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+``apache-airflow-providers-ibm-db2``
+=====================================
+
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Basics
+
+ Home
+ Changelog
+ Security
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Guides
+
+ Connection types
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: References
+
+ Python API <_api/airflow/providers/ibm/db2/index>
+ Dialects
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: System tests
+
+ System Tests <_api/tests/system/ibm/db2/index>
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Resources
+
+ PyPI Repository
+ Example Dags
+ Installing from sources
+
+.. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN AT RELEASE TIME!
+
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+ :caption: Commits
+
+ Detailed list of commits
+
+
+apache-airflow-providers-ibm-db2 package
+------------------------------------------------------
+
+`IBM Db2 `__
+
+
+Release: 0.1.0
+
+Provider package
+----------------
+
+This package is for the ``ibm.db2`` provider.
+All classes for this package are included in the ``airflow.providers.ibm.db2`` python package.
+
+Installation
+------------
+
+You can install this package on top of an existing Airflow installation via
+``pip install apache-airflow-providers-ibm-db2``.
+For the minimum Airflow version supported, see ``Requirements`` below.
+
+Requirements
+------------
+
+The minimum Apache Airflow version supported by this provider distribution is ``2.11.0``.
+
+========================================== ==================
+PIP package Version required
+========================================== ==================
+``apache-airflow`` ``>=2.11.0``
+``apache-airflow-providers-common-compat`` ``>=1.12.0``
+``apache-airflow-providers-common-sql`` ``>=1.32.0``
+``ibm-db`` ``>=3.2.0``
+``ibm-db-sa`` ``>=0.4.0``
+``methodtools`` ``>=0.4.7``
+========================================== ==================
+
+Optional dependencies
+---------------------
+
+These extras install optional third-party libraries that enable additional features of the provider.
+Install them when installing from PyPI. For example:
+
+.. code-block:: bash
+
+ pip install apache-airflow-providers-ibm-db2[openlineage]
+
+
+=============== ========================================
+Extra Dependencies
+=============== ========================================
+``openlineage`` ``apache-airflow-providers-openlineage``
+=============== ========================================
+
+Downloading official packages
+-----------------------------
+
+You can download officially released packages and verify their checksums and signatures from the
+`Official Apache Download site `_
+
+* `The apache-airflow-providers-ibm-db2 0.1.0 sdist package `_ (`asc `__, `sha512 `__)
+* `The apache-airflow-providers-ibm-db2 0.1.0 wheel package `_ (`asc `__, `sha512 `__)
diff --git a/providers/ibm/db2/docs/installing-providers-from-sources.rst b/providers/ibm/db2/docs/installing-providers-from-sources.rst
new file mode 100644
index 0000000000000..fdbb17d017579
--- /dev/null
+++ b/providers/ibm/db2/docs/installing-providers-from-sources.rst
@@ -0,0 +1,18 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+.. include:: /../../../../devel-common/src/sphinx_exts/includes/installing-providers-from-sources.rst
diff --git a/providers/ibm/db2/docs/integration-logos/Db2.png b/providers/ibm/db2/docs/integration-logos/Db2.png
new file mode 100644
index 0000000000000..d0db0bd88a052
Binary files /dev/null and b/providers/ibm/db2/docs/integration-logos/Db2.png differ
diff --git a/providers/ibm/db2/docs/security.rst b/providers/ibm/db2/docs/security.rst
new file mode 100644
index 0000000000000..351ff007ebf2f
--- /dev/null
+++ b/providers/ibm/db2/docs/security.rst
@@ -0,0 +1,18 @@
+ .. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ .. http://www.apache.org/licenses/LICENSE-2.0
+
+ .. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+.. include:: /../../../../devel-common/src/sphinx_exts/includes/security.rst
diff --git a/providers/ibm/db2/provider.yaml b/providers/ibm/db2/provider.yaml
new file mode 100644
index 0000000000000..3815e2c81c227
--- /dev/null
+++ b/providers/ibm/db2/provider.yaml
@@ -0,0 +1,93 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+---
+package-name: apache-airflow-providers-ibm-db2
+name: IBM Db2
+description: |
+ `IBM Db2 `__
+
+state: not-ready
+lifecycle: incubation
+source-date-epoch: 1743033600
+versions:
+ - 0.1.0
+
+integrations:
+ - integration-name: IBM Db2
+ external-doc-url: https://www.ibm.com/products/db2
+ logo: /docs/integration-logos/Db2.png
+ tags: [software]
+
+dialects:
+ - dialect-type: db2
+ dialect-class-name: airflow.providers.ibm.db2.dialects.db2.Db2Dialect
+
+hooks:
+ - integration-name: IBM Db2
+ python-modules:
+ - airflow.providers.ibm.db2.hooks.db2
+
+connection-types:
+ - hook-class-name: airflow.providers.ibm.db2.hooks.db2.Db2Hook
+ connection-type: ibmdb2
+ hook-name: IBM Db2
+ ui-field-behaviour:
+ hidden-fields: []
+ relabeling:
+ schema: Database
+ login: Username
+ password: Password
+ placeholders:
+ host: localhost
+ port: "50000"
+ schema: database_name
+ login: db2_user
+ password: db2_password
+ extra: >-
+ {"SECURITY": "SSL", "SSLServerCertificate": "/path/to/cert.crt",
+ "CurrentSchema": "MY_SCHEMA"}
+ conn-fields:
+ SECURITY:
+ label: Security Protocol
+ schema:
+ type: ["string", "null"]
+ enum: ["", "SSL"]
+ description: >-
+ Security protocol for the connection (leave empty for no SSL,
+ or set to SSL for encrypted connections)
+ SSLServerCertificate:
+ label: SSL Server Certificate Path
+ schema:
+ type: ["string", "null"]
+ description: Path to the SSL server certificate file (required when SECURITY is SSL)
+ CurrentSchema:
+ label: Current Schema
+ schema:
+ type: ["string", "null"]
+ description: Default schema to use for unqualified table names
+ ConnectTimeout:
+ label: Connection Timeout
+ schema:
+ type: ["integer", "null"]
+ description: Connection timeout in seconds (0 means no timeout)
+ Authentication:
+ label: Authentication Type
+ schema:
+ type: ["string", "null"]
+ enum: ["", "SERVER", "KERBEROS", "GSSPLUGIN"]
+ description: Authentication method (leave empty for default SERVER authentication)
diff --git a/providers/ibm/db2/pyproject.toml b/providers/ibm/db2/pyproject.toml
new file mode 100644
index 0000000000000..6422078c7e36c
--- /dev/null
+++ b/providers/ibm/db2/pyproject.toml
@@ -0,0 +1,136 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN!
+
+# IF YOU WANT TO MODIFY THIS FILE EXCEPT DEPENDENCIES, YOU SHOULD MODIFY THE TEMPLATE
+# `pyproject_TEMPLATE.toml.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
+[build-system]
+requires = ["flit_core==3.12.0"]
+build-backend = "flit_core.buildapi"
+
+[project]
+name = "apache-airflow-providers-ibm-db2"
+version = "0.1.0"
+description = "Provider package apache-airflow-providers-ibm-db2 for Apache Airflow"
+readme = "README.rst"
+license = "Apache-2.0"
+license-files = ['LICENSE', 'NOTICE']
+authors = [
+ {name="Apache Software Foundation", email="dev@airflow.apache.org"},
+]
+maintainers = [
+ {name="Apache Software Foundation", email="dev@airflow.apache.org"},
+]
+keywords = [ "airflow-provider", "ibm.db2", "airflow", "integration" ]
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: Console",
+ "Environment :: Web Environment",
+ "Intended Audience :: Developers",
+ "Intended Audience :: System Administrators",
+ "Framework :: Apache Airflow",
+ "Framework :: Apache Airflow :: Provider",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
+ "Topic :: System :: Monitoring",
+]
+requires-python = ">=3.10"
+
+# The dependencies should be modified in place in the generated file.
+# Any change in the dependencies is preserved when the file is regenerated
+# Make sure to run ``prek update-providers-dependencies --all-files``
+# After you modify the dependencies, and rebuild your Breeze CI image with ``breeze ci-image build``
+dependencies = [
+ "apache-airflow>=2.11.0",
+ "apache-airflow-providers-common-compat>=1.12.0",
+ "apache-airflow-providers-common-sql>=1.32.0",
+ "ibm-db>=3.2.0",
+ "ibm-db-sa>=0.4.0",
+ "methodtools>=0.4.7",
+]
+
+# The optional dependencies should be modified in place in the generated file
+# Any change in the dependencies is preserved when the file is regenerated
+[project.optional-dependencies]
+"openlineage" = [
+ "apache-airflow-providers-openlineage"
+]
+
+[dependency-groups]
+dev = [
+ "apache-airflow",
+ "apache-airflow-task-sdk",
+ "apache-airflow-devel-common",
+ "apache-airflow-providers-common-sql",
+ # Additional devel dependencies (do not remove this line and add extra development dependencies)
+]
+
+# To build docs:
+#
+# uv run --group docs build-docs
+#
+# To enable auto-refreshing build with server:
+#
+# uv run --group docs build-docs --autobuild
+#
+# To see more options:
+#
+# uv run --group docs build-docs --help
+#
+docs = [
+ "apache-airflow-devel-common[docs]"
+]
+
+[tool.uv.sources]
+# These names must match the names as defined in the pyproject.toml of the workspace items,
+# *not* the workspace folder paths
+apache-airflow = {workspace = true}
+apache-airflow-devel-common = {workspace = true}
+apache-airflow-task-sdk = {workspace = true}
+apache-airflow-providers-common-sql = {workspace = true}
+apache-airflow-providers-standard = {workspace = true}
+
+[project.urls]
+"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-ibm-db2/0.1.0"
+"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-ibm-db2/0.1.0/changelog.html"
+"Bug Tracker" = "https://github.com/apache/airflow/issues"
+"Source Code" = "https://github.com/apache/airflow"
+"Slack Chat" = "https://s.apache.org/airflow-slack"
+"Mastodon" = "https://fosstodon.org/@airflow"
+"YouTube" = "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/"
+
+[project.entry-points."apache_airflow_provider"]
+provider_info = "airflow.providers.ibm.db2.get_provider_info:get_provider_info"
+
+[tool.flit.module]
+name = "airflow.providers.ibm.db2"
+
+# Explicit sdist contents so the build does not rely on VCS information
+# (flit 4.0 makes --no-use-vcs the default — see https://github.com/pypa/flit/pull/782).
+[tool.flit.sdist]
+include = [
+ "docs/",
+ "provider.yaml",
+ "src/airflow/__init__.py",
+ "src/airflow/providers/__init__.py",
+ "src/airflow/providers/ibm/__init__.py",
+ "tests/",
+]
diff --git a/providers/ibm/db2/src/airflow/__init__.py b/providers/ibm/db2/src/airflow/__init__.py
new file mode 100644
index 0000000000000..5966d6b1d5261
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/src/airflow/providers/__init__.py b/providers/ibm/db2/src/airflow/providers/__init__.py
new file mode 100644
index 0000000000000..5966d6b1d5261
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/__init__.py b/providers/ibm/db2/src/airflow/providers/ibm/__init__.py
new file mode 100644
index 0000000000000..5966d6b1d5261
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/__init__.py b/providers/ibm/db2/src/airflow/providers/ibm/db2/__init__.py
new file mode 100644
index 0000000000000..90b1bd2dbeb2c
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/__init__.py
@@ -0,0 +1,39 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE
+# OVERWRITTEN WHEN PREPARING DOCUMENTATION FOR THE PACKAGES.
+#
+# IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE
+# `PROVIDER__INIT__PY_TEMPLATE.py.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
+#
+from __future__ import annotations
+
+import packaging.version
+
+from airflow import __version__ as airflow_version
+
+__all__ = ["__version__"]
+
+__version__ = "0.1.0"
+
+if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
+ "2.11.0"
+):
+ raise RuntimeError(
+ f"The package `apache-airflow-providers-ibm-db2:{__version__}` needs Apache Airflow 2.11.0+"
+ )
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/dialects/__init__.py b/providers/ibm/db2/src/airflow/providers/ibm/db2/dialects/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/dialects/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/dialects/db2.py b/providers/ibm/db2/src/airflow/providers/ibm/db2/dialects/db2.py
new file mode 100644
index 0000000000000..27ab10b748412
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/dialects/db2.py
@@ -0,0 +1,103 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from airflow.providers.common.sql.dialects.dialect import Dialect
+
+
+class Db2Dialect(Dialect):
+ """
+ Db2-specific SQL dialect implementation.
+
+ Provides Db2-specific SQL generation, particularly for MERGE (upsert) operations.
+ """
+
+ def generate_replace_sql(self, table, values, target_fields, **kwargs) -> str:
+ """
+ Generate MERGE SQL statement for Db2.
+
+ Db2 doesn't support REPLACE INTO syntax. Instead, it uses
+ MERGE statements for upsert operations.
+
+ :param table: Name of the target table
+ :param values: The row to insert/update
+ :param target_fields: The names of the columns to fill in the table
+ :param kwargs: Additional parameters, including replace_index: list of column names
+ to use for matching (defaults to primary keys)
+ :return: The generated MERGE SQL statement
+
+ Example generated SQL::
+
+ MERGE INTO table AS t
+ USING (VALUES (?, ?, ?)) AS s(col1, col2, col3)
+ ON t.pk = s.pk
+ WHEN MATCHED THEN UPDATE SET t.col1 = s.col1, t.col2 = s.col2
+ WHEN NOT MATCHED THEN INSERT (col1, col2, col3) VALUES (s.col1, s.col2, s.col3)
+ """
+ # Validate target_fields
+ if not target_fields:
+ raise ValueError("Db2 MERGE syntax requires column names")
+
+ # Get the columns to use for matching (ON clause)
+ replace_index = kwargs.get("replace_index") or self.get_primary_keys(table)
+
+ if not replace_index:
+ raise ValueError(
+ f"Cannot generate MERGE statement for table '{table}': "
+ "no primary key found and no replace_index provided. "
+ "Specify replace_index parameter with column names to use for matching."
+ )
+
+ # Convert string to list if needed
+ if isinstance(replace_index, str):
+ replace_index = [replace_index]
+
+ # Escape column names
+ escaped_target_fields = [self.escape_word(field) for field in target_fields]
+ escaped_replace_index = [self.escape_word(field) for field in replace_index]
+
+ # Build placeholders for VALUES clause
+ placeholders = self._joined_placeholders(values)
+
+ # Build column list for USING clause
+ columns = ", ".join(escaped_target_fields)
+
+ # Build ON clause (matching condition)
+ on_conditions = [f"t.{col} = s.{col}" for col in escaped_replace_index]
+ on_clause = " AND ".join(on_conditions)
+
+ # Build UPDATE SET clause (exclude primary key columns from update)
+ update_fields = [field for field in escaped_target_fields if field not in escaped_replace_index]
+ if update_fields:
+ update_assignments = [f"t.{field} = s.{field}" for field in update_fields]
+ update_clause = ", ".join(update_assignments)
+ when_matched = f"WHEN MATCHED THEN UPDATE SET {update_clause}"
+ else:
+ # If all columns are in the primary key, no update needed
+ when_matched = ""
+
+ # Build INSERT clause
+ insert_cols = ", ".join(escaped_target_fields)
+ insert_vals = ", ".join([f"s.{field}" for field in escaped_target_fields])
+
+ # Construct the full MERGE statement
+ sql = f"MERGE INTO {table} AS t USING (VALUES ({placeholders})) AS s({columns}) ON {on_clause}"
+ if when_matched:
+ sql += f" {when_matched}"
+ sql += f" WHEN NOT MATCHED THEN INSERT ({insert_cols}) VALUES ({insert_vals})"
+
+ return sql
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/get_provider_info.py b/providers/ibm/db2/src/airflow/providers/ibm/db2/get_provider_info.py
new file mode 100644
index 0000000000000..d146f5a290d2c
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/get_provider_info.py
@@ -0,0 +1,90 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN!
+#
+# IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE
+# `get_provider_info_TEMPLATE.py.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
+
+
+def get_provider_info():
+ return {
+ "package-name": "apache-airflow-providers-ibm-db2",
+ "name": "IBM Db2",
+ "description": "`IBM Db2 `__\n",
+ "integrations": [
+ {
+ "integration-name": "IBM Db2",
+ "external-doc-url": "https://www.ibm.com/products/db2",
+ "logo": "/docs/integration-logos/Db2.png",
+ "tags": ["software"],
+ }
+ ],
+ "dialects": [
+ {"dialect-type": "db2", "dialect-class-name": "airflow.providers.ibm.db2.dialects.db2.Db2Dialect"}
+ ],
+ "hooks": [{"integration-name": "IBM Db2", "python-modules": ["airflow.providers.ibm.db2.hooks.db2"]}],
+ "connection-types": [
+ {
+ "hook-class-name": "airflow.providers.ibm.db2.hooks.db2.Db2Hook",
+ "connection-type": "ibmdb2",
+ "hook-name": "IBM Db2",
+ "ui-field-behaviour": {
+ "hidden-fields": [],
+ "relabeling": {"schema": "Database", "login": "Username", "password": "Password"},
+ "placeholders": {
+ "host": "localhost",
+ "port": "50000",
+ "schema": "database_name",
+ "login": "db2_user",
+ "password": "db2_password",
+ "extra": '{"SECURITY": "SSL", "SSLServerCertificate": "/path/to/cert.crt", "CurrentSchema": "MY_SCHEMA"}',
+ },
+ },
+ "conn-fields": {
+ "SECURITY": {
+ "label": "Security Protocol",
+ "schema": {"type": ["string", "null"], "enum": ["", "SSL"]},
+ "description": "Security protocol for the connection (leave empty for no SSL, or set to SSL for encrypted connections)",
+ },
+ "SSLServerCertificate": {
+ "label": "SSL Server Certificate Path",
+ "schema": {"type": ["string", "null"]},
+ "description": "Path to the SSL server certificate file (required when SECURITY is SSL)",
+ },
+ "CurrentSchema": {
+ "label": "Current Schema",
+ "schema": {"type": ["string", "null"]},
+ "description": "Default schema to use for unqualified table names",
+ },
+ "ConnectTimeout": {
+ "label": "Connection Timeout",
+ "schema": {"type": ["integer", "null"]},
+ "description": "Connection timeout in seconds (0 means no timeout)",
+ },
+ "Authentication": {
+ "label": "Authentication Type",
+ "schema": {
+ "type": ["string", "null"],
+ "enum": ["", "SERVER", "KERBEROS", "GSSPLUGIN"],
+ },
+ "description": "Authentication method (leave empty for default SERVER authentication)",
+ },
+ },
+ }
+ ],
+ }
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/__init__.py b/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py b/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py
new file mode 100644
index 0000000000000..8a7e62db302ec
--- /dev/null
+++ b/providers/ibm/db2/src/airflow/providers/ibm/db2/hooks/db2.py
@@ -0,0 +1,185 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""This module allows to connect to an IBM Db2 database."""
+
+from __future__ import annotations
+
+from functools import cached_property
+from typing import TYPE_CHECKING, Any
+
+from airflow.providers.common.sql.hooks.sql import DbApiHook
+from airflow.providers.ibm.db2.dialects.db2 import Db2Dialect
+
+if TYPE_CHECKING:
+ from airflow.providers.common.sql.dialects.dialect import Dialect
+
+
+class Db2Hook(DbApiHook):
+ """
+ Interact with IBM Db2.
+
+ You can specify SSL and other connection parameters in the extra field of your connection.
+
+ **SSL Configuration:**
+ - ``{"SECURITY": "SSL", "SSLServerCertificate": "/path/to/cert.crt"}`` - For SSL with server certificate
+ - ``{"SECURITY": "SSL"}`` - For SSL without certificate validation
+
+ **Other Parameters:**
+ Any additional Db2 connection string parameters can be added to the extra field.
+ Parameter names will be automatically converted to uppercase.
+
+ :param db2_conn_id: The :ref:`Db2 connection id `
+ reference to a specific Db2 database.
+ """
+
+ conn_name_attr = "db2_conn_id"
+ default_conn_name = "db2_default"
+ conn_type = "ibmdb2"
+ hook_name = "IBM Db2"
+ supports_autocommit = True
+ supports_executemany = True
+ _test_connection_sql = "SELECT 1 FROM SYSIBM.SYSDUMMY1"
+ _placeholder = "?"
+
+ @cached_property
+ def dialect_name(self) -> str:
+ return "db2"
+
+ @cached_property
+ def dialect(self) -> Dialect:
+ return Db2Dialect(self)
+
+ @staticmethod
+ def _get_default_values(conn) -> dict[str, Any]:
+ """Extract connection values with defaults."""
+ return {
+ "host": conn.host or "localhost",
+ "port": conn.port or 50000,
+ "schema": conn.schema or "",
+ "login": conn.login or "",
+ "password": conn.password or "",
+ }
+
+ def get_conn(self) -> Any:
+ """
+ Return ibm_db_dbi connection object.
+
+ :return: Db2 connection object
+ """
+ import ibm_db_dbi
+
+ conn = self.get_connection(self.get_conn_id())
+ defaults = self._get_default_values(conn)
+
+ # Build connection string for Db2
+ conn_str_parts = [
+ f"DATABASE={defaults['schema']}",
+ f"HOSTNAME={defaults['host']}",
+ f"PORT={defaults['port']}",
+ "PROTOCOL=TCPIP",
+ f"UID={defaults['login']}",
+ f"PWD={defaults['password']}",
+ ]
+
+ # Add extra connection parameters from connection extra field
+ extra = conn.extra_dejson
+ if extra:
+ # Add all extra parameters to connection string
+ # Parameter names are automatically converted to uppercase for Db2
+ for key, value in extra.items():
+ # Convert boolean values to appropriate strings
+ if isinstance(value, bool):
+ converted_value = "true" if value else "false"
+ else:
+ converted_value = value
+ conn_str_parts.append(f"{key.upper()}={converted_value}")
+
+ conn_str = ";".join(conn_str_parts) + ";"
+
+ return ibm_db_dbi.connect(conn_str, "", "")
+
+ def get_uri(self) -> str:
+ """
+ Return connection URI for SQLAlchemy using the ``ibm-db-sa`` dialect.
+
+ Includes extra connection parameters (like SSL configuration) as query parameters.
+
+ :return: SQLAlchemy connection URI
+ """
+ from urllib.parse import quote_plus, urlencode
+
+ conn = self.get_connection(self.get_conn_id())
+ defaults = self._get_default_values(conn)
+
+ # URL encode password if it contains special characters
+ password = quote_plus(defaults["password"]) if defaults["password"] else ""
+
+ # Build base URI
+ base_uri = f"db2+ibm_db://{defaults['login']}:{password}@{defaults['host']}:{defaults['port']}/{defaults['schema']}"
+
+ # Add extra parameters as query string (e.g., SSL configuration)
+ extra = conn.extra_dejson
+ if extra:
+ query_params = {}
+ for key, value in extra.items():
+ # Convert boolean values to appropriate strings
+ if isinstance(value, bool):
+ query_params[key.upper()] = "true" if value else "false"
+ else:
+ query_params[key.upper()] = str(value)
+
+ query_string = urlencode(query_params)
+ return f"{base_uri}?{query_string}"
+
+ return base_uri
+
+ def get_column_names(self, table: str, schema: str | None = None) -> list[str]:
+ """
+ Get column names for a table, excluding identity columns.
+
+ Uses the SQLAlchemy inspector to detect identity columns (``GENERATED ALWAYS AS IDENTITY``)
+ and exclude them from the result, as they should not appear in INSERT statements.
+
+ :param table: Table name
+ :param schema: Schema name (optional, uses connection schema if not provided)
+ :return: List of column names excluding identity columns
+ """
+ # Get all columns from SQLAlchemy inspector
+ columns = self.inspector.get_columns(table, schema=schema)
+
+ # Filter out identity columns (those with autoincrement=True)
+ column_names = [col["name"] for col in columns if not col.get("autoincrement", False)]
+
+ self.log.debug("Column names for table '%s' (excluding identity columns): %s", table, column_names)
+ return column_names
+
+ def get_primary_keys(self, table: str, schema: str | None = None) -> list[str]:
+ """
+ Get primary key column names for a table.
+
+ Uses SQLAlchemy inspector to retrieve primary key information from the database.
+
+ :param table: Table name
+ :param schema: Schema name (optional, uses connection schema if not provided)
+ :return: List of primary key column names
+ """
+ pk_constraint = self.inspector.get_pk_constraint(table, schema=schema)
+ pk_columns = pk_constraint.get("constrained_columns", [])
+
+ self.log.debug("Primary key columns for table '%s': %s", table, pk_columns)
+ return pk_columns
diff --git a/providers/ibm/db2/tests/conftest.py b/providers/ibm/db2/tests/conftest.py
new file mode 100644
index 0000000000000..f56ccce0a3f69
--- /dev/null
+++ b/providers/ibm/db2/tests/conftest.py
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+pytest_plugins = "tests_common.pytest_plugin"
diff --git a/providers/ibm/db2/tests/system/__init__.py b/providers/ibm/db2/tests/system/__init__.py
new file mode 100644
index 0000000000000..5966d6b1d5261
--- /dev/null
+++ b/providers/ibm/db2/tests/system/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/tests/system/ibm/__init__.py b/providers/ibm/db2/tests/system/ibm/__init__.py
new file mode 100644
index 0000000000000..f81abdf1a60b4
--- /dev/null
+++ b/providers/ibm/db2/tests/system/ibm/__init__.py
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/tests/system/ibm/db2/__init__.py b/providers/ibm/db2/tests/system/ibm/db2/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/providers/ibm/db2/tests/system/ibm/db2/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/providers/ibm/db2/tests/system/ibm/db2/example_db2.py b/providers/ibm/db2/tests/system/ibm/db2/example_db2.py
new file mode 100644
index 0000000000000..7834a31989f82
--- /dev/null
+++ b/providers/ibm/db2/tests/system/ibm/db2/example_db2.py
@@ -0,0 +1,188 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""
+Example Dag demonstrating the Db2 Provider.
+
+This Dag shows how to use the Db2 provider for common database operations:
+
+- Using SQLExecuteQueryOperator with Db2Hook for SQL execution
+- Using Db2Hook for programmatic queries
+- Creating tables and inserting data
+- Querying and processing results
+
+Prerequisites:
+
+1. Install the Db2 provider: ``pip install apache-airflow-providers-ibm-db2``
+2. Configure a Db2 connection in the Airflow UI or set the environment variable
+ ``AIRFLOW_CONN_DB2_DEFAULT='db2://user:password@host:port/database'``
+"""
+
+from __future__ import annotations
+
+from datetime import datetime
+
+from airflow.providers.common.sql.operators.sql import SQLExecuteQueryOperator
+from airflow.providers.ibm.db2.hooks.db2 import Db2Hook
+from airflow.sdk import DAG, task
+
+with DAG(
+ dag_id="example_db2",
+ description="Example Dag demonstrating Db2 Provider functionality",
+ schedule=None,
+ start_date=datetime(2024, 1, 1),
+ catchup=False,
+ tags=["example", "db2", "database"],
+) as dag:
+
+ @task
+ def cleanup_tables() -> None:
+ """Drop tables if they exist to ensure clean state."""
+ hook = Db2Hook(conn_id="db2_default")
+ for table in ["EMPLOYEES_BACKUP", "EMPLOYEES"]:
+ try:
+ hook.run(f"DROP TABLE {table}")
+ except Exception as e:
+ if "SQLSTATE=42704" not in str(e):
+ raise
+
+ create_table = SQLExecuteQueryOperator(
+ task_id="create_sample_table",
+ conn_id="db2_default",
+ sql="""
+ CREATE TABLE employees (
+ employee_id INTEGER NOT NULL PRIMARY KEY,
+ first_name VARCHAR(50),
+ last_name VARCHAR(50),
+ department VARCHAR(50),
+ salary DECIMAL(10, 2),
+ hire_date DATE,
+ updated_at TIMESTAMP
+ )
+ """,
+ autocommit=True,
+ hook_params={"schema": None},
+ )
+
+ insert_data = SQLExecuteQueryOperator(
+ task_id="insert_sample_data",
+ conn_id="db2_default",
+ sql="""
+ INSERT INTO employees
+ (employee_id, first_name, last_name, department, salary, hire_date, updated_at)
+ VALUES
+ (1, 'John', 'Doe', 'Engineering', 75000.00, '2023-01-15', CURRENT TIMESTAMP),
+ (2, 'Jane', 'Smith', 'Marketing', 65000.00, '2023-02-20', CURRENT TIMESTAMP),
+ (3, 'Bob', 'Johnson', 'Sales', 70000.00, '2023-03-10', CURRENT TIMESTAMP)
+ """,
+ autocommit=True,
+ hook_params={"schema": None},
+ )
+
+ @task
+ def query_employees() -> int:
+ """Query employees and return count using Db2Hook."""
+ hook = Db2Hook(conn_id="db2_default")
+ sql = "SELECT employee_id, first_name, last_name, department, salary FROM employees ORDER BY employee_id"
+ records = hook.get_records(sql)
+ return len(records)
+
+ update_salary = SQLExecuteQueryOperator(
+ task_id="update_employee_salary",
+ conn_id="db2_default",
+ sql="""
+ UPDATE employees
+ SET salary = salary * 1.10,
+ updated_at = CURRENT TIMESTAMP
+ WHERE department = 'Engineering'
+ """,
+ autocommit=True,
+ hook_params={"schema": None},
+ )
+
+ calculate_stats = SQLExecuteQueryOperator(
+ task_id="calculate_department_stats",
+ conn_id="db2_default",
+ sql="""
+ SELECT
+ department,
+ COUNT(*) as employee_count,
+ AVG(salary) as avg_salary,
+ MIN(salary) as min_salary,
+ MAX(salary) as max_salary
+ FROM employees
+ GROUP BY department
+ ORDER BY department
+ """,
+ hook_params={"schema": None},
+ )
+
+ @task
+ def display_statistics() -> None:
+ """Display department statistics using Db2Hook."""
+ hook = Db2Hook(conn_id="db2_default")
+ sql = """
+ SELECT
+ department,
+ COUNT(*) as employee_count,
+ AVG(salary) as avg_salary,
+ MIN(salary) as min_salary,
+ MAX(salary) as max_salary
+ FROM employees
+ GROUP BY department
+ ORDER BY department
+ """
+ hook.get_records(sql)
+
+ create_backup = SQLExecuteQueryOperator(
+ task_id="create_backup_table",
+ conn_id="db2_default",
+ sql="""
+ CREATE TABLE employees_backup AS
+ (SELECT * FROM employees)
+ WITH DATA
+ """,
+ autocommit=True,
+ hook_params={"schema": None},
+ )
+
+ @task
+ def verify_backup() -> None:
+ """Verify backup table was created successfully."""
+ hook = Db2Hook(conn_id="db2_default")
+ original_count = hook.get_first("SELECT COUNT(*) FROM employees")[0]
+ backup_count = hook.get_first("SELECT COUNT(*) FROM employees_backup")[0]
+ if original_count != backup_count:
+ raise ValueError(f"Backup verification failed: {original_count} != {backup_count}")
+
+ (
+ cleanup_tables()
+ >> create_table
+ >> insert_data
+ >> query_employees()
+ >> update_salary
+ >> calculate_stats
+ >> display_statistics()
+ >> create_backup
+ >> verify_backup()
+ )
+
+
+from tests_common.test_utils.system_tests import get_test_run
+
+# Needed to run the example Dag with pytest (see: contributing-docs/testing/system_tests.rst)
+test_run = get_test_run(dag)
diff --git a/providers/ibm/db2/tests/unit/__init__.py b/providers/ibm/db2/tests/unit/__init__.py
new file mode 100644
index 0000000000000..5966d6b1d5261
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/tests/unit/ibm/__init__.py b/providers/ibm/db2/tests/unit/ibm/__init__.py
new file mode 100644
index 0000000000000..5966d6b1d5261
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/ibm/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/providers/ibm/db2/tests/unit/ibm/db2/__init__.py b/providers/ibm/db2/tests/unit/ibm/db2/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/ibm/db2/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/providers/ibm/db2/tests/unit/ibm/db2/dialects/__init__.py b/providers/ibm/db2/tests/unit/ibm/db2/dialects/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/ibm/db2/dialects/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/providers/ibm/db2/tests/unit/ibm/db2/dialects/test_db2.py b/providers/ibm/db2/tests/unit/ibm/db2/dialects/test_db2.py
new file mode 100644
index 0000000000000..31709289983f7
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/ibm/db2/dialects/test_db2.py
@@ -0,0 +1,158 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from unittest.mock import MagicMock
+
+import pytest
+
+from airflow.providers.common.sql.hooks.sql import DbApiHook
+from airflow.providers.ibm.db2.dialects.db2 import Db2Dialect
+
+
+class TestDb2Dialect:
+ """Test Db2Dialect functionality."""
+
+ def setup_method(self):
+ """Set up test fixtures."""
+ # Create a mock that passes isinstance check for DbApiHook
+ self.test_db_hook = MagicMock(spec=DbApiHook)
+ # Configure the mock to pass isinstance check
+ self.test_db_hook.__class__ = DbApiHook
+ self.test_db_hook.placeholder = "?"
+ self.test_db_hook.insert_statement_format = "INSERT INTO {} {} VALUES ({})"
+ self.test_db_hook.escape_word_format = '"{}"'
+ self.test_db_hook.escape_column_names = False
+
+ # Mock inspector for primary key detection (default returns ["ID"])
+ mock_inspector = MagicMock()
+ mock_inspector.get_pk_constraint.return_value = {"constrained_columns": ["ID"]}
+ self.test_db_hook.inspector = mock_inspector
+
+ def test_placeholder(self):
+ """Test placeholder property."""
+ assert Db2Dialect(self.test_db_hook).placeholder == "?"
+
+ def test_generate_replace_sql_with_single_primary_key(self):
+ """Test MERGE SQL generation with single primary key."""
+ # Default inspector already returns ["ID"]
+
+ sql = Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, "Alice", 100),
+ target_fields=["ID", "NAME", "VALUE"],
+ )
+
+ # Verify MERGE statement structure
+ assert "MERGE INTO TEST_TABLE AS t" in sql
+ assert "USING (VALUES (?,?,?)) AS s(ID, NAME, VALUE)" in sql
+ assert "ON t.ID = s.ID" in sql
+ assert "WHEN MATCHED THEN UPDATE SET t.NAME = s.NAME, t.VALUE = s.VALUE" in sql
+ assert "WHEN NOT MATCHED THEN INSERT (ID, NAME, VALUE) VALUES (s.ID, s.NAME, s.VALUE)" in sql
+
+ def test_generate_replace_sql_with_composite_key(self):
+ """Test MERGE SQL generation with composite primary key."""
+ # Override inspector to return composite primary key
+ self.test_db_hook.inspector.get_pk_constraint.return_value = {
+ "constrained_columns": ["DEPT_ID", "EMP_ID"]
+ }
+
+ sql = Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, 101, "Alice", 50000),
+ target_fields=["DEPT_ID", "EMP_ID", "NAME", "SALARY"],
+ )
+
+ # Verify composite key in ON clause
+ assert "ON t.DEPT_ID = s.DEPT_ID AND t.EMP_ID = s.EMP_ID" in sql
+
+ # Extract the UPDATE SET clause to verify primary keys are excluded
+ update_clause = sql.split("WHEN MATCHED THEN UPDATE SET")[1].split("WHEN NOT MATCHED")[0]
+
+ # Verify UPDATE excludes primary key columns
+ assert "t.NAME = s.NAME" in update_clause
+ assert "t.SALARY = s.SALARY" in update_clause
+ assert "t.DEPT_ID = s.DEPT_ID" not in update_clause # PK should not be in UPDATE SET
+ assert "t.EMP_ID = s.EMP_ID" not in update_clause # PK should not be in UPDATE SET
+
+ def test_generate_replace_sql_with_replace_index(self):
+ """Test MERGE SQL generation with explicit replace_index."""
+ sql = Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, "Alice", 100),
+ target_fields=["ID", "NAME", "VALUE"],
+ replace_index=["NAME"], # Use NAME as matching column instead of PK
+ )
+
+ # Verify replace_index is used in ON clause
+ assert "ON t.NAME = s.NAME" in sql
+ # Verify UPDATE includes ID and VALUE but not NAME
+ assert "t.ID = s.ID" in sql
+ assert "t.VALUE = s.VALUE" in sql
+
+ def test_generate_replace_sql_no_pk_no_replace_index(self):
+ """Test that MERGE SQL generation fails without primary key or replace_index."""
+ # Override inspector to return no primary key
+ self.test_db_hook.inspector.get_pk_constraint.return_value = {"constrained_columns": []}
+
+ with pytest.raises(ValueError, match="no primary key found and no replace_index provided"):
+ Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, "Alice", 100),
+ target_fields=["ID", "NAME", "VALUE"],
+ )
+
+ def test_generate_replace_sql_no_target_fields(self):
+ """Test that MERGE SQL generation fails without target_fields."""
+ with pytest.raises(ValueError, match="requires column names"):
+ Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, "Alice", 100),
+ target_fields=[],
+ )
+
+ def test_generate_replace_sql_all_columns_are_pk(self):
+ """Test MERGE SQL when all columns are part of primary key (no UPDATE needed)."""
+ # Override inspector to return both columns as PK
+ self.test_db_hook.inspector.get_pk_constraint.return_value = {"constrained_columns": ["ID", "NAME"]}
+
+ sql = Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, "Alice"),
+ target_fields=["ID", "NAME"],
+ )
+
+ # When all columns are PK, there should be no UPDATE clause
+ assert "WHEN MATCHED THEN UPDATE" not in sql
+ # But INSERT should still be present
+ assert "WHEN NOT MATCHED THEN INSERT" in sql
+
+ def test_generate_replace_sql_with_escaped_column_names(self):
+ """Test MERGE SQL generation with escaped column names."""
+ self.test_db_hook.escape_column_names = True
+ # Default inspector already returns ["ID"]
+
+ sql = Db2Dialect(self.test_db_hook).generate_replace_sql(
+ table="TEST_TABLE",
+ values=(1, "Alice", 100),
+ target_fields=["ID", "NAME", "VALUE"],
+ )
+
+ # Verify column names are escaped
+ assert '"ID"' in sql
+ assert '"NAME"' in sql
+ assert '"VALUE"' in sql
diff --git a/providers/ibm/db2/tests/unit/ibm/db2/hooks/__init__.py b/providers/ibm/db2/tests/unit/ibm/db2/hooks/__init__.py
new file mode 100644
index 0000000000000..13a83393a9124
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/ibm/db2/hooks/__init__.py
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
diff --git a/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py b/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py
new file mode 100644
index 0000000000000..bf5bd6d24975c
--- /dev/null
+++ b/providers/ibm/db2/tests/unit/ibm/db2/hooks/test_db2.py
@@ -0,0 +1,305 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Unit tests for DB2Hook."""
+
+from __future__ import annotations
+
+import sys
+from unittest.mock import MagicMock, patch
+
+import pytest
+
+from airflow.models import Connection
+from airflow.providers.ibm.db2.hooks.db2 import Db2Hook
+
+
+class TestDb2Hook:
+ """Test Db2Hook."""
+
+ @pytest.fixture
+ def mock_connection(self):
+ """Create a mock Db2 connection."""
+ conn = Connection(
+ conn_id="db2_default",
+ conn_type="db2",
+ host="localhost",
+ login="db2user",
+ password="db2pass",
+ schema="testdb",
+ port=50000,
+ )
+ return conn
+
+ @pytest.fixture
+ def mock_connection_with_extras(self):
+ """Create a mock Db2 connection with extra parameters."""
+ conn = Connection(
+ conn_id="db2_default",
+ conn_type="db2",
+ host="localhost",
+ login="db2user",
+ password="db2pass",
+ schema="testdb",
+ port=50000,
+ extra='{"ssl": true, "sslcert": "/path/to/cert.pem"}',
+ )
+ return conn
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_get_conn(self, mock_get_connection, mock_connection):
+ """Test get_conn method."""
+ mock_get_connection.return_value = mock_connection
+ mock_ibm_db_dbi = MagicMock()
+ mock_db_conn = MagicMock()
+ mock_ibm_db_dbi.connect.return_value = mock_db_conn
+
+ with patch.dict(sys.modules, {"ibm_db_dbi": mock_ibm_db_dbi}):
+ hook = Db2Hook(db2_conn_id="db2_default")
+ conn = hook.get_conn()
+
+ assert conn == mock_db_conn
+ mock_ibm_db_dbi.connect.assert_called_once()
+ call_args = mock_ibm_db_dbi.connect.call_args[0][0]
+ assert "DATABASE=testdb" in call_args
+ assert "HOSTNAME=localhost" in call_args
+ assert "PORT=50000" in call_args
+ assert "PROTOCOL=TCPIP" in call_args
+ assert "UID=db2user" in call_args
+ assert "PWD=db2pass" in call_args
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_get_conn_with_ssl(self, mock_get_connection, mock_connection_with_extras):
+ """Test get_conn method with SSL configuration."""
+ mock_get_connection.return_value = mock_connection_with_extras
+ mock_ibm_db_dbi = MagicMock()
+ mock_db_conn = MagicMock()
+ mock_ibm_db_dbi.connect.return_value = mock_db_conn
+
+ with patch.dict(sys.modules, {"ibm_db_dbi": mock_ibm_db_dbi}):
+ hook = Db2Hook(db2_conn_id="db2_default")
+ conn = hook.get_conn()
+
+ assert conn == mock_db_conn
+ mock_ibm_db_dbi.connect.assert_called_once()
+ call_args = mock_ibm_db_dbi.connect.call_args[0][0]
+ assert "SSL=true" in call_args
+ assert "SSLCERT=/path/to/cert.pem" in call_args
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_get_uri(self, mock_get_connection, mock_connection):
+ """Test get_uri method."""
+ mock_get_connection.return_value = mock_connection
+
+ hook = Db2Hook(db2_conn_id="db2_default")
+ uri = hook.get_uri()
+
+ # Verify URI format
+ assert uri == "db2+ibm_db://db2user:db2pass@localhost:50000/testdb"
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_get_uri_with_special_chars_in_password(self, mock_get_connection):
+ """Test get_uri method with special characters in password."""
+ conn = Connection(
+ conn_id="db2_default",
+ conn_type="db2",
+ host="localhost",
+ login="db2user",
+ password="p@ss:word!",
+ schema="testdb",
+ port=50000,
+ )
+ mock_get_connection.return_value = conn
+
+ hook = Db2Hook(db2_conn_id="db2_default")
+ uri = hook.get_uri()
+
+ # Verify password is URL encoded
+ assert "p%40ss%3Aword%21" in uri
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_get_uri_with_defaults(self, mock_get_connection):
+ """Test get_uri method with default values."""
+ conn = Connection(
+ conn_id="db2_default",
+ conn_type="db2",
+ host="",
+ login="",
+ password="",
+ schema="",
+ port=None,
+ )
+ mock_get_connection.return_value = conn
+
+ hook = Db2Hook(db2_conn_id="db2_default")
+ uri = hook.get_uri()
+
+ # Verify URI uses defaults
+ assert uri == "db2+ibm_db://:@localhost:50000/"
+
+ def test_hook_attributes(self):
+ """Test hook class attributes."""
+ assert Db2Hook.conn_name_attr == "db2_conn_id"
+ assert Db2Hook.default_conn_name == "db2_default"
+ assert Db2Hook.conn_type == "ibmdb2"
+ assert Db2Hook.hook_name == "IBM Db2"
+ assert Db2Hook.supports_autocommit is True
+ assert Db2Hook.supports_executemany is True
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_column_names_excludes_identity_columns(self, mock_engine, mock_get_conn, mock_connection):
+ """Test that get_column_names() excludes identity columns (autoincrement=True)."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ # Mock inspector to return columns with autoincrement flag
+ mock_inspector = MagicMock()
+ mock_inspector.get_columns.return_value = [
+ {"name": "ID", "autoincrement": True}, # Identity column - should be excluded
+ {"name": "NAME", "autoincrement": False},
+ {"name": "VALUE", "autoincrement": False},
+ ]
+
+ with patch.object(hook, "inspector", mock_inspector):
+ columns = hook.get_column_names("TEST_TABLE")
+
+ # Verify identity column is excluded
+ assert columns == ["NAME", "VALUE"]
+ assert "ID" not in columns
+ mock_inspector.get_columns.assert_called_once_with("TEST_TABLE", schema=None)
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_column_names_includes_all_when_no_identity(
+ self, mock_engine, mock_get_conn, mock_connection
+ ):
+ """Test that get_column_names() includes all columns when none are identity columns."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ # Mock inspector to return columns without autoincrement
+ mock_inspector = MagicMock()
+ mock_inspector.get_columns.return_value = [
+ {"name": "ID", "autoincrement": False},
+ {"name": "NAME", "autoincrement": False},
+ {"name": "VALUE", "autoincrement": False},
+ ]
+
+ with patch.object(hook, "inspector", mock_inspector):
+ columns = hook.get_column_names("TEST_TABLE")
+
+ # Verify all columns are included
+ assert columns == ["ID", "NAME", "VALUE"]
+ mock_inspector.get_columns.assert_called_once_with("TEST_TABLE", schema=None)
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_column_names_with_schema(self, mock_engine, mock_get_conn, mock_connection):
+ """Test that get_column_names() passes schema parameter correctly."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ mock_inspector = MagicMock()
+ mock_inspector.get_columns.return_value = [
+ {"name": "COL1", "autoincrement": False},
+ {"name": "COL2", "autoincrement": False},
+ ]
+
+ with patch.object(hook, "inspector", mock_inspector):
+ columns = hook.get_column_names("TEST_TABLE", schema="MY_SCHEMA")
+
+ assert columns == ["COL1", "COL2"]
+ mock_inspector.get_columns.assert_called_once_with("TEST_TABLE", schema="MY_SCHEMA")
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_primary_keys_single(self, mock_engine, mock_get_conn, mock_connection):
+ """Test get_primary_keys() with single primary key."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ # Mock inspector to return single primary key
+ mock_inspector = MagicMock()
+ mock_inspector.get_pk_constraint.return_value = {"constrained_columns": ["ID"]}
+
+ with patch.object(hook, "inspector", mock_inspector):
+ pk_columns = hook.get_primary_keys("TEST_TABLE")
+
+ assert pk_columns == ["ID"]
+ mock_inspector.get_pk_constraint.assert_called_once_with("TEST_TABLE", schema=None)
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_primary_keys_composite(self, mock_engine, mock_get_conn, mock_connection):
+ """Test get_primary_keys() with composite primary key."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ # Mock inspector to return composite primary key
+ mock_inspector = MagicMock()
+ mock_inspector.get_pk_constraint.return_value = {"constrained_columns": ["DEPT_ID", "EMP_ID"]}
+
+ with patch.object(hook, "inspector", mock_inspector):
+ pk_columns = hook.get_primary_keys("TEST_TABLE")
+
+ assert pk_columns == ["DEPT_ID", "EMP_ID"]
+ assert len(pk_columns) == 2
+ mock_inspector.get_pk_constraint.assert_called_once_with("TEST_TABLE", schema=None)
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_primary_keys_with_schema(self, mock_engine, mock_get_conn, mock_connection):
+ """Test that get_primary_keys() passes schema parameter correctly."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ mock_inspector = MagicMock()
+ mock_inspector.get_pk_constraint.return_value = {"constrained_columns": ["ID"]}
+
+ with patch.object(hook, "inspector", mock_inspector):
+ pk_columns = hook.get_primary_keys("TEST_TABLE", schema="MY_SCHEMA")
+
+ assert pk_columns == ["ID"]
+ mock_inspector.get_pk_constraint.assert_called_once_with("TEST_TABLE", schema="MY_SCHEMA")
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_sqlalchemy_engine")
+ def test_get_primary_keys_no_pk(self, mock_engine, mock_get_conn, mock_connection):
+ """Test get_primary_keys() when table has no primary key."""
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ # Mock inspector to return empty primary key
+ mock_inspector = MagicMock()
+ mock_inspector.get_pk_constraint.return_value = {"constrained_columns": []}
+
+ with patch.object(hook, "inspector", mock_inspector):
+ pk_columns = hook.get_primary_keys("TEST_TABLE")
+
+ assert pk_columns == []
+ mock_inspector.get_pk_constraint.assert_called_once_with("TEST_TABLE", schema=None)
+
+ @patch("airflow.providers.ibm.db2.hooks.db2.Db2Hook.get_connection")
+ def test_dialect_property(self, mock_get_conn, mock_connection):
+ """Test that hook has Db2Dialect."""
+ from airflow.providers.ibm.db2.dialects.db2 import Db2Dialect
+
+ mock_get_conn.return_value = mock_connection
+ hook = Db2Hook(db2_conn_id="db2_default")
+
+ assert hook.dialect_name == "db2"
+ assert isinstance(hook.dialect, Db2Dialect)
diff --git a/providers/ibm/mq/src/airflow/providers/ibm/__init__.py b/providers/ibm/mq/src/airflow/providers/ibm/__init__.py
index e8fd22856438c..5966d6b1d5261 100644
--- a/providers/ibm/mq/src/airflow/providers/ibm/__init__.py
+++ b/providers/ibm/mq/src/airflow/providers/ibm/__init__.py
@@ -14,4 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore
+__path__ = __import__("pkgutil").extend_path(__path__, __name__)
diff --git a/pyproject.toml b/pyproject.toml
index f95b254b0d1de..735379b73c70f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -257,6 +257,9 @@ apache-airflow = "airflow.__main__:main"
"http" = [
"apache-airflow-providers-http>=4.13.2"
]
+"ibm.db2" = [
+ "apache-airflow-providers-ibm-db2>=0.1.0"
+]
"ibm.mq" = [
"apache-airflow-providers-ibm-mq>=0.1.0; platform_machine !=\"aarch64\" and platform_machine !=\"arm64\""
]
@@ -466,6 +469,7 @@ apache-airflow = "airflow.__main__:main"
"apache-airflow-providers-grpc>=3.7.0",
"apache-airflow-providers-hashicorp>=4.0.0",
"apache-airflow-providers-http>=4.13.2",
+ "apache-airflow-providers-ibm-db2>=0.1.0",
"apache-airflow-providers-ibm-mq>=0.1.0; platform_machine !=\"aarch64\" and platform_machine !=\"arm64\"",
"apache-airflow-providers-imap>=3.8.0",
"apache-airflow-providers-influxdb>=2.8.0",
@@ -1198,6 +1202,8 @@ mypy_path = [
"$MYPY_CONFIG_FILE_DIR/providers/hashicorp/tests",
"$MYPY_CONFIG_FILE_DIR/providers/http/src",
"$MYPY_CONFIG_FILE_DIR/providers/http/tests",
+ "$MYPY_CONFIG_FILE_DIR/providers/ibm/db2/src",
+ "$MYPY_CONFIG_FILE_DIR/providers/ibm/db2/tests",
"$MYPY_CONFIG_FILE_DIR/providers/ibm/mq/src",
"$MYPY_CONFIG_FILE_DIR/providers/ibm/mq/tests",
"$MYPY_CONFIG_FILE_DIR/providers/imap/src",
@@ -1490,6 +1496,7 @@ apache-airflow-providers-google = false
apache-airflow-providers-grpc = false
apache-airflow-providers-hashicorp = false
apache-airflow-providers-http = false
+apache-airflow-providers-ibm-db2 = false
apache-airflow-providers-ibm-mq = false
apache-airflow-providers-imap = false
apache-airflow-providers-influxdb = false
@@ -1642,6 +1649,7 @@ apache-airflow-providers-google = false
apache-airflow-providers-grpc = false
apache-airflow-providers-hashicorp = false
apache-airflow-providers-http = false
+apache-airflow-providers-ibm-db2 = false
apache-airflow-providers-ibm-mq = false
apache-airflow-providers-imap = false
apache-airflow-providers-influxdb = false
@@ -1805,6 +1813,7 @@ apache-airflow-providers-google = { workspace = true }
apache-airflow-providers-grpc = { workspace = true }
apache-airflow-providers-hashicorp = { workspace = true }
apache-airflow-providers-http = { workspace = true }
+apache-airflow-providers-ibm-db2 = { workspace = true }
apache-airflow-providers-ibm-mq = { workspace = true }
apache-airflow-providers-imap = { workspace = true }
apache-airflow-providers-influxdb = { workspace = true }
@@ -1946,6 +1955,7 @@ members = [
"providers/grpc",
"providers/hashicorp",
"providers/http",
+ "providers/ibm/db2",
"providers/ibm/mq",
"providers/imap",
"providers/influxdb",
diff --git a/scripts/ci/docker-compose/remove-sources.yml b/scripts/ci/docker-compose/remove-sources.yml
index edb644a179a19..39602e0fb2cf7 100644
--- a/scripts/ci/docker-compose/remove-sources.yml
+++ b/scripts/ci/docker-compose/remove-sources.yml
@@ -80,6 +80,7 @@ services:
- ../../../empty:/opt/airflow/providers/grpc/src
- ../../../empty:/opt/airflow/providers/hashicorp/src
- ../../../empty:/opt/airflow/providers/http/src
+ - ../../../empty:/opt/airflow/providers/ibm/db2/src
- ../../../empty:/opt/airflow/providers/ibm/mq/src
- ../../../empty:/opt/airflow/providers/imap/src
- ../../../empty:/opt/airflow/providers/influxdb/src
diff --git a/scripts/ci/docker-compose/tests-sources.yml b/scripts/ci/docker-compose/tests-sources.yml
index eb700548346da..e7a5a5a927d28 100644
--- a/scripts/ci/docker-compose/tests-sources.yml
+++ b/scripts/ci/docker-compose/tests-sources.yml
@@ -93,6 +93,7 @@ services:
- ../../../providers/grpc/tests:/opt/airflow/providers/grpc/tests
- ../../../providers/hashicorp/tests:/opt/airflow/providers/hashicorp/tests
- ../../../providers/http/tests:/opt/airflow/providers/http/tests
+ - ../../../providers/ibm/db2/tests:/opt/airflow/providers/ibm/db2/tests
- ../../../providers/ibm/mq/tests:/opt/airflow/providers/ibm/mq/tests
- ../../../providers/imap/tests:/opt/airflow/providers/imap/tests
- ../../../providers/influxdb/tests:/opt/airflow/providers/influxdb/tests
diff --git a/uv.lock b/uv.lock
index 8b5cea2e6a4a0..88104ab5701e3 100644
--- a/uv.lock
+++ b/uv.lock
@@ -64,9 +64,9 @@ apache-airflow-providers-apache-cassandra = false
apache-airflow-providers-asana = false
apache-airflow-providers-oracle = false
apache-airflow-providers-mysql = false
+apache-airflow-providers-teradata = false
apache-airflow-providers-alibaba = false
apache-airflow-providers-microsoft-mssql = false
-apache-airflow-providers-teradata = false
apache-airflow-providers-jdbc = false
apache-airflow-helm-chart = false
apache-airflow-providers-anthropic = false
@@ -138,6 +138,7 @@ apache-airflow-providers-singularity = false
apache-airflow-providers-common-compat = false
apache-airflow-ctl-tests = false
apache-airflow-providers-tableau = false
+apache-airflow-providers-ibm-db2 = false
apache-airflow-providers-common-sql = false
apache-airflow-shared-configuration = false
apache-airflow-providers-facebook = false
@@ -227,6 +228,7 @@ members = [
"apache-airflow-providers-grpc",
"apache-airflow-providers-hashicorp",
"apache-airflow-providers-http",
+ "apache-airflow-providers-ibm-db2",
"apache-airflow-providers-ibm-mq",
"apache-airflow-providers-imap",
"apache-airflow-providers-influxdb",
@@ -330,7 +332,7 @@ name = "adbc-driver-manager"
version = "1.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "typing-extensions" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e9/5e/50aab18cb501e42d3aca3cd2cc26c6637094fcaf5b6576e350c444188f1f/adbc_driver_manager-1.11.0.tar.gz", hash = "sha256:c64aaabeb5810109ab3d2961008f1b014e9f2d87b3df4416c2a080a40237af50", size = 233059, upload-time = "2026-04-07T00:17:28.263Z" }
wheels = [
@@ -375,8 +377,8 @@ name = "adbc-driver-postgresql"
version = "1.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "adbc-driver-manager" },
- { name = "importlib-resources" },
+ { name = "adbc-driver-manager", marker = "python_full_version < '3.13'" },
+ { name = "importlib-resources", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/68/10/2962c25035887cd03af3b348eac3302493936f45048c220021a802d07f12/adbc_driver_postgresql-1.11.0.tar.gz", hash = "sha256:f5688b8648ac7a86d8b89340231bb3686ac5df56ee95d1ca0b875dad5d52b48a", size = 32328, upload-time = "2026-04-07T00:17:29.232Z" }
wheels = [
@@ -392,8 +394,8 @@ name = "adbc-driver-sqlite"
version = "1.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "adbc-driver-manager" },
- { name = "importlib-resources" },
+ { name = "adbc-driver-manager", marker = "python_full_version < '3.13'" },
+ { name = "importlib-resources", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3a/dd/8a5f4908aa4bdec64dcd672734fa314d692517458ce169591639d0123fe1/adbc_driver_sqlite-1.11.0.tar.gz", hash = "sha256:a4c6b4962610f7cd67cd754c42dd74e18a2c11fabeec9488c5501d73ae62dc62", size = 28885, upload-time = "2026-04-07T00:17:31.325Z" }
wheels = [
@@ -456,7 +458,7 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "caio" },
+ { name = "caio", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/67/e2/d7cb819de8df6b5c1968a2756c3cb4122d4fa2b8fc768b53b7c9e5edb646/aiofile-3.9.0.tar.gz", hash = "sha256:e5ad718bb148b265b6df1b3752c4d1d83024b93da9bd599df74b9d9ffcf7919b", size = 17943, upload-time = "2024-10-08T10:39:35.846Z" }
wheels = [
@@ -480,7 +482,7 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "caio" },
+ { name = "caio", marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/48/41/2fea7e193e061ce54eacc3b7bc0e6a99e4fcff43c78cf0a76dd781ed8334/aiofile-3.11.1.tar.gz", hash = "sha256:1f91912c6643d2a4e49ca4ae3514f0bf3867ce948a36d99a6411b8f4755f4cf9", size = 19342, upload-time = "2026-05-16T08:18:33.538Z" }
wheels = [
@@ -1054,6 +1056,7 @@ all = [
{ name = "apache-airflow-providers-grpc" },
{ name = "apache-airflow-providers-hashicorp" },
{ name = "apache-airflow-providers-http" },
+ { name = "apache-airflow-providers-ibm-db2" },
{ name = "apache-airflow-providers-ibm-mq", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64'" },
{ name = "apache-airflow-providers-imap" },
{ name = "apache-airflow-providers-influxdb" },
@@ -1297,6 +1300,9 @@ hashicorp = [
http = [
{ name = "apache-airflow-providers-http" },
]
+ibm-db2 = [
+ { name = "apache-airflow-providers-ibm-db2" },
+]
ibm-mq = [
{ name = "apache-airflow-providers-ibm-mq", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64'" },
]
@@ -1680,6 +1686,8 @@ requires-dist = [
{ name = "apache-airflow-providers-hashicorp", marker = "extra == 'hashicorp'", editable = "providers/hashicorp" },
{ name = "apache-airflow-providers-http", marker = "extra == 'all'", editable = "providers/http" },
{ name = "apache-airflow-providers-http", marker = "extra == 'http'", editable = "providers/http" },
+ { name = "apache-airflow-providers-ibm-db2", marker = "extra == 'all'", editable = "providers/ibm/db2" },
+ { name = "apache-airflow-providers-ibm-db2", marker = "extra == 'ibm-db2'", editable = "providers/ibm/db2" },
{ name = "apache-airflow-providers-ibm-mq", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and extra == 'all'", editable = "providers/ibm/mq" },
{ name = "apache-airflow-providers-ibm-mq", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and extra == 'ibm-mq'", editable = "providers/ibm/mq" },
{ name = "apache-airflow-providers-imap", marker = "extra == 'all'", editable = "providers/imap" },
@@ -1792,7 +1800,7 @@ requires-dist = [
{ name = "sentry-sdk", marker = "extra == 'sentry'", specifier = ">=2.30.0" },
{ name = "uv", marker = "extra == 'uv'", specifier = ">=0.11.29" },
]
-provides-extras = ["all-core", "async", "graphviz", "gunicorn", "kerberos", "memray", "otel", "statsd", "all-task-sdk", "airbyte", "akeyless", "alibaba", "amazon", "anthropic", "apache-cassandra", "apache-drill", "apache-druid", "apache-flink", "apache-hdfs", "apache-hive", "apache-iceberg", "apache-impala", "apache-kafka", "apache-kylin", "apache-livy", "apache-pig", "apache-pinot", "apache-spark", "apache-tinkerpop", "apprise", "arangodb", "asana", "atlassian-jira", "celery", "clickhousedb", "cloudant", "cncf-kubernetes", "cohere", "common-ai", "common-compat", "common-dataquality", "common-io", "common-messaging", "common-sql", "databricks", "datadog", "dbt-cloud", "dingding", "discord", "docker", "edge3", "elasticsearch", "exasol", "fab", "facebook", "ftp", "git", "github", "google", "grpc", "hashicorp", "http", "ibm-mq", "imap", "influxdb", "informatica", "jdbc", "jenkins", "keycloak", "microsoft-azure", "microsoft-mssql", "microsoft-psrp", "microsoft-winrm", "mongo", "mysql", "neo4j", "odbc", "openai", "openfaas", "openlineage", "opensearch", "opsgenie", "oracle", "pagerduty", "papermill", "pgvector", "pinecone", "postgres", "presto", "qdrant", "redis", "salesforce", "samba", "segment", "sendgrid", "sftp", "singularity", "slack", "smtp", "snowflake", "sqlite", "ssh", "standard", "tableau", "telegram", "teradata", "trino", "vertica", "vespa", "weaviate", "yandex", "ydb", "zendesk", "all", "aiobotocore", "apache-atlas", "apache-webhdfs", "amazon-aws-auth", "cloudpickle", "github-enterprise", "google-auth", "ldap", "pandas", "polars", "rabbitmq", "sentry", "s3fs", "uv"]
+provides-extras = ["all-core", "async", "graphviz", "gunicorn", "kerberos", "memray", "otel", "statsd", "all-task-sdk", "airbyte", "akeyless", "alibaba", "amazon", "anthropic", "apache-cassandra", "apache-drill", "apache-druid", "apache-flink", "apache-hdfs", "apache-hive", "apache-iceberg", "apache-impala", "apache-kafka", "apache-kylin", "apache-livy", "apache-pig", "apache-pinot", "apache-spark", "apache-tinkerpop", "apprise", "arangodb", "asana", "atlassian-jira", "celery", "clickhousedb", "cloudant", "cncf-kubernetes", "cohere", "common-ai", "common-compat", "common-dataquality", "common-io", "common-messaging", "common-sql", "databricks", "datadog", "dbt-cloud", "dingding", "discord", "docker", "edge3", "elasticsearch", "exasol", "fab", "facebook", "ftp", "git", "github", "google", "grpc", "hashicorp", "http", "ibm-db2", "ibm-mq", "imap", "influxdb", "informatica", "jdbc", "jenkins", "keycloak", "microsoft-azure", "microsoft-mssql", "microsoft-psrp", "microsoft-winrm", "mongo", "mysql", "neo4j", "odbc", "openai", "openfaas", "openlineage", "opensearch", "opsgenie", "oracle", "pagerduty", "papermill", "pgvector", "pinecone", "postgres", "presto", "qdrant", "redis", "salesforce", "samba", "segment", "sendgrid", "sftp", "singularity", "slack", "smtp", "snowflake", "sqlite", "ssh", "standard", "tableau", "telegram", "teradata", "trino", "vertica", "vespa", "weaviate", "yandex", "ydb", "zendesk", "all", "aiobotocore", "apache-atlas", "apache-webhdfs", "amazon-aws-auth", "cloudpickle", "github-enterprise", "google-auth", "ldap", "pandas", "polars", "rabbitmq", "sentry", "s3fs", "uv"]
[package.metadata.requires-dev]
ci-image = [
@@ -5957,6 +5965,56 @@ dev = [
]
docs = [{ name = "apache-airflow-devel-common", extras = ["docs"], editable = "devel-common" }]
+[[package]]
+name = "apache-airflow-providers-ibm-db2"
+version = "0.1.0"
+source = { editable = "providers/ibm/db2" }
+dependencies = [
+ { name = "apache-airflow" },
+ { name = "apache-airflow-providers-common-compat" },
+ { name = "apache-airflow-providers-common-sql" },
+ { name = "ibm-db" },
+ { name = "ibm-db-sa" },
+ { name = "methodtools" },
+]
+
+[package.optional-dependencies]
+openlineage = [
+ { name = "apache-airflow-providers-openlineage" },
+]
+
+[package.dev-dependencies]
+dev = [
+ { name = "apache-airflow" },
+ { name = "apache-airflow-devel-common" },
+ { name = "apache-airflow-providers-common-sql" },
+ { name = "apache-airflow-task-sdk" },
+]
+docs = [
+ { name = "apache-airflow-devel-common", extra = ["docs"] },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "apache-airflow", editable = "." },
+ { name = "apache-airflow-providers-common-compat", editable = "providers/common/compat" },
+ { name = "apache-airflow-providers-common-sql", editable = "providers/common/sql" },
+ { name = "apache-airflow-providers-openlineage", marker = "extra == 'openlineage'", editable = "providers/openlineage" },
+ { name = "ibm-db", specifier = ">=3.2.0" },
+ { name = "ibm-db-sa", specifier = ">=0.4.0" },
+ { name = "methodtools", specifier = ">=0.4.7" },
+]
+provides-extras = ["openlineage"]
+
+[package.metadata.requires-dev]
+dev = [
+ { name = "apache-airflow", editable = "." },
+ { name = "apache-airflow-devel-common", editable = "devel-common" },
+ { name = "apache-airflow-providers-common-sql", editable = "providers/common/sql" },
+ { name = "apache-airflow-task-sdk", editable = "task-sdk" },
+]
+docs = [{ name = "apache-airflow-devel-common", extras = ["docs"], editable = "devel-common" }]
+
[[package]]
name = "apache-airflow-providers-ibm-mq"
version = "0.1.0"
@@ -10446,8 +10504,8 @@ name = "cassandra-driver"
version = "3.30.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "deprecated" },
- { name = "geomet" },
+ { name = "deprecated", marker = "python_full_version < '3.14'" },
+ { name = "geomet", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bb/ed/4e16210e194660f107929ee494f1cf18557252655067d9b39029c241be2d/cassandra_driver-3.30.1.tar.gz", hash = "sha256:0c6a3e1428f7c6a9aa6c944b9c47a37cd2cdbeb5b5a82d42c33afdd56f14e398", size = 289233, upload-time = "2026-07-06T20:14:31.37Z" }
wheels = [
@@ -11953,11 +12011,11 @@ wheels = [
[[package]]
name = "fastcore"
-version = "2.1.1"
+version = "2.1.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a4/2b/5691f537eed8d372d8e08f13327ef9b9fe1982fef645640e18a10fff4017/fastcore-2.1.1.tar.gz", hash = "sha256:56b8ec133b38a731e3ada6e6640f50ca4efb92fb7ac9a7302affebcb772ec4cc", size = 104387, upload-time = "2026-07-16T05:13:53.671Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/98/64/8eebd9043c19d4cf3920609c17fdbb01b1ce96f676f314aa4e7c928cb2ca/fastcore-2.1.2.tar.gz", hash = "sha256:5fead0e2093a781d3cb76762db3d6cd5a7d6b88add6a76aeb6d42b203e2654d3", size = 107317, upload-time = "2026-07-19T02:37:28.819Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/9c/05/9e8e61894958099264f9a74da781bc3127d30a616796fe3297a06059d35d/fastcore-2.1.1-py3-none-any.whl", hash = "sha256:59f475f815a4718d4c49f42dd69a0dba9f9c28666957156b56868789b37651e7", size = 109272, upload-time = "2026-07-16T05:13:52.037Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/a7/0b886b72939f9826b6fd2a14d7f486394eb18d4a6f6a1245ce37861f934e/fastcore-2.1.2-py3-none-any.whl", hash = "sha256:bf59346591b10f077ade16884f3d3356f6ff306e0ce2f4beb9ffb5d294e0d71d", size = 112225, upload-time = "2026-07-19T02:37:27.063Z" },
]
[[package]]
@@ -12495,7 +12553,7 @@ name = "geomet"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "click" },
+ { name = "click", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2a/8c/dde022aa6747b114f6b14a7392871275dea8867e2bd26cddb80cc6d66620/geomet-1.1.0.tar.gz", hash = "sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605", size = 28732, upload-time = "2023-11-14T15:43:36.764Z" }
wheels = [
@@ -13291,28 +13349,20 @@ wheels = [
[[package]]
name = "google-cloud-spanner"
-version = "3.69.0"
+version = "3.59.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "google-api-core", extra = ["grpc"] },
- { name = "google-auth" },
{ name = "google-cloud-core" },
- { name = "google-cloud-monitoring" },
{ name = "grpc-google-iam-v1" },
{ name = "grpc-interceptor" },
- { name = "grpcio" },
- { name = "mmh3" },
- { name = "opentelemetry-api" },
- { name = "opentelemetry-resourcedetector-gcp" },
- { name = "opentelemetry-sdk" },
- { name = "opentelemetry-semantic-conventions" },
{ name = "proto-plus" },
{ name = "protobuf" },
{ name = "sqlparse" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/b7/78/0e3f0c59b38c31287c48c5b0f91976ec0fb0f0f244f8f8c4d1856db7a64f/google_cloud_spanner-3.69.0.tar.gz", hash = "sha256:e274dd63957db3c453bda20d25d9dc42662f2e58f53957bc3706811b3d539484", size = 904828, upload-time = "2026-06-25T23:39:49.976Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/df/62/f0e535875e49b34128710342115681fe1a97f45759e1427307ab150a4caa/google_cloud_spanner-3.59.0.tar.gz", hash = "sha256:dec7a78bfe1f94aef508ff9c61dba4196f3c70c83a0f75c271b4652686d08641", size = 705137, upload-time = "2025-10-23T09:35:49.885Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/7f/60/433929de67b12165c212bed01c976d9b79707500c521d343c1fb73e6ebc7/google_cloud_spanner-3.69.0-py3-none-any.whl", hash = "sha256:5efc8bc346fa4958135f43cd68c78cfcfa2c13aaa6bf162fa8b56943ca288ae8", size = 620018, upload-time = "2026-06-25T23:39:19.192Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/08/1a38139853364b4737e3a0e03a3fd87d60c7545e90a963a8a6457777b5f9/google_cloud_spanner-3.59.0-py3-none-any.whl", hash = "sha256:409ed9746787c9435fd015731a5e3cf6f3ea2995a807c580f4216bb5d464260a", size = 502645, upload-time = "2025-10-23T09:35:47.954Z" },
]
[[package]]
@@ -13928,7 +13978,7 @@ name = "gssapi"
version = "1.11.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "decorator" },
+ { name = "decorator", marker = "python_full_version < '3.15' or sys_platform != 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/23/52/c1e90623c259a42ab0587078bb04f959867b970add46ff66750ead8fc7c5/gssapi-1.11.1.tar.gz", hash = "sha256:2049ee4b1d0c363163a1344b7282a363f9f4094e51d2c36de0cf01d4735e0ae2", size = 95233, upload-time = "2026-01-26T21:01:39.463Z" }
wheels = [
@@ -14340,6 +14390,58 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/85/a0/0c159147c6bb2617d01a1cba3601db4ae025a2b46effdfe76d4be834efa8/ibm_cloud_sdk_core-3.25.0-py3-none-any.whl", hash = "sha256:4660ff545a4f9a22335f5a3670764c162f82ebb8d195293f159ecfdf91b617db", size = 76401, upload-time = "2026-06-19T19:36:37.629Z" },
]
+[[package]]
+name = "ibm-db"
+version = "3.2.9"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/6c/36/8cd1503b7f947293bb045ec86e6fa60a0bef3bacf1a601840ea65c4b78de/ibm_db-3.2.9.tar.gz", hash = "sha256:0ad6dc4575519a5563fd7f845fc6bc00d688020e1d3ae78d382e79183bc32b0b", size = 276595, upload-time = "2026-05-26T15:41:25.98Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bf/cc/4db3062ce3b404098e73ec67498b25c672b212303a870c2703ac8f9a00c6/ibm_db-3.2.9-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:e130a461a0ce3fecdb9896ec767d95d89d4f14e5eb4b8b5e63aca249790c5155", size = 24166574, upload-time = "2026-04-22T16:27:50.985Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/62/98bd8e55a9a2fdd20997bd81e8d8f68b8956fa55d8c2c0cae2fd94ccd2f5/ibm_db-3.2.9-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:4edde94384f452720b6bc58b94ed03c9b3f5dadb7343d983a55c1122b4a38cf0", size = 20391416, upload-time = "2026-04-22T16:27:54.236Z" },
+ { url = "https://files.pythonhosted.org/packages/14/be/6f95944b3052b288e5842141f334633c900ba3320f8534a8f80f657ffbde/ibm_db-3.2.9-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:80c2e242601ff2e99bce79da0fddc6e0e525b1f83d05423f00524bad5c41991e", size = 40635334, upload-time = "2026-04-22T16:27:56.746Z" },
+ { url = "https://files.pythonhosted.org/packages/89/85/571df0152cb8632e99f7923599b94fd2139f01f9e9d6ca92345f75223e9e/ibm_db-3.2.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0838993f2e98827afa9f30a1a4648bdadccabb6f9f6805ee42f24787a6ae45b7", size = 43980561, upload-time = "2026-04-22T16:27:59.973Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/4d/73602f4decf4c3f2f21079108cd5b43336db8c608c16aba8afd2578aa474/ibm_db-3.2.9-cp310-cp310-win32.whl", hash = "sha256:825f1ab7d911daef6ca370af62608d663e2193244832cad8dabbfa9708e81bdb", size = 24609207, upload-time = "2026-04-22T16:28:03.043Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/22/8d558528e019bdd595290ba109f837b17d476bf4fbeed46e4980b052a961/ibm_db-3.2.9-cp310-cp310-win_amd64.whl", hash = "sha256:b163dd252f695113851a3d480289f8b368885835fe3296e8b202063440fe34c8", size = 28754450, upload-time = "2026-04-22T16:28:05.536Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/47/992fe2d1157963df678d94cc2573e4e292d6e29c2c47fb069a36f16e3c90/ibm_db-3.2.9-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:b72049768de33e0767e7ca4f5cf9c44812a6422c8a4e07bb07fd30c242f555b2", size = 24166574, upload-time = "2026-04-22T16:28:08.538Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/27/628276aff846d1afa4680106ef7905916b12f32855c95540c638184203ec/ibm_db-3.2.9-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a002be22327f29e1f6cf48b7ee84843e6a257bb7a2f7d017caa6e731aaea4e5a", size = 20391417, upload-time = "2026-04-22T16:28:11.392Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/a5/3adf8573468a18f3c82fc41c949326a500ee0335f0290e90b565722eacc0/ibm_db-3.2.9-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:5831070fe9e6b2654668cfada10fb31a64e7555a7ef35e04e17ca831822df3bb", size = 40641529, upload-time = "2026-04-22T16:28:13.944Z" },
+ { url = "https://files.pythonhosted.org/packages/12/9d/9c0c4cf2eacfdfd5faf2f878ca1e2fdb02640a21f3defa2390c0d41c85cc/ibm_db-3.2.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ec172bc1c61ac15cb98ebe1a2737689752b6565a2afa9c4442a09129f2ada963", size = 43987216, upload-time = "2026-04-22T16:28:17.083Z" },
+ { url = "https://files.pythonhosted.org/packages/05/c4/13723b51f6b560f44f146518e52b81c47e4a748d118e45f1ae3a5b496855/ibm_db-3.2.9-cp311-cp311-win32.whl", hash = "sha256:8aaefd0162f7c500af87b39593eeec126312cbebf6c4ff7c3051eeb9e8b7f47d", size = 24609273, upload-time = "2026-04-22T16:28:19.767Z" },
+ { url = "https://files.pythonhosted.org/packages/34/ef/b3dba8a536b8be36086c05f2d6903593aea7e9aef10c32bb7fabc7292660/ibm_db-3.2.9-cp311-cp311-win_amd64.whl", hash = "sha256:82517f76253ba3153aa8a43073cf9230a487974a660f3cf99bd4adda41910407", size = 28754305, upload-time = "2026-04-22T16:28:22.521Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/19/e4664a631cf69c2aa6684c03073b732ccbd41ed440a9d5d94f3700b979cb/ibm_db-3.2.9-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:5432ef9103c094631ebb7e534a72dfd8324f265c3695e79698eb5c09fa28cddb", size = 24166563, upload-time = "2026-04-22T16:28:25.312Z" },
+ { url = "https://files.pythonhosted.org/packages/40/23/5f9388f5ee2148a0ca5c372c4124415bbf7aaba5b64cd13ef5fb801becde/ibm_db-3.2.9-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d4b650ac1e3a9161090234821a655adb767baa52764e839c1a5ff306cd967de5", size = 20391654, upload-time = "2026-04-22T16:28:27.865Z" },
+ { url = "https://files.pythonhosted.org/packages/77/02/e1226db9f19ae1672098027cbb0fab7bea8c29e9b802e4337a9651595c09/ibm_db-3.2.9-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4b3d8d707a9cf3bf633c7742fffc557d9c71e6555f0c9733a0f9b8ed7f874ffe", size = 40606621, upload-time = "2026-04-22T16:28:30.411Z" },
+ { url = "https://files.pythonhosted.org/packages/23/26/3bf46353bb850d0ab71b8f9cc396da4e76d41e54abad26bc5f2fed95c8f7/ibm_db-3.2.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e60e1a12fa8e36510384944e1b438e6e9a353bc92d1d496a66acc8e1cb853a5e", size = 43945644, upload-time = "2026-04-22T16:28:33.351Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/75/c0506dc89c4da674adb40aa038729b1513d90a1ef3e2e6e34faaa00a5981/ibm_db-3.2.9-cp312-cp312-win32.whl", hash = "sha256:a0b395c0f770627bbb6765f45d9fe99ed990fc4801c1adeeaa872d599ccc3b9d", size = 24608567, upload-time = "2026-04-22T16:28:36.145Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/fa/730129a0169d4986c3af351617051a2fbcc73858de21f141ef8978f502a4/ibm_db-3.2.9-cp312-cp312-win_amd64.whl", hash = "sha256:2353c0b968ec337ee4d4111dc4f8fe15a56818b3c399939de952f9a1f2589840", size = 28755039, upload-time = "2026-04-22T16:28:38.868Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/62/2027a98282f2bc02ece82b46ea086b43cbc73fa4aa50e371a8e828a4b3cd/ibm_db-3.2.9-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:09cc163f950d0e8ffb8e390ddd65c3de45c0dc752ce7744e0934e74374134572", size = 24166466, upload-time = "2026-04-22T16:28:41.663Z" },
+ { url = "https://files.pythonhosted.org/packages/98/86/d66b45f1d7e975215abdcb9d33e61ed050467c0661fe6d98c65d2b6476bb/ibm_db-3.2.9-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:b9264183d3353f68a77f06a8cc4ff8ba8fdfc567bcde619c74b7fc685f27152a", size = 20391631, upload-time = "2026-04-22T16:28:44.114Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/8b/984c1584d1ffaa61a9c88d01ebda111bac04ede74ec8fa10528c89f680b5/ibm_db-3.2.9-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:06e578cceff73ec5a04a89b2d1807867b37553bee8dcd32369a9d07d17fe86c2", size = 40606656, upload-time = "2026-04-22T16:28:47.501Z" },
+ { url = "https://files.pythonhosted.org/packages/73/48/b017c182e3e5e902faa25b81a0416afdc7341a6fb03494f78fcfe69224cb/ibm_db-3.2.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bbc992915eb03a70be716844bb05f252dc0413f0d475602445be66df7e188a11", size = 43945653, upload-time = "2026-04-22T16:28:50.4Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/08/fd17875b1ddf66a8252f6cb80d30f7d2d7ffe5fd317a473ce25067ec6305/ibm_db-3.2.9-cp313-cp313-win32.whl", hash = "sha256:03e044a50abb91852b194bf6f6ca35b1c46b8695e0377c663ee3361c118024ce", size = 24608571, upload-time = "2026-04-22T16:28:53.195Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/c7/fcca5a11346d218e6a55328211c575cc29c53e7423e8b3c6c99e93144fbd/ibm_db-3.2.9-cp313-cp313-win_amd64.whl", hash = "sha256:973edafd5622a947d3a205274db5ace68a7d5bf53d92003f0901151b33c89d27", size = 28755050, upload-time = "2026-04-22T16:28:55.681Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/1e/93cb11b58589bab4b58433a54d2eb2716e4a735d9f604f01afe1dc26485c/ibm_db-3.2.9-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5190366f1d4a777797a39624146cfa99d0884f8a3c7ced1c82c8fb9520d65faa", size = 24166743, upload-time = "2026-04-22T16:28:58.396Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/b4/238c00b95b2697c5e3cf1526057e5389c5d41d7803246c21f5057b5e2318/ibm_db-3.2.9-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d204acdaa08436dd84ef999bb048ff352b7a1deae02752d144586bd278d9d31a", size = 20391505, upload-time = "2026-04-22T16:29:01.228Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/a1/e60b39120807bfafacdbc2a85b5d88b36fccfb36ed45338b792c77b63612/ibm_db-3.2.9-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9eb5725526b046b0d0e1021c30fe2e60078f2f1080010dc93f95d057c51cce0a", size = 40606947, upload-time = "2026-04-22T16:29:04.25Z" },
+ { url = "https://files.pythonhosted.org/packages/46/ec/e44e5c11431a16ec933e10df9bfb55e97001b6946c10eba584219dd78e7a/ibm_db-3.2.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ccbce68115de998ba99af314b489f36daab5453dbdb69c9a625b3a9722da0e3", size = 43945000, upload-time = "2026-04-22T16:29:07.36Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/9b/8b544037a245e573b4ba21f4b258143e5e4c147c9a75c25eae263ee6a861/ibm_db-3.2.9-cp314-cp314-win32.whl", hash = "sha256:350d6e40c62340b583b6aa4887730a626191290fa91f63d9f7e58ff60edf17af", size = 25562087, upload-time = "2026-04-22T16:29:10.118Z" },
+ { url = "https://files.pythonhosted.org/packages/07/92/6a3749de901a633c4eff94e58fb2263691981582771f9dc03ba54ba226f2/ibm_db-3.2.9-cp314-cp314-win_amd64.whl", hash = "sha256:62b2fc14da8b49895f6d9670a3bdce65d8ea2a5fdabd00303fbe404b8f84d947", size = 29355366, upload-time = "2026-04-22T16:29:13.318Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/04/0730e66aa3dc9c61bc2b1f59abdb274188bc1ae1cafc01705e3724ccead1/ibm_db-3.2.9-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5fa430ce90eda04f2b1326a84817f09ad6a9f16d475afacb43522debf4283300", size = 24170941, upload-time = "2026-04-22T16:29:16.366Z" },
+]
+
+[[package]]
+name = "ibm-db-sa"
+version = "0.4.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "ibm-db" },
+ { name = "sqlalchemy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/7d/9d/2d6a1ba44af4a6ee411a61e18dbaa735f5d63880e159b877658b17ba4ea3/ibm_db_sa-0.4.4.tar.gz", hash = "sha256:f2567853fd095821964d6a6880e54fddee249d68cc835a3fd0c7d1cdd6a01055", size = 45207, upload-time = "2026-03-18T06:49:20.86Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/83/6a/1fdabb124aa5a045e38ad68fec876b27537b50e85cf7603dc2f4778c6bfb/ibm_db_sa-0.4.4-py3-none-any.whl", hash = "sha256:db0464d87d39a6a3ec8716515ec1dbb7f4620596295e433be53375cdeab9d631", size = 42731, upload-time = "2026-03-18T06:49:19.742Z" },
+]
+
[[package]]
name = "ibmcloudant"
version = "0.11.9"
@@ -14705,17 +14807,17 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "decorator" },
- { name = "exceptiongroup" },
- { name = "jedi" },
- { name = "matplotlib-inline" },
- { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
- { name = "prompt-toolkit" },
- { name = "pygments" },
- { name = "stack-data" },
- { name = "traitlets" },
- { name = "typing-extensions" },
+ { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" },
+ { name = "decorator", marker = "python_full_version < '3.11'" },
+ { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
+ { name = "jedi", marker = "python_full_version < '3.11'" },
+ { name = "matplotlib-inline", marker = "python_full_version < '3.11'" },
+ { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "prompt-toolkit", marker = "python_full_version < '3.11'" },
+ { name = "pygments", marker = "python_full_version < '3.11'" },
+ { name = "stack-data", marker = "python_full_version < '3.11'" },
+ { name = "traitlets", marker = "python_full_version < '3.11'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/40/18/f8598d287006885e7136451fdea0755af4ebcbfe342836f24deefaed1164/ipython-8.39.0.tar.gz", hash = "sha256:4110ae96012c379b8b6db898a07e186c40a2a1ef5d57a7fa83166047d9da7624", size = 5513971, upload-time = "2026-03-27T10:02:13.94Z" }
wheels = [
@@ -14739,18 +14841,18 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "decorator" },
- { name = "ipython-pygments-lexers" },
- { name = "jedi" },
- { name = "matplotlib-inline" },
- { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
- { name = "prompt-toolkit" },
- { name = "psutil", marker = "sys_platform != 'cygwin' and sys_platform != 'emscripten'" },
- { name = "pygments" },
- { name = "stack-data" },
- { name = "traitlets" },
- { name = "typing-extensions", marker = "python_full_version < '3.12'" },
+ { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" },
+ { name = "decorator", marker = "python_full_version >= '3.11'" },
+ { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" },
+ { name = "jedi", marker = "python_full_version >= '3.11'" },
+ { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" },
+ { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
+ { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" },
+ { name = "psutil", marker = "python_full_version >= '3.11' and sys_platform != 'cygwin' and sys_platform != 'emscripten'" },
+ { name = "pygments", marker = "python_full_version >= '3.11'" },
+ { name = "stack-data", marker = "python_full_version >= '3.11'" },
+ { name = "traitlets", marker = "python_full_version >= '3.11'" },
+ { name = "typing-extensions", marker = "python_full_version == '3.11.*'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/53/59/165d3b4d75cc34add3122c4417ecb229085140ac573103c223cd01dde96f/ipython-9.15.0.tar.gz", hash = "sha256:da2819ce2aa83135257df830660b1176d986c3d2876db24df01974fa955b2756", size = 4442580, upload-time = "2026-06-26T11:03:35.913Z" }
wheels = [
@@ -14762,7 +14864,7 @@ name = "ipython-pygments-lexers"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pygments" },
+ { name = "pygments", marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" }
wheels = [
@@ -17714,21 +17816,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/7c/8be563d68e93bbefa5c8affb82ddcff91b3ad858ce49957ba7b16fd3e0ab/opentelemetry_proto-1.44.0-py3-none-any.whl", hash = "sha256:898b155a0e1557afd867478fb6158e8122a46329ca0bb8dc53cc55e98f017f56", size = 72483, upload-time = "2026-07-16T15:25:28.429Z" },
]
-[[package]]
-name = "opentelemetry-resourcedetector-gcp"
-version = "1.12.0a0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "opentelemetry-api" },
- { name = "opentelemetry-sdk" },
- { name = "requests" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/21/ae/b62c5e986c9c7f908a15682ea173bcfcdc00403c0c85243ccbd30eca7fc2/opentelemetry_resourcedetector_gcp-1.12.0a0.tar.gz", hash = "sha256:d5e3f78283a272eb92547e00bbeff45b7332a34ae791a70ab4eba81af9bc3baf", size = 18797, upload-time = "2026-04-28T20:59:43.195Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/df/84/9db2999adbc41505af3e6717e8d958746778cbfc9e07ed9c670bf9d1e6db/opentelemetry_resourcedetector_gcp-1.12.0a0-py3-none-any.whl", hash = "sha256:e803688d14e2969fe816077be81f7b034368314d485863f12ce49daba7c81919", size = 18798, upload-time = "2026-04-28T20:59:39.257Z" },
-]
-
[[package]]
name = "opentelemetry-sdk"
version = "1.44.0"
@@ -18090,9 +18177,9 @@ wheels = [
[package.optional-dependencies]
sql-other = [
- { name = "adbc-driver-postgresql" },
- { name = "adbc-driver-sqlite" },
- { name = "sqlalchemy" },
+ { name = "adbc-driver-postgresql", marker = "python_full_version < '3.13'" },
+ { name = "adbc-driver-sqlite", marker = "python_full_version < '3.13'" },
+ { name = "sqlalchemy", marker = "python_full_version < '3.13'" },
]
[[package]]
@@ -20500,9 +20587,9 @@ name = "python3-saml"
version = "1.16.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "isodate" },
- { name = "lxml" },
- { name = "xmlsec" },
+ { name = "isodate", marker = "python_full_version < '3.13'" },
+ { name = "lxml", marker = "python_full_version < '3.13'" },
+ { name = "xmlsec", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5d/98/6e0268c3a9893af3d4c5cf670183e0314cd6b5cb034a612d6a7cc5060df8/python3-saml-1.16.0.tar.gz", hash = "sha256:97c9669aecabc283c6e5fb4eb264f446b6e006f5267d01c9734f9d8bffdac133", size = 83468, upload-time = "2023-10-09T10:37:43.128Z" }
wheels = [
@@ -20938,123 +21025,123 @@ wheels = [
[[package]]
name = "regex"
-version = "2026.7.10"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/7b/37/451aaddbf50922f34d744ad5ca919ae1fcfac112123885d9728f52a484b3/regex-2026.7.10.tar.gz", hash = "sha256:1050fedf0a8a92e843971120c2f57c3a99bea86c0dfa1d63a9fac053fe54b135", size = 416282, upload-time = "2026-07-10T19:49:46.267Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/b3/69/62bb7d63f26698949c905cb7ebe29c7b0659e2a7f2a50c35cc29640b0852/regex-2026.7.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:799a369bdab91dcf0eb424ebd7aa9650897025ce22f729248d8f2c72002c4daa", size = 494652, upload-time = "2026-07-10T19:46:28.394Z" },
- { url = "https://files.pythonhosted.org/packages/3a/f2/eed2ce38cc38def9c366d060ec739ff5f235a33647ceb73ae6be37306d39/regex-2026.7.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f0192e5f1cfc70e3cb35347135dd02e7497b3e7d83e378aa226d8b3e53a93f19", size = 295920, upload-time = "2026-07-10T19:46:30.342Z" },
- { url = "https://files.pythonhosted.org/packages/36/57/4d724eeb1c440d71ccd6400d33b62b911bb62ca05385fe1961556e628319/regex-2026.7.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:221f2771cb780186b94bbf125a151bbeb242fa1a971da6ad59d7b0370f19de9a", size = 290696, upload-time = "2026-07-10T19:46:31.953Z" },
- { url = "https://files.pythonhosted.org/packages/c7/9d/76c6779e424c64740d2a564b7ecb389a62c77b6294127d34f52008c91ea7/regex-2026.7.10-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab2fb1f7a2deb4ca3ddebbae6b93905d21480a3b4e11de28d79d9fb0d316fcf8", size = 784833, upload-time = "2026-07-10T19:46:33.145Z" },
- { url = "https://files.pythonhosted.org/packages/54/ec/f777841d88f0c9d46699daf16f86a8086e077e506603be212de2c4584f85/regex-2026.7.10-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f98ef73a13791a387d5c841416ad7f52040ae5caf10bcf46fa12bd2b3d63745", size = 852182, upload-time = "2026-07-10T19:46:34.368Z" },
- { url = "https://files.pythonhosted.org/packages/d1/de/5ba208a0826117851f6c12af9ae7fae5838ccfde69b999b26c5fdc1cedc3/regex-2026.7.10-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9a094ed44a22f9da497453137c3118b531fd783866ab524b0b0fc146e7395e1d", size = 899571, upload-time = "2026-07-10T19:46:35.564Z" },
- { url = "https://files.pythonhosted.org/packages/7f/46/602b7b81d26a53113d3cec6dd845fd664d7b854b0ea45245bfdd6b9dc9ef/regex-2026.7.10-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53bbbd6c610489700f7110db1d85f3623924c3f7c760f987eca033867360788a", size = 794164, upload-time = "2026-07-10T19:46:36.972Z" },
- { url = "https://files.pythonhosted.org/packages/53/cc/c21ebc520c3e17d93e495eb2de2b1c5ae5f6780ccdb298b2d8ce1e940820/regex-2026.7.10-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:87b776cf2890e356e4ab104b9df846e169da3eb5b0f110975547091f4e51854e", size = 786304, upload-time = "2026-07-10T19:46:38.238Z" },
- { url = "https://files.pythonhosted.org/packages/65/d8/69ec8c062bbba8d4d153f9eb70ab43564f591035b81fc4ea7eb059fdf71c/regex-2026.7.10-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ab39d2c967aae3b48a412bff9cdbe7cd7559cd1e277599aceaeada7bc82b7200", size = 769958, upload-time = "2026-07-10T19:46:39.541Z" },
- { url = "https://files.pythonhosted.org/packages/af/82/c56db326ac5f852865bd78d49a275757cc367e8114b13bc1015ed2491db1/regex-2026.7.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b56416091bfd7a429f958f69aaf6823c517be9a49cb5bf1daa3767ce8bf8095e", size = 775056, upload-time = "2026-07-10T19:46:40.808Z" },
- { url = "https://files.pythonhosted.org/packages/af/2a/1ba62462f679eb598d7325ff20798a264ddb9aa34a3f5d2ac388d54c6e4b/regex-2026.7.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:617e8f10472e34a8477931f978ff3a88d46ae2ba0e41927e580b933361f60948", size = 848857, upload-time = "2026-07-10T19:46:42.02Z" },
- { url = "https://files.pythonhosted.org/packages/84/5b/37bf2e2fe810540ca90bbfe457a2f61088721c95d442eee8bb1257165ad7/regex-2026.7.10-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:31fa17378b29519bfd0a1b8ba4e9c10cf0baf1cf4099b39b0689429e7dc2c795", size = 757747, upload-time = "2026-07-10T19:46:43.282Z" },
- { url = "https://files.pythonhosted.org/packages/9a/c5/131dd41f73f766af6b08492073b5f28bc4f907b5571230c9f9e895e88302/regex-2026.7.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5c363de7c0339d39341b6181839ed32509820b85ef506deafcf2e7e43baadab4", size = 837183, upload-time = "2026-07-10T19:46:44.91Z" },
- { url = "https://files.pythonhosted.org/packages/a5/ee/00b9332c3c5d7460639f2c10fdc7197a64de6eaafff69478ec3332815335/regex-2026.7.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed7c886a2fcbf14493ceaf9579394b33521730c161ebb8dad7db9c3e9fcab1a8", size = 782151, upload-time = "2026-07-10T19:46:46.385Z" },
- { url = "https://files.pythonhosted.org/packages/e5/a7/31ce26ec6465c12e7136ea9efcc716f5c55cac616f7958c33f0bf171781e/regex-2026.7.10-cp310-cp310-win32.whl", hash = "sha256:b04583e8867136ae66353fa274f45121ab3ec3166dc45aaff3655a5db90d9f0e", size = 266770, upload-time = "2026-07-10T19:46:47.608Z" },
- { url = "https://files.pythonhosted.org/packages/71/00/22a554bb83203eef88a40ec2fe7cf9a6e5df8765d57f7a96ebe1af5d60c3/regex-2026.7.10-cp310-cp310-win_amd64.whl", hash = "sha256:e21e888a6b471b2bb1cdd4247e8d86632672232f29be583e7eafaa5f4634d34c", size = 277941, upload-time = "2026-07-10T19:46:48.915Z" },
- { url = "https://files.pythonhosted.org/packages/76/46/596a7084918ddf18cea6fb0cc047af1f00cec8790962e8f2edee9b6ec749/regex-2026.7.10-cp310-cp310-win_arm64.whl", hash = "sha256:081acf191b4d614d573a56cab69f948b6864daa5e3cc69f209ee92e26e454c2f", size = 276923, upload-time = "2026-07-10T19:46:50.829Z" },
- { url = "https://files.pythonhosted.org/packages/3d/16/bfd13770be1acd1c05506b93fc6be15c759d6417595d1ba334d355efbf26/regex-2026.7.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:66d2c35587cd601c95965d5c0415058ba5cfd6ffbab7624ce198bd967102b341", size = 494639, upload-time = "2026-07-10T19:46:52.207Z" },
- { url = "https://files.pythonhosted.org/packages/e6/b4/0086215709f0f705661f13ba81516287538886ef0d589c545c12b0484669/regex-2026.7.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28a0973eeffff4292f5a7ee498ab65d5e94ee8cc9cea364239251eb4a260a0f1", size = 295920, upload-time = "2026-07-10T19:46:53.63Z" },
- { url = "https://files.pythonhosted.org/packages/8e/9e/8e07d0eea46d2cf36bf4d3794634bb0a820f016d31bc349dfef008d96b02/regex-2026.7.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8331484450b3894298bef8abecce532171ff6ac60b71f999eed10f2c01941a8a", size = 290673, upload-time = "2026-07-10T19:46:54.863Z" },
- { url = "https://files.pythonhosted.org/packages/b7/56/d83c446de21c70ff49d2f1b2ff2196ac79a4ac6373d2cfe496011a250600/regex-2026.7.10-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0639b2488b775a0109f55a5a2172deebdedb4b6c5ab0d48c90b43cbf5de58d17", size = 792378, upload-time = "2026-07-10T19:46:56.116Z" },
- { url = "https://files.pythonhosted.org/packages/dc/0e/d265e0cc6da47aea97e90eb896be2d2e8f92d16add13bac04fa46a0fd972/regex-2026.7.10-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:be4223af640d0aa04c05db81d5d96ada3ead9c09187d892fd37f4f97829480be", size = 861790, upload-time = "2026-07-10T19:46:57.611Z" },
- { url = "https://files.pythonhosted.org/packages/b4/a5/62655f6208d1170a3e9188d6a45d4af0a5ae3b9da8b87d474818ac5ff016/regex-2026.7.10-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d3c75d57a00109255e60bc9c623b6ececaf7905eaab845c79f036670ed4750a2", size = 906530, upload-time = "2026-07-10T19:46:59.142Z" },
- { url = "https://files.pythonhosted.org/packages/86/b7/d65aa2e9ffb18677cd0afbcf5990da8519a4e50778deb1bca49f043c5174/regex-2026.7.10-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:724ee9379568658ec06362cf24325c5315cc5a67f61dfe585bfeff58300a355b", size = 799912, upload-time = "2026-07-10T19:47:00.534Z" },
- { url = "https://files.pythonhosted.org/packages/8f/19/3a5ce23ea2eb1fe36306aef49c79746ce297e4b434aeb981b525c661413a/regex-2026.7.10-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:732c19e5828eb287d01edb83b2eb87f283ba8e5fc3441c732709d3e8cbd14aaa", size = 773675, upload-time = "2026-07-10T19:47:01.999Z" },
- { url = "https://files.pythonhosted.org/packages/fe/76/3c0eaa426700dd2ba14f2335f2b700a4e1484202254192ae440b83b8352a/regex-2026.7.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:982d07727c809b42a3968785354f11c3728414e4e90af0754345b431b2c32561", size = 781711, upload-time = "2026-07-10T19:47:03.425Z" },
- { url = "https://files.pythonhosted.org/packages/a4/a8/a5a3fad84f9a7f897619f0f8e0a2c64946e9709044a186a8f869fb5c332f/regex-2026.7.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4574feca202f8c470bf678aed8b5d89df04aaf8dc677f3b83d92825051301c0f", size = 854539, upload-time = "2026-07-10T19:47:04.999Z" },
- { url = "https://files.pythonhosted.org/packages/f8/c7/47e9b8c8ee77723b9eda74f517b6b25d2f555cf276c063a9eeea35bd86d5/regex-2026.7.10-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:80151ca5bfc6c4524186b3e08b499e97319b2001fc265ed2d4fc12c0d5692cdf", size = 763378, upload-time = "2026-07-10T19:47:06.845Z" },
- { url = "https://files.pythonhosted.org/packages/36/09/e27e42d9d42edf71205c7e6f5b2902bc874ea03c557c80da03b8ed16c9bf/regex-2026.7.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bb52e10e453b5493afe1f7702a2973bc10f4dd8901c0f2ed869ffaa3f8319296", size = 844663, upload-time = "2026-07-10T19:47:08.923Z" },
- { url = "https://files.pythonhosted.org/packages/a1/b5/2423acb98362184ad9c8eebabafa15188d6a177daab919add8f2120fc6cd/regex-2026.7.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e37aba1994d73b4944053ab65a15f313bd5c28c885dd7f0d494a11749d89db6e", size = 789236, upload-time = "2026-07-10T19:47:10.303Z" },
- { url = "https://files.pythonhosted.org/packages/60/ed/b387e84c8a3d6aa115dfb56865437a3fbaf28f4a6fb3b76cc6cce38ced70/regex-2026.7.10-cp311-cp311-win32.whl", hash = "sha256:6cbedeb5112f59dbd169385459b9943310bdd241c6966c19c5f6e2295055c93a", size = 266774, upload-time = "2026-07-10T19:47:11.904Z" },
- { url = "https://files.pythonhosted.org/packages/c4/64/f30a163a65ed1f07ad12c53af00a6bd2a7251a5329fba5a08adc6f9e81a3/regex-2026.7.10-cp311-cp311-win_amd64.whl", hash = "sha256:b1963ec5ba4d52788fb0eac6aca6eb8040e8e318c7e47ebbdfc09440c802919c", size = 277959, upload-time = "2026-07-10T19:47:13.231Z" },
- { url = "https://files.pythonhosted.org/packages/2b/de/61c8174171134cebb834ca9f8fe2ff8f49d8a3dd43453b48b537d0fbb49b/regex-2026.7.10-cp311-cp311-win_arm64.whl", hash = "sha256:3750c42d47712e362158a04d0fd80131f73a55e8c715b2885442a0ff6f9fc3fc", size = 276918, upload-time = "2026-07-10T19:47:14.693Z" },
- { url = "https://files.pythonhosted.org/packages/b3/9c/2503d4ccf3452dc323f8baa3cf3ee10406037d52735c76cfced81423f183/regex-2026.7.10-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7252b48b0c60100095088fbeb281fca9a4fcf678a4e04b1c520c3f8613c952c4", size = 497114, upload-time = "2026-07-10T19:47:16.22Z" },
- { url = "https://files.pythonhosted.org/packages/91/eb/04534f4263a4f658cd20a511e9d6124350044f2214eb24fee2db96acf318/regex-2026.7.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:da6ef4cb8d457aab0482b50120136ae94238aaa421863eaa7d599759742c72d6", size = 297422, upload-time = "2026-07-10T19:47:17.794Z" },
- { url = "https://files.pythonhosted.org/packages/ca/2d/35809de392ab66ba439b58c3187ae3b8b53c883233f284b59961e5725c99/regex-2026.7.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fe7ff456c22725c9d9017f7a2a7df2b51af6df77314176760b22e2d05278e181", size = 292110, upload-time = "2026-07-10T19:47:19.188Z" },
- { url = "https://files.pythonhosted.org/packages/ad/1e/5ce0fbe9aab071893ce2b7df020d0f561f7b411ec334124302468d587884/regex-2026.7.10-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3463a5f26be513a49e4d497debcf1b252a2db7b92c77d89621aa90b83d2dd38", size = 796800, upload-time = "2026-07-10T19:47:20.639Z" },
- { url = "https://files.pythonhosted.org/packages/d4/67/c1ccbada395c10e334763b583e1039b1660b142303ebb941d4269130b22f/regex-2026.7.10-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:948dfc62683a6947b9b486c4598d8f6e3ecc542478b6767b87d52be68aeb55c6", size = 865509, upload-time = "2026-07-10T19:47:22.135Z" },
- { url = "https://files.pythonhosted.org/packages/0e/06/f0b31afc16c1208f945b66290eb2a9936ab8becdfb23bbcedb91cc5f9d9b/regex-2026.7.10-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c2cbd385d82f63bb35edb60b09b08abad3619bd0a4a492ae59e55afaf98e1b9d", size = 912395, upload-time = "2026-07-10T19:47:24.128Z" },
- { url = "https://files.pythonhosted.org/packages/0b/1c/8687de3a6c3220f4f872a9bf4bcd8dc249f2a96e7dddfa93de8bd4d16399/regex-2026.7.10-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6222cafe00e072bb2b8f14142cd969637411fbc4dd3b1d73a90a3b817fa046f", size = 801308, upload-time = "2026-07-10T19:47:25.696Z" },
- { url = "https://files.pythonhosted.org/packages/5f/e3/60a40ec02a2315d826414a125640aceb6f30450574c530c8f352110ece0e/regex-2026.7.10-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:65ee5d1ac3cd541325f5ac92625b1c1505f4d171520dd931bda7952895c5321a", size = 777120, upload-time = "2026-07-10T19:47:27.158Z" },
- { url = "https://files.pythonhosted.org/packages/6a/9a/ec579b4f840ac59bc7c192b56e66abd4cbf385615300d59f7c94bf6863ae/regex-2026.7.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa34473fbcc108fea403074f3f45091461b18b2047d136f16ffaa4c65ad46a68", size = 785164, upload-time = "2026-07-10T19:47:28.732Z" },
- { url = "https://files.pythonhosted.org/packages/ad/1c/60d88afd5f98d4b0fb1f8b8969270628140dc01c7ff93a939f2aa83f31a6/regex-2026.7.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:9d028d189d8f38d7ff292f22187c0df37f2317f554d2ed9a2908ada330af57c0", size = 860161, upload-time = "2026-07-10T19:47:30.605Z" },
- { url = "https://files.pythonhosted.org/packages/2a/40/08ae3ba45fe79e48c9a888a3389a7ee7e2d8c580d2d996da5ece02dfdcb9/regex-2026.7.10-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:396ea70e4ea1f19571940add3bad9fd3eb6a19dc610d0d01f692bc1ba0c10cb4", size = 765829, upload-time = "2026-07-10T19:47:32.06Z" },
- { url = "https://files.pythonhosted.org/packages/12/e6/e613c6755d19aca9d977cdc3418a1991ffc8f386779752dd8fdfa888ea89/regex-2026.7.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ebbf0d83ed5271991d666e54bb6c90ac2c55fb2ef3a88740c6af85dc85de2402", size = 852170, upload-time = "2026-07-10T19:47:33.567Z" },
- { url = "https://files.pythonhosted.org/packages/03/33/89072f2060e6b844b4916d5bc40ef01e973640c703025707869264ec75ab/regex-2026.7.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:58a4571b2a093f6f6ee4fd281faa8ebf645abcf575f758173ea2605c7a1e1ecb", size = 789550, upload-time = "2026-07-10T19:47:35.395Z" },
- { url = "https://files.pythonhosted.org/packages/e3/3c/4bc8be9a155035e63780ccac1da101f36194946fdc3f6fce90c7179fc6df/regex-2026.7.10-cp312-cp312-win32.whl", hash = "sha256:eac1207936555aa691ce32df1432b478f2729d54e6d93a1f4db9215bcd8eb47d", size = 267151, upload-time = "2026-07-10T19:47:37.047Z" },
- { url = "https://files.pythonhosted.org/packages/35/73/9f5aade65bb98cc6e99c336e45a49a658300720c16721f3e687f8d754fec/regex-2026.7.10-cp312-cp312-win_amd64.whl", hash = "sha256:ecae626449d00db8c08f8f1fc00047a32d6d7eb5402b3976f5c3fda2b80a7a4f", size = 277751, upload-time = "2026-07-10T19:47:38.488Z" },
- { url = "https://files.pythonhosted.org/packages/36/6f/d069dd12872ea1d50e17319d342f89e2072cae4b62f4245009a1108c74d8/regex-2026.7.10-cp312-cp312-win_arm64.whl", hash = "sha256:87794549a3f5c1c2bdfba2380c1bf87b931e375f4133d929da44f95e396bf5fe", size = 277063, upload-time = "2026-07-10T19:47:40.023Z" },
- { url = "https://files.pythonhosted.org/packages/e0/88/0c977b9f3ba9b08645516eca236388c340f56f7a87054d41a187a04e134c/regex-2026.7.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:4db009b4fc533d79af3e841d6c8538730423f82ea8508e353a3713725de7901c", size = 496868, upload-time = "2026-07-10T19:47:41.675Z" },
- { url = "https://files.pythonhosted.org/packages/f6/51/600882cd5d9a3cf083fd66a4064f5b7f243ba2a7de2437d42823e286edaf/regex-2026.7.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b96341cb29a3faa5db05aff29c77d141d827414f145330e5d8846892119351c1", size = 297306, upload-time = "2026-07-10T19:47:43.521Z" },
- { url = "https://files.pythonhosted.org/packages/52/6f/48a912054ffcb756e374207bb8f4430c5c3e0ffa9627b3c7b6661844b30a/regex-2026.7.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14d27f6bd04beb01f6a25a1153d73e58c290fd45d92ba56af1bb44199fd1010d", size = 291950, upload-time = "2026-07-10T19:47:45.267Z" },
- { url = "https://files.pythonhosted.org/packages/1a/c8/8e1c3c86ebcee7effccbd1f7fc54fe3af22aa0e9204503e2baea4a6ff001/regex-2026.7.10-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6b6a11bf898cca3ce7bfaa17b646901107f3975677fbd5097f36e5eb5641983", size = 796817, upload-time = "2026-07-10T19:47:48.054Z" },
- { url = "https://files.pythonhosted.org/packages/65/39/3e49d9ff0e0737eb8180a00569b47aabb59b84611f48392eba4d998d91a0/regex-2026.7.10-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:234f8e0d65cf1df9becadae98648f74030ee85a8f12edcb5eb0f60a22a602197", size = 865513, upload-time = "2026-07-10T19:47:49.855Z" },
- { url = "https://files.pythonhosted.org/packages/70/57/6511ad809bb3122c65bbeeffa5b750652bb03d273d29f3acb0754109b183/regex-2026.7.10-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:91b916d495db3e1b473c7c8e68733beec4dce8e487442db61764fff94f59740e", size = 912391, upload-time = "2026-07-10T19:47:51.776Z" },
- { url = "https://files.pythonhosted.org/packages/cc/29/a1b0c109c9e878cb04b931bfe4c54332d692b93c322e127b5ae9f25b0d9e/regex-2026.7.10-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f0d4ccf70b1d13711242de0ba78967db5c35d12ac408378c70e06295c3f6644", size = 801338, upload-time = "2026-07-10T19:47:53.38Z" },
- { url = "https://files.pythonhosted.org/packages/33/be/171c3dad4d77000e1befeff2883ca88734696dfd97b2951e5e074f32e4dd/regex-2026.7.10-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c622f4c638a725c39abcb2e680b1bd592663c83b672a4ed350a17f806d75618e", size = 777149, upload-time = "2026-07-10T19:47:54.944Z" },
- { url = "https://files.pythonhosted.org/packages/33/61/41ab0de0e4574da1071c151f67d1eb9db3d92c43e31d64d2e6863c3d89bf/regex-2026.7.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41a47c2b28d9421e2509a4583a22510dc31d83212fcf38e1508a7013140f71a8", size = 785216, upload-time = "2026-07-10T19:47:56.56Z" },
- { url = "https://files.pythonhosted.org/packages/66/28/372859ea693736f07cf7023247c7eca8f221d9c6df8697ff9f93371cca08/regex-2026.7.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:13fba679fe035037e9d5286620f88bbfd105df4d5fcd975942edd282ab986775", size = 860229, upload-time = "2026-07-10T19:47:58.278Z" },
- { url = "https://files.pythonhosted.org/packages/50/b1/e1d32cd944b599534ae655d35e8640d0ec790c0fa12e1fb29bf434d50f55/regex-2026.7.10-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8e26a075fa9945b9e44a3d02cc83d776c3b76bb1ff4b133bbfa620d5650131da", size = 765797, upload-time = "2026-07-10T19:48:00.291Z" },
- { url = "https://files.pythonhosted.org/packages/0c/62/79a2cd9556a3329351e370929743ef4f0ccc0aaff6b3dc414ae5fa4a1302/regex-2026.7.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d0834c84ae8750ae1c4cede59b0afd4d2f775be958e11b18a3eea24ed9d0d9f1", size = 852130, upload-time = "2026-07-10T19:48:01.972Z" },
- { url = "https://files.pythonhosted.org/packages/66/58/76fec29898cf5d359ab63face50f9d4f7135cc2eca3477139227b1d09952/regex-2026.7.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64722a5031aeace7f6c8d5ea9a9b22d9368af0d6e8fa532585da8158549ea963", size = 789644, upload-time = "2026-07-10T19:48:03.748Z" },
- { url = "https://files.pythonhosted.org/packages/f6/06/3c7cec7817bda293e13c8f88aed227bbcf8b37e5990936ff6442a8fdf11a/regex-2026.7.10-cp313-cp313-win32.whl", hash = "sha256:74ae61d8573ecd51b5eeee7be2218e4c56e99c14fa8fcf97cf7519611d4be92e", size = 267130, upload-time = "2026-07-10T19:48:05.677Z" },
- { url = "https://files.pythonhosted.org/packages/88/6c/e2a6f9a6a905f923cfc912298a5949737e9504b1ca24f29eda8d04d05ece/regex-2026.7.10-cp313-cp313-win_amd64.whl", hash = "sha256:5e792367e5f9b4ffb8cad93f1beaa91837056b94da98aa5c65a0db0c1b474927", size = 277722, upload-time = "2026-07-10T19:48:07.318Z" },
- { url = "https://files.pythonhosted.org/packages/00/a6/9d8935aaa940c388496aa1a0c82669cc4b5d06291c2712d595e3f0cf16d3/regex-2026.7.10-cp313-cp313-win_arm64.whl", hash = "sha256:82ab8330e7e2e416c2d42fcec67f02c242393b8681014750d4b70b3f158e1f08", size = 277059, upload-time = "2026-07-10T19:48:08.977Z" },
- { url = "https://files.pythonhosted.org/packages/7d/e9/26decfd3e85c09e42ff7b0d23a6f51085ca4c268db15f084928ca33459c6/regex-2026.7.10-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:2b93eafd92c4128bab2f93500e8912cc9ecb3d3765f6685b902c6820d0909b6b", size = 501508, upload-time = "2026-07-10T19:48:10.668Z" },
- { url = "https://files.pythonhosted.org/packages/38/a5/5b167cebde101945690219bf34361481c9f07e858a4f46d9996b80ec1490/regex-2026.7.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3f03b92fb6ec739df042e45b06423fc717ecf0063e07ffe2897f7b2d5735e1e8", size = 299705, upload-time = "2026-07-10T19:48:12.544Z" },
- { url = "https://files.pythonhosted.org/packages/f6/20/7909be4b9f449f8c282c14b6762d59aa722aeaeebe7ee4f9bb623eeaa5e0/regex-2026.7.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:bb5aab464a0c5e03a97abad5bdf54517061ebbf72340d576e99ff661a42575cc", size = 294605, upload-time = "2026-07-10T19:48:14.495Z" },
- { url = "https://files.pythonhosted.org/packages/82/88/e52550185d6fda68f549b01239698697de47320fd599f5e880b1986b7673/regex-2026.7.10-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fadb07dbe36a541283ff454b1a268afd54b077d917043f2e1e5615372cb5f200", size = 811747, upload-time = "2026-07-10T19:48:16.197Z" },
- { url = "https://files.pythonhosted.org/packages/06/98/16c255c909714de1ee04da6ae30f3ee04170f300cdc0dcf57a314ee4816a/regex-2026.7.10-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:21150500b970b12202879dfd82e7fd809d8e853140fff84d08e57a90cf1e154e", size = 871203, upload-time = "2026-07-10T19:48:18.12Z" },
- { url = "https://files.pythonhosted.org/packages/3b/32/423ed27c9bae2092a453e853da2b6628a658d08bb5a6117db8d591183d85/regex-2026.7.10-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a68b637451d64ba30ed8ae125c973fa834cc2d37dfa7f154c2b479015d477ba8", size = 917334, upload-time = "2026-07-10T19:48:19.952Z" },
- { url = "https://files.pythonhosted.org/packages/73/87/74dac8efb500db31cb000fda6bae2be45fc2fbf1fa9412f445fbb8acbe37/regex-2026.7.10-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e23458d8903e33e7d27196d7a311523dc4e2f4137a5f34e4dbd30c8d37ff33e", size = 816379, upload-time = "2026-07-10T19:48:21.616Z" },
- { url = "https://files.pythonhosted.org/packages/a8/9f/1859403654e3e030b288f06d49233c6a4f889d62b84c4ef3f3a28653173d/regex-2026.7.10-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae27622c094558e519abf3242cf4272db961d12c5c9a9ffb7a1b44b2627d5c6", size = 785563, upload-time = "2026-07-10T19:48:23.643Z" },
- { url = "https://files.pythonhosted.org/packages/6d/d8/35d30d6bdf1ef6a5430e8982607b3a6db4df1ddedbe001e43435585d88ba/regex-2026.7.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ee877b6d78f9dff1da94fef51ae8cf9cce0967e043fdcc864c40b85cf293c192", size = 801415, upload-time = "2026-07-10T19:48:25.499Z" },
- { url = "https://files.pythonhosted.org/packages/f7/22/630f31f5ea4826167b2b064d9cac2093a5b3222af380aa432cfe1a5dabcd/regex-2026.7.10-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:2c66a8a1969cfd506d1e203c0005fd0fc3fe6efc83c945606566b6f9611d4851", size = 866560, upload-time = "2026-07-10T19:48:27.789Z" },
- { url = "https://files.pythonhosted.org/packages/8d/14/f5914a6d9c5bc63b9bed8c9a1169fb0be35dbe05cdc460e17d953031a366/regex-2026.7.10-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:2bc350e1c5fa250f30ab0c3e38e5cfdffcd82cb8af224df69955cab4e3003812", size = 772877, upload-time = "2026-07-10T19:48:29.563Z" },
- { url = "https://files.pythonhosted.org/packages/c1/0f/7c13999eef3e4186f7c79d4950fa56f041bf4de107682fb82c80db605ff9/regex-2026.7.10-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:53f54993b462f3f91fea0f2076b46deb6619a5f45d70dbd1f543f789d8b900ef", size = 856648, upload-time = "2026-07-10T19:48:31.282Z" },
- { url = "https://files.pythonhosted.org/packages/a4/71/a48e43909b6450fb48fa94e783bef2d9a37179258bc32ef2283955df7be7/regex-2026.7.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cfcec18f7da682c4e2d82112829ce906569cb8d69fa6c26f3a50dfbed5ceb682", size = 803520, upload-time = "2026-07-10T19:48:33.275Z" },
- { url = "https://files.pythonhosted.org/packages/e0/b8/f037d1bf2c133cb24ceb6e7d81d08417080390eddab6ddfd701aa7091874/regex-2026.7.10-cp313-cp313t-win32.whl", hash = "sha256:a2d6d30be35ddd70ce0f8ee259a4c25f24d6d689a45a5ac440f03e6bcc5a21d1", size = 269168, upload-time = "2026-07-10T19:48:35.353Z" },
- { url = "https://files.pythonhosted.org/packages/b6/9c/eaac34f8452a838956e7e89852ad049678cdc1af5d14f72d3b3b658b1ea5/regex-2026.7.10-cp313-cp313t-win_amd64.whl", hash = "sha256:c57b6ad3f7a1bdd101b2966f29dc161adf49727b1e8d3e1e89db2eda8a75c344", size = 280004, upload-time = "2026-07-10T19:48:37.106Z" },
- { url = "https://files.pythonhosted.org/packages/cd/a9/e22e997587bc1d588b0b2cd0572027d39dd3a006216e40bbf0361688c51c/regex-2026.7.10-cp313-cp313t-win_arm64.whl", hash = "sha256:3d8ef9df02c8083c7b4b855e3cb87c8e0ebbcfea088d98c7a886aaefdf88d837", size = 279308, upload-time = "2026-07-10T19:48:38.907Z" },
- { url = "https://files.pythonhosted.org/packages/6a/4a/a7fa3ada9bd2d2ce20d56dfceec6b2a51afeed9bf3d8286355ceec5f0628/regex-2026.7.10-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:39f81d1fdf594446495f2f4edd8e62d8eda0f7a802c77ac596dc8448ad4cc5ca", size = 497087, upload-time = "2026-07-10T19:48:40.543Z" },
- { url = "https://files.pythonhosted.org/packages/0f/7e/ca0b1a87192e5828dbc16f16ae6caca9b67f25bf729a3348468a5ff52755/regex-2026.7.10-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:441edc66a54063f8269d1494fc8474d06605e71e8a918f4bcfd079ebda4ce042", size = 297307, upload-time = "2026-07-10T19:48:42.213Z" },
- { url = "https://files.pythonhosted.org/packages/b2/6c/fb40bb34275d3cd4d7a376d5fb2ea1f0f4a96fd884fa83c0c4ae869001bf/regex-2026.7.10-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cfeb11990f59e59a0df26c648f0adfcbf27be77241250636f5769eb08db662be", size = 292163, upload-time = "2026-07-10T19:48:43.929Z" },
- { url = "https://files.pythonhosted.org/packages/18/0b/34cbea16c8fea9a18475a7e8f5837c70af451e738bfeb4eb5b029b7dc07a/regex-2026.7.10-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:460176b2db044a292baaee6891106566739657877af89a251cded228689015a6", size = 797064, upload-time = "2026-07-10T19:48:45.623Z" },
- { url = "https://files.pythonhosted.org/packages/87/77/f6805d97f15f5a710bdfd56a768f3468c978239daf9e1b15efd8935e1967/regex-2026.7.10-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9dc55698737aca028848bde418d6c51d74f2a5fd44872d3c8b56b626729adb89", size = 866155, upload-time = "2026-07-10T19:48:47.589Z" },
- { url = "https://files.pythonhosted.org/packages/a2/e3/a2a905807bba3bcd90d6ebbb67d27af2adf7d41708175cbc6b956a0c75f1/regex-2026.7.10-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d3e10779f60c000213a5b53f518824bd07b3dc119333b26d70c6be1c27b5c794", size = 911596, upload-time = "2026-07-10T19:48:49.473Z" },
- { url = "https://files.pythonhosted.org/packages/a2/ca/a3126888b2c6f33c7e29144fedf85f6d5a52a400024fa045ad8fc0550ef1/regex-2026.7.10-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:38a5926601aaccf379512746b86eb0ac1d29121f6c776dac6ac5b31077432f2c", size = 800713, upload-time = "2026-07-10T19:48:51.452Z" },
- { url = "https://files.pythonhosted.org/packages/66/19/9d252fd969f726c8b56b4bacf910811cc70495a110907b3a7ccb96cd9cad/regex-2026.7.10-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a72ecf5bfd3fc8d57927f7e3ded2487e144472f39010c3acaec3f6f3ff53f361", size = 777286, upload-time = "2026-07-10T19:48:53.443Z" },
- { url = "https://files.pythonhosted.org/packages/40/7a/5f1bf433fa446ecb3aab87bb402603dc9e171ef8052c1bb8690bb4e255a3/regex-2026.7.10-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d50714405845c1010c871098558cfe5718fe39d2a2fab5f95c8863caeb7a82b3", size = 785826, upload-time = "2026-07-10T19:48:55.381Z" },
- { url = "https://files.pythonhosted.org/packages/99/ca/69f3a7281d86f1b592338007f3e535cc219d771448e2b61c0b56e4f9d05b/regex-2026.7.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ec1c44cf9bd22079aac37a07cb49a29ced9050ab5bddf24e50aba298f1e34d90", size = 860957, upload-time = "2026-07-10T19:48:57.962Z" },
- { url = "https://files.pythonhosted.org/packages/bc/11/487ff55c8d515ec9dd60d7ba3c129eeaa9e527358ed9e8a054a9e9430f81/regex-2026.7.10-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:9e9aaef25a40d1f1e1bbb1d0eb0190c4a64a7a1750f7eb67b8399bed6f4fd2a6", size = 765959, upload-time = "2026-07-10T19:49:00.27Z" },
- { url = "https://files.pythonhosted.org/packages/73/e1/fa034e6fa8896a09bd0d5e19c81fdc024411ab37980950a0401dccee8f6d/regex-2026.7.10-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:e54e088dc64dd2766014e7cfe5f8bc45399400fd486816e494f93e3f0f55da06", size = 851447, upload-time = "2026-07-10T19:49:02.128Z" },
- { url = "https://files.pythonhosted.org/packages/ee/a5/b9427ed53b0e14c540dc436d56aaf57a19fb9183c6e7abd66f4b4368fbad/regex-2026.7.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:834271b1ff2cfa1f67fcd65a48bf11d11e9ab837e21bf79ce554efb648599ae8", size = 789418, upload-time = "2026-07-10T19:49:03.949Z" },
- { url = "https://files.pythonhosted.org/packages/ba/52/aab92420c8aa845c7bcbe68dc65023d4a9e9ea785abf0beb2198f0de5ba1/regex-2026.7.10-cp314-cp314-win32.whl", hash = "sha256:f988a1cec68058f71a38471813fba9e87dffe855582682e8a10e40ece12567a2", size = 272538, upload-time = "2026-07-10T19:49:05.833Z" },
- { url = "https://files.pythonhosted.org/packages/99/16/5c7050e0ef7dd8889441924ff0a2c33b7f0587c0ccb0953fe7ca997d673b/regex-2026.7.10-cp314-cp314-win_amd64.whl", hash = "sha256:2129e4a5e86f26926982d883dff815056f2e98220fdf630e59f961b578a26c43", size = 280796, upload-time = "2026-07-10T19:49:07.593Z" },
- { url = "https://files.pythonhosted.org/packages/e8/1a/4f6099d2ba271502fdb97e697bae2ed0213c0d87f2273fe7d21e2e401d12/regex-2026.7.10-cp314-cp314-win_arm64.whl", hash = "sha256:9cd5b6805396157b4cf993a6940cbb8663161f29b4df2458c1c9991f099299c5", size = 281017, upload-time = "2026-07-10T19:49:09.767Z" },
- { url = "https://files.pythonhosted.org/packages/19/02/4061fc71f64703e0df61e782c2894c3fbc089d277767eff6e16099581c73/regex-2026.7.10-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:103e8f3acc3dcede88c0331c8612766bdcfc47c9250c5477f0e10e0550b9da49", size = 501467, upload-time = "2026-07-10T19:49:11.952Z" },
- { url = "https://files.pythonhosted.org/packages/73/a5/8d42b2f3fd672908a05582effd0f88438bf9bb4e8e02d69a62c723e23601/regex-2026.7.10-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:538ddb143f5ca085e372def17ef3ed9d74b50ad7fc431bd85dc50a9af1a7076f", size = 299700, upload-time = "2026-07-10T19:49:14.067Z" },
- { url = "https://files.pythonhosted.org/packages/65/70/36fa4b46f73d268c0dbe77c40e62da2cd4833ee206d3b2e438c2034e1f36/regex-2026.7.10-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6e3448e86b05ce87d4eb50f9c680860830f3b32493660b39f43957d6263e2eba", size = 294590, upload-time = "2026-07-10T19:49:15.883Z" },
- { url = "https://files.pythonhosted.org/packages/e0/a7/b6db1823f3a233c2a46f854fdc986f4fd424a84ed557b7751f2998efb266/regex-2026.7.10-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5eab9d3f981c423afd1a61db055cfe83553c3f6455949e334db04722469dd0a2", size = 811925, upload-time = "2026-07-10T19:49:17.97Z" },
- { url = "https://files.pythonhosted.org/packages/b6/7d/f8bee4c210c42c7e8b952bb9fb7099dd7fb2f4bd0f33d0d65a8ab08aafc0/regex-2026.7.10-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:177f930af3ad72e1045f8877540e0c43a38f7d328cf05f31963d0bd5f7ecf067", size = 871257, upload-time = "2026-07-10T19:49:19.943Z" },
- { url = "https://files.pythonhosted.org/packages/5d/78/22adf72e614ba0216b996e9aaef5712c23699e360ea127bb3d5ee1a7666f/regex-2026.7.10-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dd3b6d97beb39afb412f2c79522b9e099463c31f4c49ab8347c5a2ca3531c478", size = 917551, upload-time = "2026-07-10T19:49:22.069Z" },
- { url = "https://files.pythonhosted.org/packages/03/f7/ebc15a39e81e6b58da5f913b91fc293a25c6700d353c14d5cd25fc85712a/regex-2026.7.10-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8679f0652a183d93da646fcec8da8228db0be40d1595da37e6d74c2dc8c4713c", size = 816436, upload-time = "2026-07-10T19:49:24.131Z" },
- { url = "https://files.pythonhosted.org/packages/5c/33/20bc2bdd57f7e0fcc51be37e4c4d1bca7f0b4af8dc0a148c23220e689da8/regex-2026.7.10-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:494b19a5805438aeb582de99f9d97603d8fd48e6f4cc74d0088bb292b4da3b70", size = 785935, upload-time = "2026-07-10T19:49:26.265Z" },
- { url = "https://files.pythonhosted.org/packages/b4/51/87ff99c849b56309c40214a72b54b0eef320d0516a8a516970cc8be1b725/regex-2026.7.10-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0911e34151a5429d0325dae538ba9851ec0b62426bdfd613060cda8f1c36ec7f", size = 801494, upload-time = "2026-07-10T19:49:28.493Z" },
- { url = "https://files.pythonhosted.org/packages/16/11/fde67d49083fef489b7e0f841e2e5736516795b166c9867f05956c1e494b/regex-2026.7.10-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b862572b7a5f5ed47d2ba5921e63bf8d9e3b682f859d8f11e0e5ca46f7e82173", size = 866549, upload-time = "2026-07-10T19:49:30.592Z" },
- { url = "https://files.pythonhosted.org/packages/e6/b5/31a156c36acf10181d88f55a66c688d5454a344e53ccc03d49f4a48a2297/regex-2026.7.10-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:3f361215e000d68a4aff375106637b83c80be36091d83ee5107ad3b32bd73f48", size = 773089, upload-time = "2026-07-10T19:49:32.661Z" },
- { url = "https://files.pythonhosted.org/packages/27/bb/734e978c904726664df47ae36ce5eca5065de5141185ae46efec063476a2/regex-2026.7.10-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:4533af6099543db32ef26abc2b2f824781d4eebb309ab9296150fd1a0c7eb07d", size = 856710, upload-time = "2026-07-10T19:49:35.289Z" },
- { url = "https://files.pythonhosted.org/packages/6d/e5/dc35cea074dbdcb9776c4b0542a3bc326ff08454af0768ef35f3fc66e7fa/regex-2026.7.10-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:668ab85105361d0200e3545bec198a1acfc6b0aeb5fff8897647a826e5a171be", size = 803621, upload-time = "2026-07-10T19:49:37.704Z" },
- { url = "https://files.pythonhosted.org/packages/a6/b2/124564af46bc0b592785610b3985315610af0a07f4cf21fa36e06c2398dd/regex-2026.7.10-cp314-cp314t-win32.whl", hash = "sha256:dd7715817a187edd7e2a2390908757f7ba42148e59cad755fb8ee1160c628eca", size = 274558, upload-time = "2026-07-10T19:49:39.926Z" },
- { url = "https://files.pythonhosted.org/packages/4e/9c/cd813ce9f3404c0443915175c1e339c5afd8fcda04310102eaf233015eef/regex-2026.7.10-cp314-cp314t-win_amd64.whl", hash = "sha256:78712d4954234df5ca24fdadb65a2ab034213f0cdfde376c272f9fc5e09866bb", size = 283687, upload-time = "2026-07-10T19:49:41.872Z" },
- { url = "https://files.pythonhosted.org/packages/1b/d3/3dae6a6ce46144940e64425e32b8573a393a009aeaf75fa6752a35399056/regex-2026.7.10-cp314-cp314t-win_arm64.whl", hash = "sha256:749b92640e1970e881fdf22a411d74bf9d049b154f4ef7232eeb9a90dd8be7f3", size = 283377, upload-time = "2026-07-10T19:49:43.985Z" },
+version = "2026.7.19"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/20/98/04b13f1ddfb63158025291c02e03eb42fbb7acb51d091d541050eb4e35e8/regex-2026.7.19.tar.gz", hash = "sha256:7e77b324909c1617cbb4c668677e2c6ae13f44d7c1de0d4f15f2e3c10f3315b5", size = 416440, upload-time = "2026-07-19T00:19:48.923Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/24/13/bbf7d9d1887fe4a3693527c6caa232c197ea9da91f1212e9672eff60329d/regex-2026.7.19-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:555497390743af1a65045fa4527782d10ff5b88970359412baa4a1e628fe393b", size = 494009, upload-time = "2026-07-19T00:16:13.602Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/19/783688e75a2bec15d50aec0d5e7e317d363808bc82a6eb6750b897bfcd7b/regex-2026.7.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:343a4504e3fb688c47cad451221ca5d4814f42b1e16c0065bde9cbf7f473bd52", size = 295287, upload-time = "2026-07-19T00:16:15.702Z" },
+ { url = "https://files.pythonhosted.org/packages/16/01/cefe4f051302ca298d3f3e79ed6dbd933ac84485b9515acdd6a52d70cef7/regex-2026.7.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ebee1ee89c39c953baac6924fcde08c5bb427c4057510862f9d7c7bdb3d8665", size = 290633, upload-time = "2026-07-19T00:16:17.182Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/1e/1045ca2cabb12e8ec41ad0d138e9f3ff1eb079d30a6f51ccf7d709b44aad/regex-2026.7.19-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:062f8cb7a9739c4835d22bd96f370c59aba89f257adcfa53be3cc209e08d3ae0", size = 785300, upload-time = "2026-07-19T00:16:18.505Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/4a/20e5bca184e90bf1bd187efdb53363f4a7b7b34f01d54ced5740caf104bd/regex-2026.7.19-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1123ef4211d763ee771d47916a1596e2f4915794f7aabdc1adcb20e4249a6951", size = 854079, upload-time = "2026-07-19T00:16:19.909Z" },
+ { url = "https://files.pythonhosted.org/packages/09/9b/5a2e59678be3b24aa6a42b2c6d66a48daa212593e9f4096fe7ba577fa9b1/regex-2026.7.19-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6e44c0e7c5664be20aee92085153150c0a7967310a73a43c0f832b7cd35d0dd3", size = 899496, upload-time = "2026-07-19T00:16:21.453Z" },
+ { url = "https://files.pythonhosted.org/packages/48/9a/7317f14ed8ed9fd998d1978b4802b07bc4d79216353c435dbcc1ddd1301f/regex-2026.7.19-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98c6ac18480fcdb33f35439183f1d2e79760ab41930309c6d951cb1f8e46694c", size = 793541, upload-time = "2026-07-19T00:16:22.991Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/53/833c2db3e274d3c191f4c42fe5bfa358e4c8b617d5d7312d31334965fc46/regex-2026.7.19-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4458124d71339f505bf1fb94f69fd1bb8fa9d2481eebfef27c10ef4f2b9e12f6", size = 785515, upload-time = "2026-07-19T00:16:24.654Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/b9/efb2f9fa151d71db09d4015e1fb92fee47416f01c12164836bbd23e2f3c2/regex-2026.7.19-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fbf300e2070bb35038660b3be1be4b91b0024edb41517e6996320b49b92b4175", size = 769556, upload-time = "2026-07-19T00:16:26.207Z" },
+ { url = "https://files.pythonhosted.org/packages/81/4d/45610c263f8eadb84e4a1fabd904d81d5176226faa9104ef498bf8a8b285/regex-2026.7.19-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b2b506b1788df5fecd270a10d5e70a95fe77b87ea2b370a318043f6f5f817ee6", size = 774130, upload-time = "2026-07-19T00:16:27.786Z" },
+ { url = "https://files.pythonhosted.org/packages/40/95/1b40d87c7a9e5480bec7a87bce9fd67fc3f14b5f106c8ee66d660249072f/regex-2026.7.19-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:52579c60a6078be70a0e49c81d6e56d677f34cd439af281a0083b8c7bc75c095", size = 848694, upload-time = "2026-07-19T00:16:29.412Z" },
+ { url = "https://files.pythonhosted.org/packages/17/8b/bb45968addd5b394ef9cd9184bd9c65ade1a819dbb2b92b71ad52a0c7907/regex-2026.7.19-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:2955907b7157a6660f27079edf7e0229e9c9c5325c77a2ef6a890cba91efa6f0", size = 758505, upload-time = "2026-07-19T00:16:31.006Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/6f/33386c672fbf43e21602135a0f29a97ee251a483f007fe51d10e9b2dbc93/regex-2026.7.19-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:89dfee3319f5ae3f75ebd5c2445a809bb320252ba5529ffdafea4ef25d79cf1a", size = 836985, upload-time = "2026-07-19T00:16:32.459Z" },
+ { url = "https://files.pythonhosted.org/packages/22/f1/9112b86e9bb075619862e8e42b604794389f1958faa68fb69bde505dd90e/regex-2026.7.19-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d3143f159261b1ce5b24c261c590e5913370c3200c5e9ebbb92b5aa5e111902", size = 782610, upload-time = "2026-07-19T00:16:33.857Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/f9/13d460d8a385ca0b0be9e6be80a90968b9293b3e30895543ad2d1d1653e4/regex-2026.7.19-cp310-cp310-win32.whl", hash = "sha256:64729333167c2dcaaa56a331d40ee097bd9c5617ffd51dabb09eaddafb1b532e", size = 266772, upload-time = "2026-07-19T00:16:35.194Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/90/29addd7a03e1aea402c1f31467e25c80caabc8c3735b88a23cf73b0aa9c2/regex-2026.7.19-cp310-cp310-win_amd64.whl", hash = "sha256:1c398716054621aa300b3d411f467dda903806c5da0df6945ab73982b8d115db", size = 277967, upload-time = "2026-07-19T00:16:36.847Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/ba/ecfce06fe66c122bc6f77ae284887a9282e4411fe1e6268c5266611ca054/regex-2026.7.19-cp310-cp310-win_arm64.whl", hash = "sha256:064f1760a5a4ade65c5419be23e782f29147528e8a66e0c42dd4cedb8d4e9fc6", size = 276963, upload-time = "2026-07-19T00:16:38.315Z" },
+ { url = "https://files.pythonhosted.org/packages/05/e5/cef4de2bac939280b68d32adc659478845238a8274f2f79c465063f590ad/regex-2026.7.19-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ac777001cdfc28b72477d93c8564bb7583081ea8fb45cdca3d568e0a4f87183c", size = 494012, upload-time = "2026-07-19T00:16:39.927Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/87/e86f51eb117457bb7803132ffe5cb6e2841e2b5bea4cc85d397f3c6e257d/regex-2026.7.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:59787bd5f8c70aa339084e961d2996b53fbdeab4d5393bba5c1fe1fc32e02bae", size = 295281, upload-time = "2026-07-19T00:16:41.433Z" },
+ { url = "https://files.pythonhosted.org/packages/41/2e/2360c41d8080a3d9ec7e5c90fad6eab3b50192869d10e9a5609e48c8177b/regex-2026.7.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:90c633e7e8d6bf4e992b8b36ce69e018f834b641dd6de8cea6d78c06ffa119c5", size = 290615, upload-time = "2026-07-19T00:16:43.058Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/69/b65ba4344efbc771b28fe5dde84cbbb6c8f9551165952fe78def5b9dde6a/regex-2026.7.19-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:87ccab0db8d5f4fbb0272642113c1adb2ffc698c16d3a0944580222331fa7a20", size = 791804, upload-time = "2026-07-19T00:16:44.662Z" },
+ { url = "https://files.pythonhosted.org/packages/81/b6/a40dfa0dc6224b36f620c00296eacc830489cbf8c2837b6750dfe6170375/regex-2026.7.19-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e50d748a32da622f256e8d505867f5d3c43a837c6a9f0efb149655fadd1042a", size = 861723, upload-time = "2026-07-19T00:16:46.412Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/02/735991dee71abd83196a7962f7ed8bf5aa05720ff06e2d3ff896a85e2bbb/regex-2026.7.19-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bf1516fe58fc104f39b2d1dbe2d5e27d0cd45c4be2e42ba6ee0cc763701ec3c7", size = 905932, upload-time = "2026-07-19T00:16:47.956Z" },
+ { url = "https://files.pythonhosted.org/packages/45/6c/e7098d8b846ccdbf431d8c081b61e496526a27a28094ed09e0dce21b3f54/regex-2026.7.19-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09f3e5287f94f17b709dc9a9e70865855feee835c861613be144218ce4ca82cc", size = 801407, upload-time = "2026-07-19T00:16:49.43Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/18/34b69274e2649bcc7d9b089c2b2983fb2632d8ecf667e359593be9072e79/regex-2026.7.19-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6383cd2ed53a646c659ba1fe65727db76437fdaa069e697a0b44a51d5843d864", size = 774448, upload-time = "2026-07-19T00:16:51.352Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/e6/0a72247d025585fd3800b98e040b84d562a88af6303347100484849f4f01/regex-2026.7.19-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:09d3007fc76249a83cdd33de160d50e6cb77f54e09d8fa9e7148e10607ce24af", size = 783297, upload-time = "2026-07-19T00:16:53.071Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/aa/c4f65ae7dd02a36b323a70c4cff326e1f3442361aaebc9311100a130d54f/regex-2026.7.19-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f8c6e7a1cfa3dc9d0ee2de0e65e834537fa29992cc3976ffec914afc35c5dd5", size = 854736, upload-time = "2026-07-19T00:16:54.607Z" },
+ { url = "https://files.pythonhosted.org/packages/62/c3/668082bcc817b9e694189b84997aeba7385b7779faa6711788679c482e35/regex-2026.7.19-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b2ea4a3e8357be8849e833beeae757ac3c7a6b3fc055c03c808a53c91ad30d82", size = 763298, upload-time = "2026-07-19T00:16:56.289Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/fb/2d07ad555e7af88aa5f867fdafa47a8d945ee237c20af3ebceb46a820835/regex-2026.7.19-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:80115dd39481fd3a4b4080220799dbcacb921a844de4b827264ececacbe17c78", size = 844430, upload-time = "2026-07-19T00:16:57.933Z" },
+ { url = "https://files.pythonhosted.org/packages/51/15/c82a471fe3dce56f03745635b43aa456c40dc0db089e07ef148b331507d1/regex-2026.7.19-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d6ce43a0269d68cee79a7d1ade7def53c20f8f2a047b92d7b5d5bcc73ae88327", size = 789683, upload-time = "2026-07-19T00:16:59.583Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/f4/7532a2c59d56f5398902c20de60f0c9a5d1cd364e42a051b48e1b210be7b/regex-2026.7.19-cp311-cp311-win32.whl", hash = "sha256:9be2a6647740dd3cca6acb24e87f03d7632cd280dbce9bbe40c26353a215a45d", size = 266778, upload-time = "2026-07-19T00:17:01.032Z" },
+ { url = "https://files.pythonhosted.org/packages/83/2b/cf1bc631db154eb95520d9d5dbc2371ff77a0f014bbf7d748fed8496aa63/regex-2026.7.19-cp311-cp311-win_amd64.whl", hash = "sha256:8d3469c91dd92ee41b7c95280edbd975ef1ba9195086686623a1c6e8935ce965", size = 277983, upload-time = "2026-07-19T00:17:02.571Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/bd/56ceaf170e875d5a6761bf2bfd0d040f1cacc896850d5e40cb29b11bbd06/regex-2026.7.19-cp311-cp311-win_arm64.whl", hash = "sha256:36aacfb15faaff3ced55afbf35ec72f50d4aee22082c4f7fe0573a33e2fca92e", size = 276961, upload-time = "2026-07-19T00:17:04.135Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/b9/d11d7e501ac8fd7d617684423ebb9561e0b998481c1e4cbc0cb212c5d74a/regex-2026.7.19-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2cc3460cedf7579948486eab03bc9ad7089df4d7281c0f47f4afe03e8d13f02d", size = 496778, upload-time = "2026-07-19T00:17:05.677Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/a9/a5ab6f312f24318019170dc485d5421fe4f89e43a98640da50d95a8a7041/regex-2026.7.19-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0e9554c8785eac5cffe6300f69a91f58ba72bc88a5f8d661235ad7c6aa5b8ccd", size = 297122, upload-time = "2026-07-19T00:17:07.59Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/63/4cab4d7f2d384a144d420b763d97674cb70619c878ea6fcd7640d0e62143/regex-2026.7.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d7da47a0f248977f08e2cb659ff3c17ddc13a4d39b3a7baa0a81bf5b415430f6", size = 292009, upload-time = "2026-07-19T00:17:09.648Z" },
+ { url = "https://files.pythonhosted.org/packages/22/85/102a81b218298957d4ea7d2f084fae537a71add9d6ff93c8e67284c5f45e/regex-2026.7.19-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93db40c8de0815baab96a06e08a984bac71f989d13bab789e382158c5d426797", size = 796708, upload-time = "2026-07-19T00:17:11.542Z" },
+ { url = "https://files.pythonhosted.org/packages/78/b5/dc136af5629938a037cd2b304c12240e132ec92f38be8ff9cc89af2a1f2d/regex-2026.7.19-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:66bd62c59a5427746e8c44becae1d9b99d22fb13f30f492083dfb9ad7c45cc18", size = 865651, upload-time = "2026-07-19T00:17:13.312Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/75/67402ae3cd9c8c988a4c805d15ee3eef015e7ca4cb112cf3e640fc1f4153/regex-2026.7.19-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1649eb39fcc9ea80c4d2f110fde2b8ab2aef3877b98f02ab9b14e961f418c511", size = 911756, upload-time = "2026-07-19T00:17:15.015Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/8e/096d00c7c480ef2ff4265349b14e2261d4ab787ba1f74e2e80d1c58079c3/regex-2026.7.19-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9dce8ec9695f531a1b8a6f314fd4b393adcccf2ea861db480cdf97a301d01a68", size = 801798, upload-time = "2026-07-19T00:17:17.208Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/41/e7ecac6edb5722417f85cc67eaf386322fbe8acf6918ec2fdc37c20dd9d0/regex-2026.7.19-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3080a7fd38ef049bd489e01c970c97dd84ff446a885b0f1f6b26d9b1ad13ce11", size = 776933, upload-time = "2026-07-19T00:17:19.347Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/69/03c9b3f058d66403e0ca2c938696e81d51cd4c6d47ec5265f02f96948d9a/regex-2026.7.19-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d793a7988e04fcb1e2e135567443d82173225d657419ec09414a9b5a145b986", size = 784338, upload-time = "2026-07-19T00:17:21.057Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/f7/b38ab3d43f284afbb618fcd15d0e77eb786ae461ce1f6bc7494619ddc0f2/regex-2026.7.19-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e8b0abe7d870f53ca5143895fef7d1041a0c831a140d3dc2c760dd7ba25d4a8b", size = 860452, upload-time = "2026-07-19T00:17:23.119Z" },
+ { url = "https://files.pythonhosted.org/packages/15/5c/ff60ef0571121714f3cf9920bc183071e384a10b556d042e0fdb06cc07a5/regex-2026.7.19-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:4e5413bd5f13d3a4e3539ca98f70f75e7fca92518dd7f117f030ebedd10b60cb", size = 765958, upload-time = "2026-07-19T00:17:24.81Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/0f/bd34021162c0ab47f9a315bd56cd5642e920c8e5668a75ef6c6a6fca590d/regex-2026.7.19-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:73b133a9e6fb512858e7f065e96f1180aa46646bc74a83aea62f1d314f3dd035", size = 851765, upload-time = "2026-07-19T00:17:26.993Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/20/a2ca43edade0595cccfdc98636739f536d9e26898e7dbddc2b9e98898953/regex-2026.7.19-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dbe6493fbd27321b1d1f2dd4f5c7e5bd4d8b1d7cab7f32fd67db3d0b2ed8248a", size = 789714, upload-time = "2026-07-19T00:17:28.699Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/47/e02db4015d424fc83c00ea0ac8c5e5ec14397943de9abf909d5ce3a25931/regex-2026.7.19-cp312-cp312-win32.whl", hash = "sha256:ddd67571c10869f65a5d7dde536d1e066e306cc90de57d7de4d5f34802428bb5", size = 267157, upload-time = "2026-07-19T00:17:31.051Z" },
+ { url = "https://files.pythonhosted.org/packages/08/8e/c780c131f79b42ed22d1bd7da4096c2c35f813e835acd02ef0f018bd892c/regex-2026.7.19-cp312-cp312-win_amd64.whl", hash = "sha256:e30d40268a28d54ce0437031750497004c22602b8e3ab891f759b795a003b312", size = 277777, upload-time = "2026-07-19T00:17:32.848Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/4c/e4d7e086449bdf379d89774bf1f89dc4a41943f3c5a6125a03905b34b5fb/regex-2026.7.19-cp312-cp312-win_arm64.whl", hash = "sha256:de9208bb427130c82a5dbfd104f92c8876fc9559278c880b3002755bbbe9c83d", size = 277136, upload-time = "2026-07-19T00:17:34.803Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/3d/84165e4299ff76f3a40fe1f2abf939e976f693383a08d2beea6af62bd2c1/regex-2026.7.19-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f035d9dc1d25eff9d361456572231c7d27b5ccd473ca7dc0adfce732bd006d40", size = 496552, upload-time = "2026-07-19T00:17:36.808Z" },
+ { url = "https://files.pythonhosted.org/packages/02/a2/a65293e6e4cf28eb7ee1be5335a5386c40d6742e9f47fafc8fec785e16c7/regex-2026.7.19-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c42572142ed0b9d5d261ba727157c426510da78e20828b66bbb855098b8a4e38", size = 296983, upload-time = "2026-07-19T00:17:38.816Z" },
+ { url = "https://files.pythonhosted.org/packages/95/47/2d0564e93d87bc48618360ddca232a2ca612bbdf53ce8465d45ca5ce14ee/regex-2026.7.19-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:40b34dd88658e4fedd2fddbf0275ac970d00614b731357f425722a3ed1983d11", size = 291832, upload-time = "2026-07-19T00:17:40.726Z" },
+ { url = "https://files.pythonhosted.org/packages/07/cd/42dfbabff3dfc9603c501c0e2e2c5adbb09d127b267bf5348de0af338c15/regex-2026.7.19-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c41c63992bf1874cebb6e7f56fd7d3c007924659a604ae3d90e427d40d4fd13", size = 796775, upload-time = "2026-07-19T00:17:42.382Z" },
+ { url = "https://files.pythonhosted.org/packages/df/5d/f6a4839f2b934e3eed5973fd07f5929ee97d4c98939fb275ea23c274ee16/regex-2026.7.19-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d3372064506b94dd2c67c845f2db8062e9e9ba84d04e33cb96d7d33c11fe1ae", size = 865687, upload-time = "2026-07-19T00:17:44.185Z" },
+ { url = "https://files.pythonhosted.org/packages/14/b0/b47d6c36049bc59806a50bd4c86ced70bbe058d787f80281b1d7a9b0e024/regex-2026.7.19-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fce7760bf283405b2c7999cab3da4e72f7deca6396013115e3f7a955db9760da", size = 911962, upload-time = "2026-07-19T00:17:46.442Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/be/ff61f28f9273658cfe23acbbac5217221f6519960ed401e61dfdab12bc35/regex-2026.7.19-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c0d702548d89d572b2929879bc883bb7a4c4709efafe4512cadee56c55c9bd15", size = 801817, upload-time = "2026-07-19T00:17:48.25Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/bb/8b4f7f26b333f9f79e1b453613c39bb4776f51d38ae66dd0ba31d6b354ca/regex-2026.7.19-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d446c6ac40bb6e05025ccee55b84d80fe9bf8e93010ffc4bb9484f13d498835f", size = 776908, upload-time = "2026-07-19T00:17:50.183Z" },
+ { url = "https://files.pythonhosted.org/packages/09/13/610110fc5921d380516d03c26b652555f08aa0d23ea78a771231873c3638/regex-2026.7.19-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4c3501bfa814ab07b5580741f9bf78dfdfe146a04057f82df9e2402d2a975939", size = 784426, upload-time = "2026-07-19T00:17:52.454Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/f5/1ef9e2a83a5947c57ebff0b377cb5727c3d5ec1992317a320d035cd0dbb6/regex-2026.7.19-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c4585c3e64b4f9e583b4d2683f18f5d5d872b3d71dcf24594b74ecc23602fa96", size = 860600, upload-time = "2026-07-19T00:17:54.229Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/02/073af33a3ec149241d11c80acea91e722aa0adbf05addd50f251c4fe89c3/regex-2026.7.19-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:571fde9741eb0ccde23dd4e0c1d50fbae910e901fa7e629faf39b2dda740d220", size = 765950, upload-time = "2026-07-19T00:17:56.041Z" },
+ { url = "https://files.pythonhosted.org/packages/81/a9/d1e9f819dc394a568ef370cd56cf25394e957a2235f8370f23b576e5a475/regex-2026.7.19-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:15b364b9b98d6d2fe1a85034c23a3180ff913f46caddc3895f6fd65186255ccc", size = 851794, upload-time = "2026-07-19T00:17:57.897Z" },
+ { url = "https://files.pythonhosted.org/packages/03/3a/8ae83eda7579feacdf984e71fb9e70635fb6f832eeddca58427ec4fca926/regex-2026.7.19-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffd8893ccc1c2fce6e0d6ca402d716fe1b29db70c7132609a05955e31b2aa8f2", size = 789845, upload-time = "2026-07-19T00:17:59.97Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/23/c195cbfe5a75fdec64d8f6554fd15237b837919d2c61bdc141d7c807b08b/regex-2026.7.19-cp313-cp313-win32.whl", hash = "sha256:f0fa4fa9c3632d708742baf2282f2055c11d888a790362670a403cbf48a2c404", size = 267135, upload-time = "2026-07-19T00:18:01.958Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/80/a11de8404b7272b70acb45c1c05987cce60b45d5693da2e176f0e390d564/regex-2026.7.19-cp313-cp313-win_amd64.whl", hash = "sha256:d51ffd3427640fa2da6ade574ceba932f210ad095f65fcc450a2b0a0d454868e", size = 277747, upload-time = "2026-07-19T00:18:04.121Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/29/0f5c8eff1b4f1f3d83276d365fccecf666afcc7d947420943bf394d07adb/regex-2026.7.19-cp313-cp313-win_arm64.whl", hash = "sha256:c670fe7be5b6020b76bc6e8d2196074657e1327595bca93a389e1a76ab130ad8", size = 277129, upload-time = "2026-07-19T00:18:05.821Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/4c/44b74742052cedda40f9ae469532a037112f7311a36669a891fba8984bb0/regex-2026.7.19-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db47b561c9afd884baa1f96f797c9ca369872c4b65912bc691cfa99e68340af2", size = 501134, upload-time = "2026-07-19T00:18:07.567Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/45/bbd038b5e39ee5613a5a689290145b40058cc152c41de9cc23639d2b9734/regex-2026.7.19-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:65dcd28d3eba2ab7c2fd906485cc301392b47cc2234790d27d4e4814e02cdfda", size = 299418, upload-time = "2026-07-19T00:18:09.38Z" },
+ { url = "https://files.pythonhosted.org/packages/65/38/c5bde94b4cedfd5850d64c3f08222d8e1600e84f6ee71d9b44b4b8163f74/regex-2026.7.19-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f2e7f8e2ab6c2922be02c7ec45185aa5bd771e2e57b95455ee343a44d8130dff", size = 294486, upload-time = "2026-07-19T00:18:11.188Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/6a/2f5e107cb26c960b781967178899daf2787a7ab151844ed3c01d6fc95474/regex-2026.7.19-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe31f28c94402043161876a258a9c6f757cb485905c7614ce8d6cd40e6b7bdc1", size = 811643, upload-time = "2026-07-19T00:18:12.975Z" },
+ { url = "https://files.pythonhosted.org/packages/37/d4/a2f963406d7d73a62eed84ba05a258afb6cad1b21aa4517443ce40506b78/regex-2026.7.19-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f8f6fa298bb4f7f58a33334406218ba74716e68feddf5e4e54cd5d8082705abf", size = 871081, upload-time = "2026-07-19T00:18:14.733Z" },
+ { url = "https://files.pythonhosted.org/packages/45/a3/44be546340bedb15f13063f5e7fe16793ea4d9ea2e805d09bd174ac27724/regex-2026.7.19-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cc1b2440423a851fad781309dd87843868f4f66a6bcd1ddb9225cf4ec2c84732", size = 917372, upload-time = "2026-07-19T00:18:16.724Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/f6/e0870b0fd2a40dba0074e4b76e514b21313d37946c9248453e34ec43923e/regex-2026.7.19-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ac59a0900474a52b7c04af8196affc22bd9842acb0950df12f7b813e983609a", size = 816089, upload-time = "2026-07-19T00:18:18.617Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/27/957e8e22690ad6634572b39b71f130a6105f4d0718bb16849eac00fff147/regex-2026.7.19-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4896db1f4ce0576765b8272aa922df324e0f5b9bb2c3d03044ff32a7234a9aba", size = 785206, upload-time = "2026-07-19T00:18:20.464Z" },
+ { url = "https://files.pythonhosted.org/packages/76/a4/186e410941e731037c01166069ab86da9f65e8f8110c18009ccf4bd623ee/regex-2026.7.19-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4e6883a021db30511d9fb8cfb0f222ce1f2c369f7d4d8b0448f449a93ba0bdfc", size = 800431, upload-time = "2026-07-19T00:18:22.716Z" },
+ { url = "https://files.pythonhosted.org/packages/73/9f/e4e10e023d291d64a33e246610b724493bf1ce98e0e59c9b7c837e5acfb7/regex-2026.7.19-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:09523a592938aa9f587fb74467c63ff0cf88fc3df14c82ab0f0517dcf76aaa62", size = 864906, upload-time = "2026-07-19T00:18:24.772Z" },
+ { url = "https://files.pythonhosted.org/packages/24/57/ccb20b6be5f1f52a053d1ba2a8f7a077edb9d918248b8490d7506c6832b3/regex-2026.7.19-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:1ebac3474b8589fce2f9b225b650afd61448f7c73a5d0255a10cc6366471aed1", size = 773559, upload-time = "2026-07-19T00:18:27.008Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/82/f3b263cf8fad927dc102891da8502e718b7ff9d19af7a2a07c03865d7188/regex-2026.7.19-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4a0530bb1b8c1c985e7e2122e2b4d3aedd8a3c21c6bfddae6767c4405668b56e", size = 857739, upload-time = "2026-07-19T00:18:29.107Z" },
+ { url = "https://files.pythonhosted.org/packages/47/2e/1687bd1b6c2aed5e672ccf845fc11557821fe7366d921b50889ea5ce57bf/regex-2026.7.19-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef7eeb108c47ce7bcc9513e51bcb1bf57e8f483d52fce68a8642e3527141ae0", size = 804522, upload-time = "2026-07-19T00:18:31.362Z" },
+ { url = "https://files.pythonhosted.org/packages/76/7c/cc4e7655181b2d9235b704f2c5e19d8eff002bbc437bae59baee0e381aca/regex-2026.7.19-cp313-cp313t-win32.whl", hash = "sha256:64b6ca7391a1395c2638dd5c7456d67bea44fc6c5e8e92c5dc8aa6a8f23292b4", size = 269141, upload-time = "2026-07-19T00:18:33.479Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/14/961b4c7b05a2391c32dbc85e27773076671ef8f97f36cec70fe414734c02/regex-2026.7.19-cp313-cp313t-win_amd64.whl", hash = "sha256:f04b9f56b0e0614c0126be12c2c2d9f8850c1e57af302bd0a63bed379d4af974", size = 280036, upload-time = "2026-07-19T00:18:35.419Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/67/795644550d788ddbb6dc458c95895f8009978ea6d6ea76b005eb3f45e8c9/regex-2026.7.19-cp313-cp313t-win_arm64.whl", hash = "sha256:fcee38cd8e5089d6d4f048ba1233b3ad76e5954f545382180889112ff5cb712d", size = 279394, upload-time = "2026-07-19T00:18:37.454Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/25/0c4c452f8ef3efe456745b2f33195f5904b573fb4c2ff3f0cb9ec188461e/regex-2026.7.19-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:a81758ed242b861b72e778ba34d41366441a2e10b16b472784c88da2dea7e2dd", size = 496750, upload-time = "2026-07-19T00:18:39.633Z" },
+ { url = "https://files.pythonhosted.org/packages/24/9e/b70ca6c1704f6c7cd32a9e143c86cc5968d10981eca284bad670c245ea7d/regex-2026.7.19-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4aa5435cdb3eb6f55fe98a171b05e3fbcd95fadaa4aa32acf62afd9b0cfdbcac", size = 297093, upload-time = "2026-07-19T00:18:41.583Z" },
+ { url = "https://files.pythonhosted.org/packages/87/74/0b692da2520d51fbff19c88b83d97e4c702909dd02386c585998b7e2dbed/regex-2026.7.19-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:60be8693a1dadc210bbcbc0db3e26da5f7d01d1d5a3da594e99b4fa42df404f5", size = 292043, upload-time = "2026-07-19T00:18:43.347Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/a7/1d478e614016045a33feae57446215f9fd65b665a5ceb2f891fb3183bc52/regex-2026.7.19-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d19662dbedbe783d323196312d38f5ba53cf56296378252171985da6899887d3", size = 797214, upload-time = "2026-07-19T00:18:45.362Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/ae/11b9c9411d92c30e3d2db32df5a31133e4a99a8fc397a604fd08f6c4bffb/regex-2026.7.19-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d15df07081d91b76ff20d43f94592ee110330152d617b730fdbe5ef9fb680053", size = 866433, upload-time = "2026-07-19T00:18:47.315Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/62/2b2efc4992f91d6d204b24c647c9f9412e85379d92b7c0ab9fdae622327e/regex-2026.7.19-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:56ad4d9f77df871a99e25c37091052a02528ec0eb059de928ee33956b854b45b", size = 911360, upload-time = "2026-07-19T00:18:49.588Z" },
+ { url = "https://files.pythonhosted.org/packages/14/71/986ceea9aa3da548bf1357cad89b63915ec6d21ec957c8113b29ece567df/regex-2026.7.19-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7322ec6cc9fba9d49ab888bb82d67ac5625627aa168f0165139b17018df3fb8a", size = 801275, upload-time = "2026-07-19T00:18:51.767Z" },
+ { url = "https://files.pythonhosted.org/packages/15/be/ce9d9534b2cda96eab32c548261224b9b4e220a4126f098f60f42ae7b4cd/regex-2026.7.19-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9c7472192ebfad53a6be7c4a8bfb2d64b81c0e93a1fc8c57e1dd0b638297b5d1", size = 777131, upload-time = "2026-07-19T00:18:54.053Z" },
+ { url = "https://files.pythonhosted.org/packages/61/2b/58b5c710f2c3929515a25f3a1ca0dad0dcd4518d4fff3cf23bc7adb8dcd2/regex-2026.7.19-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c10b82c2634df08dfb13b1f04e38fe310d086ee092f4f69c0c8da234251e556e", size = 785020, upload-time = "2026-07-19T00:18:56.579Z" },
+ { url = "https://files.pythonhosted.org/packages/84/03/5fe091935b74f15fe0f97998c215cae418d1c0413f6258c7d4d2e83aa37f/regex-2026.7.19-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:17ed5692f6acc4183e98331101a5f9e4f64d72fe58b753da4d444a2c77d05b12", size = 861263, upload-time = "2026-07-19T00:18:58.64Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/fa/d60bf82e10841eef62a9e32aac401468f05fddfbcb2942e342b1ba3d2433/regex-2026.7.19-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:22a992de9a0d91bda927bf02b94351d737a0302905432c88a53de7c4b9ce62e2", size = 766199, upload-time = "2026-07-19T00:19:00.705Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/5d/11e64d151b0662b81d6bf644c74dc118d461df85bdf2577fadbbf751788a/regex-2026.7.19-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:618a0aed532be87294c4477b0481f3aa0f1520f4014a4374dd4cf789b4cd2c97", size = 851317, upload-time = "2026-07-19T00:19:03.015Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/34/532efb87488d90807bae6a443d357ee5e2728a478c597619c8aaa17cc0bd/regex-2026.7.19-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ce9e679f776649746729b6c86382da519ef649c8e34cc41df0d2e5e0f6c36d4", size = 789557, upload-time = "2026-07-19T00:19:05.338Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/90/3a8d5ca977171ec3ae21a71207d2228b2663bde14d7f7ef0e6363ecf9290/regex-2026.7.19-cp314-cp314-win32.whl", hash = "sha256:73f272fba87b8ccfe70a137d02a54af386f6d27aa509fbffdd978f5947aae1aa", size = 272531, upload-time = "2026-07-19T00:19:07.487Z" },
+ { url = "https://files.pythonhosted.org/packages/96/e1/8862885e70409de70e8c005f57fb2e7be8d9ef0317250d60f4c9660a300d/regex-2026.7.19-cp314-cp314-win_amd64.whl", hash = "sha256:d721e53758b2cca74990185eb0671dd466d7a388a1a45d0c6f4c13cef41a68ac", size = 280831, upload-time = "2026-07-19T00:19:09.46Z" },
+ { url = "https://files.pythonhosted.org/packages/08/82/2693e53e29f9104d9de95d37ce4dd826bd32d5f9c0085d3aa6ac042675c4/regex-2026.7.19-cp314-cp314-win_arm64.whl", hash = "sha256:65fa6cb38ed5e9c3637e68e544f598b39c3b86b808ed0627a67b68320384b459", size = 281099, upload-time = "2026-07-19T00:19:11.398Z" },
+ { url = "https://files.pythonhosted.org/packages/92/b7/9a01aa16461a18cde9d7b9c3ab21e501db2ce33725f53014342b91df2b0a/regex-2026.7.19-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:5a2721c8720e2cb3c209925dfb9200199b4b07361c9e01d321719404b21458b3", size = 501121, upload-time = "2026-07-19T00:19:13.425Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/5e/bbaeca815dc9191c424c94a4fdc5c87c75748a64a6271821212ebdd4e1a3/regex-2026.7.19-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:199535629f25caf89698039af3d1ad5fcae7f933e2112c73f1cdf49165c99518", size = 299415, upload-time = "2026-07-19T00:19:15.43Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/d6/0dd1a321afaab95eb7ff44aa0f637301786f1dc71c6b797b9ed236ed8890/regex-2026.7.19-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9b60d7814174f059e5de4ab98271cc5ba9259cfea55273a81544dceea32dc8d9", size = 294483, upload-time = "2026-07-19T00:19:17.879Z" },
+ { url = "https://files.pythonhosted.org/packages/92/5f/40bacf91d0904f812e13bbbab3864604c463eced8afdc54aeaa50492ea95/regex-2026.7.19-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbece16025afda5e3031af0c4059207e61dcf73ef13af844964f57f387d1c435", size = 811833, upload-time = "2026-07-19T00:19:20.102Z" },
+ { url = "https://files.pythonhosted.org/packages/94/7c/4902744261f775aeede8b5627314b38482da29cf49a57b66a6fb753246c5/regex-2026.7.19-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d24ecb4f5e009ea0bd275ee37ad9953b32005e2e5e60f8bbae16da0dbbf0d3a0", size = 871270, upload-time = "2026-07-19T00:19:22.365Z" },
+ { url = "https://files.pythonhosted.org/packages/16/70/6980c9be6bf21c0a60ed3e0aea39cf419ecf3b08d1d9947bc56e196ef186/regex-2026.7.19-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8cae6fd77a5b72dae505084b1a2ee0360139faf72fedbab667cd7cc65aae7a6a", size = 917534, upload-time = "2026-07-19T00:19:24.529Z" },
+ { url = "https://files.pythonhosted.org/packages/52/92/8b2bd872782ce8c42691e39acb38eb8efe014e5ddb78ad7d943d6f197ce9/regex-2026.7.19-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9724e6cb5e478cd7d8cabf027826178739cb18cf0e117d0e32814d479fa02276", size = 816135, upload-time = "2026-07-19T00:19:26.919Z" },
+ { url = "https://files.pythonhosted.org/packages/de/2d/33a602f657bdc4041f17d79f92ab18261d255d91a06117a6e29df023e5e2/regex-2026.7.19-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:572fc57b0009c735ee56c175ea021b637a15551a312f56734277f923d6fd0f6c", size = 785492, upload-time = "2026-07-19T00:19:29.192Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/36/0987cf4cb271680064a70d24a475873775a151d0b7058698a006cb0cae4a/regex-2026.7.19-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:20568e182eb82d39a6bf7cff3fd58566f14c75c6f74b2c8c96537eecf9010e3a", size = 800658, upload-time = "2026-07-19T00:19:31.392Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/24/c14f31c135e1ba55fa4f9a58ca98d0842512bf6188230763c31c8f449e3b/regex-2026.7.19-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:1d58561843f0ff7dc78b4c28b5e2dc388f3eff94ebc8a232a3adba961fc00009", size = 865073, upload-time = "2026-07-19T00:19:33.485Z" },
+ { url = "https://files.pythonhosted.org/packages/14/85/181a12211f22469f24d2de1ebddfe397d2396e2c29013b9a58134a91069a/regex-2026.7.19-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:61bb1bd45520aacd56dd80943bd34991fb5350afdd1f36f2282230fd5154a218", size = 773684, upload-time = "2026-07-19T00:19:35.599Z" },
+ { url = "https://files.pythonhosted.org/packages/23/58/bd1a0c1a62251366f8d21f41b1ea3c76994962071b8b6ea42f72d505c0f0/regex-2026.7.19-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:cd3584591ea4429026cdb931b054342c2bcf189b44ff367f8d5c15bc092a2966", size = 857769, upload-time = "2026-07-19T00:19:37.738Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/4f/f7e2dad6756b2fe1fe75dd90a628c3b45f249d39f948dd90cd2476325417/regex-2026.7.19-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5cc26a66e212fa5d6c6170c3a40d99d888db3020c6fdab1523250d4341382e44", size = 804546, upload-time = "2026-07-19T00:19:40.229Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/d7/01d31d5bdb09bc026fab77f59a371fdf8f9b292e4810546c56182ca70498/regex-2026.7.19-cp314-cp314t-win32.whl", hash = "sha256:2c4e61e2e1be56f63ec3cc618aa9e0de81ef6f43d177205451840022e24f5b78", size = 274526, upload-time = "2026-07-19T00:19:42.398Z" },
+ { url = "https://files.pythonhosted.org/packages/52/0e/cea4ce73bc0a8247a0748228ae6669984c7e1f8134b6fa66e59c0572e0ea/regex-2026.7.19-cp314-cp314t-win_amd64.whl", hash = "sha256:c639ea314df70a7b2811e8020448c75af8c9445f5a60f8a4ced81c306a9380c2", size = 283763, upload-time = "2026-07-19T00:19:44.644Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/b6/26e41975febae63b7a6e3e02f32cff6cff2e4f10d19c929082f56aebf7c6/regex-2026.7.19-cp314-cp314t-win_arm64.whl", hash = "sha256:9a15e785f244f3e07847b984ce8773fc3da10a9f3c131cc49a4c5b4d672b4547", size = 283451, upload-time = "2026-07-19T00:19:46.639Z" },
]
[[package]]
@@ -21634,10 +21721,10 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "joblib" },
- { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } },
- { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" } },
- { name = "threadpoolctl" },
+ { name = "joblib", marker = "python_full_version < '3.11'" },
+ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
+ { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
+ { name = "threadpoolctl", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/37/59/44985a2bdc95c74e34fef3d10cb5d93ce13b0e2a7baefffe1b53853b502d/scikit_learn-1.5.2.tar.gz", hash = "sha256:b4237ed7b3fdd0a4882792e68ef2545d5baa50aca3bb45aa7df468138ad8f94d", size = 7001680, upload-time = "2024-09-11T15:50:10.957Z" }
wheels = [
@@ -21680,13 +21767,13 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "joblib" },
- { name = "narwhals" },
- { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
+ { name = "joblib", marker = "python_full_version >= '3.11'" },
+ { name = "narwhals", marker = "python_full_version >= '3.11'" },
+ { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
{ name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
- { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
+ { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
{ name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
- { name = "threadpoolctl" },
+ { name = "threadpoolctl", marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fa/6f/37092bdb25f712817231799fc5674d8e704066a8a70c1d2d40517e18b4ab/scikit_learn-1.9.0.tar.gz", hash = "sha256:8833266989d3a5110178a9fae30783675460724d0e1efb13b14901d2c660c557", size = 7750767, upload-time = "2026-06-02T11:54:32.706Z" }
wheels = [
@@ -21731,7 +21818,7 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } },
+ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" }
wheels = [
@@ -21791,7 +21878,7 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" } },
+ { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" }
wheels = [
@@ -21872,7 +21959,7 @@ resolution-markers = [
"(python_full_version == '3.12.*' and platform_machine != 'arm64') or (python_full_version == '3.12.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" } },
+ { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" }
wheels = [
@@ -21957,8 +22044,8 @@ name = "secretstorage"
version = "3.5.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "cryptography" },
- { name = "jeepney" },
+ { name = "cryptography", marker = "python_full_version >= '3.14' or platform_machine != 'arm64' or sys_platform != 'darwin'" },
+ { name = "jeepney", marker = "python_full_version >= '3.14' or platform_machine != 'arm64' or sys_platform != 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" }
wheels = [
@@ -22261,15 +22348,15 @@ name = "snowflake-snowpark-python"
version = "1.53.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "cloudpickle" },
- { name = "protobuf" },
- { name = "python-dateutil" },
- { name = "pyyaml" },
- { name = "setuptools" },
- { name = "snowflake-connector-python" },
- { name = "typing-extensions" },
- { name = "tzlocal" },
- { name = "wheel" },
+ { name = "cloudpickle", marker = "python_full_version < '3.14'" },
+ { name = "protobuf", marker = "python_full_version < '3.14'" },
+ { name = "python-dateutil", marker = "python_full_version < '3.14'" },
+ { name = "pyyaml", marker = "python_full_version < '3.14'" },
+ { name = "setuptools", marker = "python_full_version < '3.14'" },
+ { name = "snowflake-connector-python", marker = "python_full_version < '3.14'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.14'" },
+ { name = "tzlocal", marker = "python_full_version < '3.14'" },
+ { name = "wheel", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/72/5b/4a0eb18191c98d62b8a0a363a4c2d9ee5f01f0f33f32ecd59ddea7b56e3e/snowflake_snowpark_python-1.53.1.tar.gz", hash = "sha256:5a0bcbf01aac54336c7763b748837281762e57214b6425c84ed412706fb58df7", size = 1784995, upload-time = "2026-07-15T23:06:44.704Z" }
wheels = [
@@ -22300,11 +22387,11 @@ wheels = [
[[package]]
name = "soupsieve"
-version = "2.8.4"
+version = "2.9"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/47/2c/0a5f6f8ee0d5589e48c7640213ed5175d52cf540a06725b628cc1a45d6ce/soupsieve-2.8.4.tar.gz", hash = "sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e", size = 121110, upload-time = "2026-05-24T13:55:57.154Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/80/f1/93422647dd7e461f23d254e6b2bfa687a85b53aeb4903fcdbb74474d4584/soupsieve-2.9.tar.gz", hash = "sha256:acee8417325c5653e1377dc31eccad59eb82cbc65942afe6174c53b3aaad63fc", size = 122122, upload-time = "2026-07-19T01:35:18.425Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/5e/f5/0c41cb68dcae6b7de4fac4188a3a9589e21fb31df21ea3a2e888db95e6c9/soupsieve-2.8.4-py3-none-any.whl", hash = "sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65", size = 37304, upload-time = "2026-05-24T13:55:55.406Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/d6/3185ab5ad1280319b31986898f3206dd7227cd75e293d4dba2a5e6bf27a0/soupsieve-2.9-py3-none-any.whl", hash = "sha256:a2b2c76d67df2382d245409fd71e321a571717e58463efa32ace87dcadac2c12", size = 37387, upload-time = "2026-07-19T01:35:17.106Z" },
]
[[package]]
@@ -22316,23 +22403,23 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "alabaster" },
- { name = "babel" },
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } },
- { name = "imagesize" },
- { name = "jinja2" },
- { name = "packaging" },
- { name = "pygments" },
- { name = "requests" },
- { name = "snowballstemmer" },
- { name = "sphinxcontrib-applehelp" },
- { name = "sphinxcontrib-devhelp" },
- { name = "sphinxcontrib-htmlhelp" },
- { name = "sphinxcontrib-jsmath" },
- { name = "sphinxcontrib-qthelp" },
- { name = "sphinxcontrib-serializinghtml" },
- { name = "tomli" },
+ { name = "alabaster", marker = "python_full_version < '3.11'" },
+ { name = "babel", marker = "python_full_version < '3.11'" },
+ { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" },
+ { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
+ { name = "imagesize", marker = "python_full_version < '3.11'" },
+ { name = "jinja2", marker = "python_full_version < '3.11'" },
+ { name = "packaging", marker = "python_full_version < '3.11'" },
+ { name = "pygments", marker = "python_full_version < '3.11'" },
+ { name = "requests", marker = "python_full_version < '3.11'" },
+ { name = "snowballstemmer", marker = "python_full_version < '3.11'" },
+ { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11'" },
+ { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11'" },
+ { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11'" },
+ { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11'" },
+ { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11'" },
+ { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11'" },
+ { name = "tomli", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" }
wheels = [
@@ -22348,23 +22435,23 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "alabaster" },
- { name = "babel" },
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } },
- { name = "imagesize" },
- { name = "jinja2" },
- { name = "packaging" },
- { name = "pygments" },
- { name = "requests" },
- { name = "roman-numerals" },
- { name = "snowballstemmer" },
- { name = "sphinxcontrib-applehelp" },
- { name = "sphinxcontrib-devhelp" },
- { name = "sphinxcontrib-htmlhelp" },
- { name = "sphinxcontrib-jsmath" },
- { name = "sphinxcontrib-qthelp" },
- { name = "sphinxcontrib-serializinghtml" },
+ { name = "alabaster", marker = "python_full_version == '3.11.*'" },
+ { name = "babel", marker = "python_full_version == '3.11.*'" },
+ { name = "colorama", marker = "python_full_version == '3.11.*' and sys_platform == 'win32'" },
+ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
+ { name = "imagesize", marker = "python_full_version == '3.11.*'" },
+ { name = "jinja2", marker = "python_full_version == '3.11.*'" },
+ { name = "packaging", marker = "python_full_version == '3.11.*'" },
+ { name = "pygments", marker = "python_full_version == '3.11.*'" },
+ { name = "requests", marker = "python_full_version == '3.11.*'" },
+ { name = "roman-numerals", marker = "python_full_version == '3.11.*'" },
+ { name = "snowballstemmer", marker = "python_full_version == '3.11.*'" },
+ { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*'" },
+ { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*'" },
+ { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*'" },
+ { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*'" },
+ { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*'" },
+ { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" }
wheels = [
@@ -22386,23 +22473,23 @@ resolution-markers = [
"(python_full_version == '3.12.*' and platform_machine != 'arm64') or (python_full_version == '3.12.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "alabaster" },
- { name = "babel" },
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } },
- { name = "imagesize" },
- { name = "jinja2" },
- { name = "packaging" },
- { name = "pygments" },
- { name = "requests" },
- { name = "roman-numerals" },
- { name = "snowballstemmer" },
- { name = "sphinxcontrib-applehelp" },
- { name = "sphinxcontrib-devhelp" },
- { name = "sphinxcontrib-htmlhelp" },
- { name = "sphinxcontrib-jsmath" },
- { name = "sphinxcontrib-qthelp" },
- { name = "sphinxcontrib-serializinghtml" },
+ { name = "alabaster", marker = "python_full_version >= '3.12'" },
+ { name = "babel", marker = "python_full_version >= '3.12'" },
+ { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" },
+ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
+ { name = "imagesize", marker = "python_full_version >= '3.12'" },
+ { name = "jinja2", marker = "python_full_version >= '3.12'" },
+ { name = "packaging", marker = "python_full_version >= '3.12'" },
+ { name = "pygments", marker = "python_full_version >= '3.12'" },
+ { name = "requests", marker = "python_full_version >= '3.12'" },
+ { name = "roman-numerals", marker = "python_full_version >= '3.12'" },
+ { name = "snowballstemmer", marker = "python_full_version >= '3.12'" },
+ { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" },
+ { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" },
+ { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" },
+ { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" },
+ { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" },
+ { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" }
wheels = [
@@ -22468,12 +22555,12 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "colorama" },
- { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } },
- { name = "starlette" },
- { name = "uvicorn" },
- { name = "watchfiles" },
- { name = "websockets" },
+ { name = "colorama", marker = "python_full_version < '3.11'" },
+ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
+ { name = "starlette", marker = "python_full_version < '3.11'" },
+ { name = "uvicorn", marker = "python_full_version < '3.11'" },
+ { name = "watchfiles", marker = "python_full_version < '3.11'" },
+ { name = "websockets", marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023, upload-time = "2024-10-02T23:15:30.172Z" }
wheels = [
@@ -22497,13 +22584,13 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "colorama" },
- { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
+ { name = "colorama", marker = "python_full_version >= '3.11'" },
+ { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
{ name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
- { name = "starlette" },
- { name = "uvicorn" },
- { name = "watchfiles" },
- { name = "websockets" },
+ { name = "starlette", marker = "python_full_version >= '3.11'" },
+ { name = "uvicorn", marker = "python_full_version >= '3.11'" },
+ { name = "watchfiles", marker = "python_full_version >= '3.11'" },
+ { name = "websockets", marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e0/3c/a59a3a453d4133777f7ed2e83c80b7dc817d43c74b74298ca0af869662ad/sphinx_autobuild-2025.8.25.tar.gz", hash = "sha256:9cf5aab32853c8c31af572e4fecdc09c997e2b8be5a07daf2a389e270e85b213", size = 15200, upload-time = "2025-08-25T18:44:55.436Z" }
wheels = [
@@ -22533,7 +22620,7 @@ resolution-markers = [
"(python_full_version < '3.11' and platform_machine != 'arm64') or (python_full_version < '3.11' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } },
+ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689, upload-time = "2024-08-02T13:48:44.277Z" }
wheels = [
@@ -22557,7 +22644,7 @@ resolution-markers = [
"(python_full_version == '3.11.*' and platform_machine != 'arm64') or (python_full_version == '3.11.*' and sys_platform != 'darwin')",
]
dependencies = [
- { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
+ { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
{ name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/13/7b/804f311da4663a4aecc6cf7abd83443f3d4ded970826d0c958edc77d4527/sphinx_design-0.7.0.tar.gz", hash = "sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a", size = 2203582, upload-time = "2026-01-19T13:12:53.297Z" }
@@ -22665,7 +22752,7 @@ wheels = [
[[package]]
name = "sphinxcontrib-mermaid"
-version = "2.0.3"
+version = "2.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jinja2" },
@@ -22674,9 +22761,9 @@ dependencies = [
{ name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
{ name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/51/29/54cf1f7e03630ca4859caba25bc192698954d7c630377c62d1e264715c37/sphinxcontrib_mermaid-2.0.3.tar.gz", hash = "sha256:a6865ef6b65b225c5403a3170de63a04a07227cada11a4a71a6b87b4f9ed185a", size = 20764, upload-time = "2026-07-08T00:30:44.216Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/07/9d/bf3a48a657682c7e0445c71d916bca7ab8194454276cc22b16e7f974e502/sphinxcontrib_mermaid-2.1.0.tar.gz", hash = "sha256:13c5f9ac395cb6abf403eca34e228dc9fb3a30c9d960dbf3e40e9a8cef969549", size = 21695, upload-time = "2026-07-18T23:08:11.265Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/1a/57/b39c7a69b70a3ce999732bdb57fcaac78fb3cc8e2843a3daf1c1f821bc9d/sphinxcontrib_mermaid-2.0.3-py3-none-any.whl", hash = "sha256:f001ed36a55c108f6221a2d656a441c487ee30651b54db72b7c752a20c7a66e8", size = 15401, upload-time = "2026-07-08T00:30:42.877Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/bd/d3348d62296e73a91420f0edf671450c9003ecd8704da40b1e3d9b868459/sphinxcontrib_mermaid-2.1.0-py3-none-any.whl", hash = "sha256:417cd144ec4b28852f46ba653f02ce8e538881c812111671a4c30344e87f2112", size = 16190, upload-time = "2026-07-18T23:08:10.098Z" },
]
[[package]]
@@ -24514,7 +24601,7 @@ name = "xmlsec"
version = "1.3.17"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "lxml" },
+ { name = "lxml", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/49/14/538b75379e6ab8f688f14d8663e2ab138d9c778bac4999d155b5f33c71c1/xmlsec-1.3.17.tar.gz", hash = "sha256:f3fac9ae679f66585925cc00c5f6839ae36c1d03157619571dee18acc05b9c01", size = 115637, upload-time = "2025-11-11T16:20:46.019Z" }
wheels = [