From eedc61e9b0f922cd76c9be78a049f908e8e621be Mon Sep 17 00:00:00 2001 From: Yurii Serhiichuk Date: Sun, 26 May 2024 21:49:35 +0300 Subject: [PATCH 1/2] Update CI and tooling (#236) * Update pre-commit hooks Signed-off-by: Yurii Serhiichuk * Add Python 3.12 Signed-off-by: Yurii Serhiichuk * Drop python 3.7 and add 3.12 to TOX Signed-off-by: Yurii Serhiichuk * Migrate to latest action versions. Drop v3.7 from CI and add 3.12 Signed-off-by: Yurii Serhiichuk * Migrate to Python 3.8 Signed-off-by: Yurii Serhiichuk * Fix changelog message. Signed-off-by: Yurii Serhiichuk --------- Signed-off-by: Yurii Serhiichuk --- .github/workflows/main.yml | 10 +++++----- .github/workflows/pypi-release.yml | 9 +++++---- .pre-commit-config.yaml | 6 +++--- CHANGELOG.md | 4 ++++ mypy.ini | 2 +- setup.py | 1 - tox.ini | 2 +- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1a6ae4..107bf9e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,9 +7,9 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' @@ -22,13 +22,13 @@ jobs: test: strategy: matrix: - python: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python: ['3.8', '3.9', '3.10', '3.11'] os: [ubuntu-latest, windows-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index 56bbf66..4cb248b 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -12,15 +12,16 @@ jobs: name: Build source distribution runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Build SDist and wheel run: pipx run build - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: + name: artifact path: dist/* - name: Check metadata @@ -30,7 +31,7 @@ jobs: if: github.event_name == 'push' needs: [ build_dist ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python @@ -40,7 +41,7 @@ jobs: cache: 'pip' - name: Install build dependencies run: pip install -U setuptools wheel build - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: # unpacks default artifact into dist/ # if `name: artifact` is omitted, the action will create extra parent dir diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 15ab654..cc893e5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,17 +6,17 @@ repos: - id: end-of-file-fixer - id: check-toml - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort args: [ "--profile", "black", "--filter-files" ] - repo: https://github.com/psf/black - rev: 23.10.1 + rev: 24.4.2 hooks: - id: black language_version: python3.11 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.1 + rev: v1.10.0 hooks: - id: mypy files: ^(cloudevents/) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51fcb0e..66dc58d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Dropped Python3.7 from CI while its EOL. + ## [1.10.1] ### Fixed diff --git a/mypy.ini b/mypy.ini index 3942637..d8fb9cc 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,6 +1,6 @@ [mypy] plugins = pydantic.mypy -python_version = 3.7 +python_version = 3.8 pretty = True show_error_context = True diff --git a/setup.py b/setup.py index 95ccf97..a4e4bef 100644 --- a/setup.py +++ b/setup.py @@ -65,7 +65,6 @@ if __name__ == "__main__": "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index a5cbdfa..0436a1b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{37,38,39,310,311},lint +envlist = py{38,39,310,311,312},lint skipsdist = True [testenv] From 11520e35e134b9aa749859981d100e27fe6a0e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20D=2E=20Batista?= Date: Sun, 26 May 2024 15:51:36 -0300 Subject: [PATCH 2/2] Pydantic v2 (#235) * Fixes examples when using Pydantic V2 Signed-off-by: Fabio Batista * When type checking, uses the latest (V2) version of Pydantic Signed-off-by: Fabio Batista --------- Signed-off-by: Fabio Batista Co-authored-by: Yurii Serhiichuk --- .pre-commit-config.yaml | 2 +- cloudevents/pydantic/__init__.py | 33 ++++++++++++++++++++------------ cloudevents/pydantic/v2/event.py | 18 ++++++++--------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cc893e5..75ad2ef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,4 +24,4 @@ repos: types: [ python ] args: [ ] additional_dependencies: - - "pydantic" + - "pydantic~=2.7" diff --git a/cloudevents/pydantic/__init__.py b/cloudevents/pydantic/__init__.py index 409eb44..f8556ca 100644 --- a/cloudevents/pydantic/__init__.py +++ b/cloudevents/pydantic/__init__.py @@ -12,22 +12,31 @@ # License for the specific language governing permissions and limitations # under the License. +from typing import TYPE_CHECKING + from cloudevents.exceptions import PydanticFeatureNotInstalled try: - from pydantic import VERSION as PYDANTIC_VERSION - - pydantic_major_version = PYDANTIC_VERSION.split(".")[0] - if pydantic_major_version == "1": - from cloudevents.pydantic.v1 import CloudEvent, from_dict, from_http, from_json - + if TYPE_CHECKING: + from cloudevents.pydantic.v2 import CloudEvent, from_dict, from_http, from_json else: - from cloudevents.pydantic.v2 import ( # type: ignore - CloudEvent, - from_dict, - from_http, - from_json, - ) + from pydantic import VERSION as PYDANTIC_VERSION + + pydantic_major_version = PYDANTIC_VERSION.split(".")[0] + if pydantic_major_version == "1": + from cloudevents.pydantic.v1 import ( + CloudEvent, + from_dict, + from_http, + from_json, + ) + else: + from cloudevents.pydantic.v2 import ( + CloudEvent, + from_dict, + from_http, + from_json, + ) except ImportError: # pragma: no cover # hard to test raise PydanticFeatureNotInstalled( diff --git a/cloudevents/pydantic/v2/event.py b/cloudevents/pydantic/v2/event.py index 4ae8bb5..643794c 100644 --- a/cloudevents/pydantic/v2/event.py +++ b/cloudevents/pydantic/v2/event.py @@ -51,53 +51,53 @@ class CloudEvent(abstract.CloudEvent, BaseModel): # type: ignore data: typing.Optional[typing.Any] = Field( title=FIELD_DESCRIPTIONS["data"].get("title"), description=FIELD_DESCRIPTIONS["data"].get("description"), - example=FIELD_DESCRIPTIONS["data"].get("example"), + examples=[FIELD_DESCRIPTIONS["data"].get("example")], default=None, ) source: str = Field( title=FIELD_DESCRIPTIONS["source"].get("title"), description=FIELD_DESCRIPTIONS["source"].get("description"), - example=FIELD_DESCRIPTIONS["source"].get("example"), + examples=[FIELD_DESCRIPTIONS["source"].get("example")], ) id: str = Field( title=FIELD_DESCRIPTIONS["id"].get("title"), description=FIELD_DESCRIPTIONS["id"].get("description"), - example=FIELD_DESCRIPTIONS["id"].get("example"), + examples=[FIELD_DESCRIPTIONS["id"].get("example")], default_factory=attribute.default_id_selection_algorithm, ) type: str = Field( title=FIELD_DESCRIPTIONS["type"].get("title"), description=FIELD_DESCRIPTIONS["type"].get("description"), - example=FIELD_DESCRIPTIONS["type"].get("example"), + examples=[FIELD_DESCRIPTIONS["type"].get("example")], ) specversion: attribute.SpecVersion = Field( title=FIELD_DESCRIPTIONS["specversion"].get("title"), description=FIELD_DESCRIPTIONS["specversion"].get("description"), - example=FIELD_DESCRIPTIONS["specversion"].get("example"), + examples=[FIELD_DESCRIPTIONS["specversion"].get("example")], default=attribute.DEFAULT_SPECVERSION, ) time: typing.Optional[datetime.datetime] = Field( title=FIELD_DESCRIPTIONS["time"].get("title"), description=FIELD_DESCRIPTIONS["time"].get("description"), - example=FIELD_DESCRIPTIONS["time"].get("example"), + examples=[FIELD_DESCRIPTIONS["time"].get("example")], default_factory=attribute.default_time_selection_algorithm, ) subject: typing.Optional[str] = Field( title=FIELD_DESCRIPTIONS["subject"].get("title"), description=FIELD_DESCRIPTIONS["subject"].get("description"), - example=FIELD_DESCRIPTIONS["subject"].get("example"), + examples=[FIELD_DESCRIPTIONS["subject"].get("example")], default=None, ) datacontenttype: typing.Optional[str] = Field( title=FIELD_DESCRIPTIONS["datacontenttype"].get("title"), description=FIELD_DESCRIPTIONS["datacontenttype"].get("description"), - example=FIELD_DESCRIPTIONS["datacontenttype"].get("example"), + examples=[FIELD_DESCRIPTIONS["datacontenttype"].get("example")], default=None, ) dataschema: typing.Optional[str] = Field( title=FIELD_DESCRIPTIONS["dataschema"].get("title"), description=FIELD_DESCRIPTIONS["dataschema"].get("description"), - example=FIELD_DESCRIPTIONS["dataschema"].get("example"), + examples=[FIELD_DESCRIPTIONS["dataschema"].get("example")], default=None, )