diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0e05f22..0135f3a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,24 +30,23 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"] runs-on: windows-latest if: github.event_name == 'pull_request' || github.event_name == 'push' steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 with: fetch-depth: 9 submodules: false - name: Use Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - pip install cython==3.0.2 pip install -r requirements.txt pip install flake8 @@ -77,24 +76,24 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 with: fetch-depth: 9 submodules: false - name: Use Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | pip install -r requirements.txt - pip install black==24.2.0 isort==5.13.2 flake8==7.0.0 + pip install black==24.8.0 isort==5.13.2 flake8==7.1.1 - name: Compile Cython extensions run: | @@ -104,10 +103,10 @@ jobs: run: | pytest --doctest-modules --junitxml=junit/pytest-results-${{ matrix.os }}-${{ matrix.python-version }}.xml --cov=$PROJECT_NAME --cov-report=xml - - name: Run tests with Pydantic v2 + - name: Run tests with Pydantic v1 run: | - echo "[*] The previous tests used Pydantic v1, now running with v2" - pip install -U pydantic==2.4.2 + echo "[*] The previous tests used Pydantic v2, now running with v1" + pip install -U "pydantic<2" pytest - name: Run linters @@ -167,22 +166,22 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"] os: [ubuntu-latest, macos-latest, windows-latest] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 with: fetch-depth: 9 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install build dependencies run: | - pip install cython==3.0.2 + pip install cython==3.0.11 pip install --upgrade build - name: Compile Cython extensions @@ -229,7 +228,7 @@ jobs: path: dist - name: Use Python 3.11 - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: '3.11' diff --git a/pyproject.toml b/pyproject.toml index 0006c52..af16474 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Environment :: Web Environment", "Operating System :: OS Independent", "Framework :: AsyncIO", @@ -25,13 +26,13 @@ keywords = ["blacksheep", "web framework", "asyncio"] dependencies = [ "httptools>=0.5", "certifi>=2022.9.24", - "charset-normalizer~=3.1.0", + "charset-normalizer~=3.4.0", "guardpost>=1.0.2", "rodi~=2.0.2", "essentials>=1.1.4,<2.0", "essentials-openapi>=1.0.6,<1.1", - "python-dateutil~=2.8.2", - "itsdangerous~=2.1.2", + "python-dateutil~=2.9.0", + "itsdangerous~=2.2.0", ] [tool.setuptools] @@ -42,7 +43,7 @@ version = { attr = "blacksheep.__version__" } [project.optional-dependencies] jinja = ["Jinja2~=3.1.2"] -full = ["cryptography>=38.0.1,<41.1.0", "PyJWT~=2.6.0", "websockets~=10.3"] +full = ["cryptography>=44.0.0,<45.0.0", "PyJWT~=2.9.0", "websockets~=13.1"] [project.urls] "Homepage" = "https://github.com/Neoteroi/BlackSheep" diff --git a/requirements.txt b/requirements.txt index e1e520c..b0040fe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,59 +1,60 @@ -annotated-types==0.6.0 -asgiref==3.7.2 -attrs==23.1.0 -blinker==1.6.3 -certifi==2023.7.22 -cffi==1.16.0 -charset-normalizer==3.3.1 +annotated-types==0.7.0 +asgiref==3.8.1 +attrs==24.2.0 +blinker==1.8.2 +certifi==2024.12.14 +cffi==1.17.1 +charset-normalizer==3.4.0 click==8.1.7 -coverage==7.3.2 -cryptography==41.0.6 -Cython==3.0.4; platform_system != "Windows" +coverage==7.6.1 +cryptography==44.0.0 +Cython==3.0.11 essentials==1.1.5 -essentials-openapi==1.0.8 -Flask==3.0.0 -gevent==23.9.1 -greenlet==3.0.0 +essentials-openapi==1.0.9 +Flask==3.0.3 +gevent==24.2.1 +greenlet==3.1.1 guardpost==1.0.2 h11==0.14.0 h2==4.1.0 hpack==4.0.0 -httptools==0.6.1 +httptools==0.6.4 hypercorn==0.14.4 hyperframe==6.0.1 -idna==3.4 +idna==3.10 iniconfig==2.0.0 -itsdangerous==2.1.2 -Jinja2==3.1.3 -MarkupSafe==2.1.3 +itsdangerous==2.2.0 +Jinja2==3.1.4 +MarkupSafe==2.1.5 mccabe==0.7.0 -packaging==23.2 -pluggy==1.3.0 +packaging==24.2 +pluggy==1.5.0 priority==2.0.0 py==1.11.0 -pycparser==2.21 -pydantic==2.4.2 -pydantic_core==2.10.1 -PyJWT==2.8.0 -pyparsing==3.1.1 -pytest==7.4.2 +pycparser==2.22 +pydantic==2.10.3 +pydantic-core==2.27.1 +PyJWT==2.9.0 +pyparsing==3.1.4 +pytest==8.3.4 pytest-asyncio==0.21.1 -pytest-cov==4.1.0 -python-dateutil==2.8.2 -PyYAML==6.0.1 -regex==2023.10.3 -requests==2.31.0 -rodi==2.0.3 -setuptools==68.2.2 -six==1.16.0 +pytest-cov==5.0.0 +python-dateutil==2.9.0.post0 +PyYAML==6.0.2 +regex==2024.11.6 +requests==2.32.3 +rodi==2.0.6 +setuptools==75.3.0 +six==1.17.0 toml==0.10.2 -tomli==2.0.1 -typing_extensions==4.8.0 -urllib3==2.0.7 -uvicorn==0.23.2 -wcwidth==0.2.8 -websockets==12.0 -Werkzeug==3.0.1 +tomli==2.2.1 +typing-extensions==4.12.2 +urllib3==2.2.3 +uvicorn==0.33.0 +wcwidth==0.2.13 +websockets==13.1 +Werkzeug==3.0.6 wsproto==1.2.0 zope.event==5.0 -zope.interface==6.1 +zope.interface==7.2 +build==1.2.2.post1 diff --git a/tests/test_openapi_v3.py b/tests/test_openapi_v3.py index cbddde4..9727e0d 100644 --- a/tests/test_openapi_v3.py +++ b/tests/test_openapi_v3.py @@ -1049,9 +1049,68 @@ def home() -> PydPaginatedSetOfCat: ... yaml = serializer.to_yaml(docs.generate_documentation(app)) if sys.version_info >= (3, 9): - assert ( - yaml.strip() - == """ + if PYDANTIC_VERSION == 1: + assert ( + yaml.strip() + == """ +openapi: 3.0.3 +info: + title: Example + version: 0.0.1 +paths: + /: + get: + responses: + '200': + description: Success response + content: + application/json: + schema: + $ref: '#/components/schemas/PydPaginatedSetOfCat' + operationId: home +components: + schemas: + PydCat: + type: object + required: + - id + - name + - childs + properties: + id: + type: integer + format: int64 + nullable: false + name: + type: string + nullable: false + childs: + type: array + nullable: false + items: + nullable: false + PydPaginatedSetOfCat: + type: object + required: + - items + - total + properties: + items: + type: array + nullable: false + items: + $ref: '#/components/schemas/PydCat' + total: + type: integer + format: int64 + nullable: false +tags: [] +""".strip() + ) + else: + assert ( + yaml.strip() + == """ openapi: 3.0.3 info: title: Example @@ -1107,7 +1166,7 @@ def home() -> PydPaginatedSetOfCat: ... nullable: false tags: [] """.strip() - ) + ) else: assert ( yaml.strip() @@ -1177,9 +1236,89 @@ def home() -> PydTypeWithChildModels: ... yaml = serializer.to_yaml(docs.generate_documentation(app)) if sys.version_info >= (3, 9): - assert ( - yaml.strip() - == """ + if PYDANTIC_VERSION == 1: + assert ( + yaml.strip() + == """ +openapi: 3.0.3 +info: + title: Example + version: 0.0.1 +paths: + /: + get: + responses: + '200': + description: Success response + content: + application/json: + schema: + $ref: '#/components/schemas/PydTypeWithChildModels' + operationId: home +components: + schemas: + PydCat: + type: object + required: + - id + - name + - childs + properties: + id: + type: integer + format: int64 + nullable: false + name: + type: string + nullable: false + childs: + type: array + nullable: false + items: + nullable: false + PydPaginatedSetOfCat: + type: object + required: + - items + - total + properties: + items: + type: array + nullable: false + items: + $ref: '#/components/schemas/PydCat' + total: + type: integer + format: int64 + nullable: false + PydExampleWithSpecificTypes: + type: object + required: + - url + properties: + url: + type: string + format: uri + maxLength: 2083 + minLength: 1 + nullable: false + PydTypeWithChildModels: + type: object + required: + - child + - friend + properties: + child: + $ref: '#/components/schemas/PydPaginatedSetOfCat' + friend: + $ref: '#/components/schemas/PydExampleWithSpecificTypes' +tags: [] + """.strip() + ) + else: + assert ( + yaml.strip() + == """ openapi: 3.0.3 info: title: Example @@ -1256,7 +1395,7 @@ def home() -> PydTypeWithChildModels: ... $ref: '#/components/schemas/PydExampleWithSpecificTypes' tags: [] """.strip() - ) + ) else: assert ( yaml.strip() @@ -1347,9 +1486,68 @@ def home() -> PaginatedSet[PydCat]: ... yaml = serializer.to_yaml(docs.generate_documentation(app)) if sys.version_info >= (3, 9): - assert ( - yaml.strip() - == """ + if PYDANTIC_VERSION == 1: + assert ( + yaml.strip() + == """ +openapi: 3.0.3 +info: + title: Example + version: 0.0.1 +paths: + /: + get: + responses: + '200': + description: Success response + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedSetOfPydCat' + operationId: home +components: + schemas: + PydCat: + type: object + required: + - id + - name + - childs + properties: + id: + type: integer + format: int64 + nullable: false + name: + type: string + nullable: false + childs: + type: array + nullable: false + items: + nullable: false + PaginatedSetOfPydCat: + type: object + required: + - items + - total + properties: + items: + type: array + nullable: false + items: + $ref: '#/components/schemas/PydCat' + total: + type: integer + format: int64 + nullable: false +tags: [] + """.strip() + ) + else: + assert ( + yaml.strip() + == """ openapi: 3.0.3 info: title: Example @@ -1405,7 +1603,7 @@ def home() -> PaginatedSet[PydCat]: ... nullable: false tags: [] """.strip() - ) + ) else: assert ( yaml.strip() @@ -1939,8 +2137,6 @@ def home() -> PydResponse[PydCat]: ... type: array nullable: false items: - type: string - format: uuid nullable: false Error: type: object @@ -2221,8 +2417,8 @@ def home() -> PydConstrained: ... big_float: type: number format: float - maximum: 1024 - minimum: 1000 + maximum: 1024.0 + minimum: 1000.0 nullable: false unit_interval: type: number